Subversion Repositories FlightCtrl

Rev

Rev 2164 | Only display areas with differences | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 2164 Rev 2189
1
#ifndef EEMEM
1
#ifndef EEMEM
2
#define EEMEM __attribute__ ((section (".eeprom")))
2
#define EEMEM __attribute__ ((section (".eeprom")))
3
#endif
3
#endif
4
 
4
 
5
#include "eeprom.h"
5
#include "eeprom.h"
6
#include "printf_P.h"
-
 
7
#include "output.h"
6
//#include "output.h"
8
#include "configuration.h"
7
#include "configuration.h"
-
 
8
#include "analog.h"
9
#include <avr/wdt.h>
9
#include <avr/wdt.h>
10
#include <avr/eeprom.h>
10
#include <avr/eeprom.h>
11
#include <avr/interrupt.h>
11
#include <avr/interrupt.h>
-
 
12
#include <stdio.h>
12
 
13
 
13
// byte array in eeprom
14
// byte array in eeprom
14
uint8_t EEPromArray[E2END + 1] EEMEM;
15
uint8_t EEPromArray[E2END + 1] EEMEM;
15
 
16
 
16
/***************************************************/
17
/***************************************************/
17
/*       Read Parameter from EEPROM as byte        */
18
/*       Read Parameter from EEPROM as byte        */
18
/***************************************************/
19
/***************************************************/
19
uint8_t getParamByte(uint16_t param_id) {
20
uint8_t getParamByte(uint16_t param_id) {
20
  return eeprom_read_byte(&EEPromArray[EEPROM_ADR_PARAM_BEGIN + param_id]);
21
  return eeprom_read_byte(&EEPromArray[EEPROM_ADR_PARAM_BEGIN + param_id]);
21
}
22
}
22
 
23
 
23
/***************************************************/
24
/***************************************************/
24
/*       Write Parameter to EEPROM as byte         */
25
/*       Write Parameter to EEPROM as byte         */
25
/***************************************************/
26
/***************************************************/
26
void setParamByte(uint16_t param_id, uint8_t value) {
27
void setParamByte(uint16_t param_id, uint8_t value) {
27
  eeprom_write_byte(&EEPromArray[EEPROM_ADR_PARAM_BEGIN + param_id], value);
28
  eeprom_write_byte(&EEPromArray[EEPROM_ADR_PARAM_BEGIN + param_id], value);
28
}
29
}
29
 
30
 
30
/***************************************************/
31
/***************************************************/
31
/*       Read Parameter from EEPROM as word        */
32
/*       Read Parameter from EEPROM as word        */
32
/***************************************************/
33
/***************************************************/
33
/*
34
/*
34
uint16_t getParamWord(uint16_t param_id) {
35
uint16_t getParamWord(uint16_t param_id) {
35
  return eeprom_read_word((uint16_t *) &EEPromArray[EEPROM_ADR_PARAM_BEGIN
36
  return eeprom_read_word((uint16_t *) &EEPromArray[EEPROM_ADR_PARAM_BEGIN
36
                                                    + param_id]);
37
                                                    + param_id]);
37
}
38
}
38
*/
39
*/
39
 
40
 
40
/***************************************************/
41
/***************************************************/
41
/*       Write Parameter to EEPROM as word         */
42
/*       Write Parameter to EEPROM as word         */
42
/***************************************************/
43
/***************************************************/
43
/*
44
/*
44
void setParamWord(uint16_t param_id, uint16_t value) {
45
void setParamWord(uint16_t param_id, uint16_t value) {
45
  eeprom_write_word((uint16_t *) &EEPromArray[EEPROM_ADR_PARAM_BEGIN + param_id], value);
46
  eeprom_write_word((uint16_t *) &EEPromArray[EEPROM_ADR_PARAM_BEGIN + param_id], value);
46
}
47
}
47
*/
48
*/
48
 
49
 
49
uint16_t CRC16(uint8_t* data, uint16_t length) {
50
uint16_t CRC16(uint8_t* data, uint16_t length) {
50
  uint16_t crc = 0;
51
  uint16_t crc = 0;
51
  for (uint16_t i=0; i<length; i++) {
52
  for (uint16_t i=0; i<length; i++) {
52
    crc  = (uint8_t)(crc >> 8) | (crc << 8);
53
    crc  = (uint8_t)(crc >> 8) | (crc << 8);
53
    crc ^= data[i];
54
    crc ^= data[i];
54
    crc ^= (uint8_t)(crc & 0xff) >> 4;
55
    crc ^= (uint8_t)(crc & 0xff) >> 4;
55
    crc ^= (crc << 8) << 4;
56
    crc ^= (crc << 8) << 4;
56
    crc ^= ((crc & 0xff) << 4) << 1;
57
    crc ^= ((crc & 0xff) << 4) << 1;
57
  }
58
  }
58
  return crc;
59
  return crc;
59
}
60
}
60
 
61
 
61
// offset is where the checksum is stored, offset+1 is the revision number, and offset+2... are the data.
62
// offset is where the checksum is stored, offset+1 is the revision number, and offset+2... are the data.
62
// length is the length of the pure data not including checksum and revision number.
63
// length is the length of the pure data not including checksum and revision number.
63
void writeChecksummedBlock(uint8_t revisionNumber, uint8_t* data, uint16_t offset, uint16_t length) {
64
void writeChecksummedBlock(uint8_t revisionNumber, uint8_t* data, uint16_t offset, uint16_t length) {
64
  uint16_t CRC = CRC16(data, length);
65
  uint16_t CRC = CRC16(data, length);
65
  uint8_t sreg = SREG;
66
  uint8_t sreg = SREG;
66
  cli();
67
  cli();
67
  eeprom_write_byte(&EEPromArray[offset], CRC&0xff);
68
  eeprom_write_byte(&EEPromArray[offset], CRC&0xff);
68
  eeprom_write_byte(&EEPromArray[offset+1], CRC>>8);
69
  eeprom_write_byte(&EEPromArray[offset+1], CRC>>8);
69
  eeprom_write_byte(&EEPromArray[offset+2], revisionNumber);
70
  eeprom_write_byte(&EEPromArray[offset+2], revisionNumber);
70
  eeprom_write_block(data, &EEPromArray[offset+3], length);
71
  eeprom_write_block(data, &EEPromArray[offset+3], length);
71
  SREG = sreg;
72
  SREG = sreg;
72
}
73
}
73
 
74
 
74
// offset is where the checksum is stored, offset+1 is the revision number, and offset+2... are the data.
75
// offset is where the checksum is stored, offset+1 is the revision number, and offset+2... are the data.
75
// length is the length of the pure data not including checksum and revision number.
76
// length is the length of the pure data not including checksum and revision number.
76
uint8_t readChecksummedBlock(uint8_t revisionNumber, uint8_t* target, uint16_t offset, uint16_t length) {
77
uint8_t readChecksummedBlock(uint8_t revisionNumber, uint8_t* target, uint16_t offset, uint16_t length) {
77
  uint16_t CRCRead = eeprom_read_byte(&EEPromArray[offset]) | (eeprom_read_byte(&EEPromArray[offset+1])<<8);
78
  uint16_t CRCRead = eeprom_read_byte(&EEPromArray[offset]) | (eeprom_read_byte(&EEPromArray[offset+1])<<8);
78
  uint8_t revisionNumberRead = eeprom_read_byte(&EEPromArray[offset+2]);
79
  uint8_t revisionNumberRead = eeprom_read_byte(&EEPromArray[offset+2]);
79
  eeprom_read_block(target, &EEPromArray[offset+3], length);
80
  eeprom_read_block(target, &EEPromArray[offset+3], length);
80
  uint16_t CRCCalculated = CRC16(target, length);
81
  uint16_t CRCCalculated = CRC16(target, length);
81
 
82
 
82
  uint8_t CRCError = (CRCRead != CRCCalculated);
83
  uint8_t CRCError = (CRCRead != CRCCalculated);
83
  uint8_t revisionMismatch = (revisionNumber != revisionNumberRead);
84
  uint8_t revisionMismatch = (revisionNumber != revisionNumberRead);
84
 
85
 
85
  if (CRCError && revisionMismatch) printf("\n\rEEPROM CRC error and revision mismatch; ");
86
  if (CRCError && revisionMismatch) printf("\n\rEEPROM CRC error and revision mismatch; ");
86
  else if (CRCError) printf("\n\rEEPROM CRC error; ");
87
  else if (CRCError) printf("\n\rEEPROM CRC error; ");
87
  else if (revisionMismatch) printf("\n\rEEPROM revision mismatch; ");
88
  else if (revisionMismatch) printf("\n\rEEPROM revision mismatch; ");
88
  return (CRCError || revisionMismatch);
89
  return (CRCError || revisionMismatch);
89
}
90
}
90
 
91
 
91
/***************************************************/
92
/***************************************************/
92
/*       Read Parameter Set from EEPROM            */
93
/*       Read Parameter Set from EEPROM            */
93
/***************************************************/
94
/***************************************************/
94
// setnumber [1..5]
95
// setnumber [1..5]
95
uint8_t paramSet_readFromEEProm(uint8_t setnumber) {
96
uint8_t paramSet_readFromEEProm(uint8_t setnumber) {
96
  uint16_t offset = EEPROM_ADR_PARAMSET_BEGIN + (setnumber-1)*(sizeof(ParamSet_t)+EEPROM_CHECKSUMMED_BLOCK_OVERHEAD);
97
  uint16_t offset = EEPROM_ADR_PARAMSET_BEGIN + (setnumber-1)*(sizeof(ParamSet_t)+EEPROM_CHECKSUMMED_BLOCK_OVERHEAD);
97
  uint8_t result = readChecksummedBlock(EEPARAM_REVISION, (uint8_t*)&staticParams, offset, sizeof(ParamSet_t));
98
  uint8_t result = readChecksummedBlock(EEPARAM_REVISION, (uint8_t*)&staticParams, offset, sizeof(ParamSet_t));
98
  configuration_paramSetDidChange();
99
  configuration_paramSetDidChange();
99
  return result;
100
  return result;
100
}
101
}
101
 
102
 
102
/***************************************************/
103
/***************************************************/
103
/*        Write Parameter Set to EEPROM            */
104
/*        Write Parameter Set to EEPROM            */
104
/***************************************************/
105
/***************************************************/
105
void paramSet_writeToEEProm(uint8_t setnumber) {
106
void paramSet_writeToEEProm(uint8_t setnumber) {
106
  uint16_t offset = EEPROM_ADR_PARAMSET_BEGIN + (setnumber-1)*(sizeof(ParamSet_t)+EEPROM_CHECKSUMMED_BLOCK_OVERHEAD);
107
  uint16_t offset = EEPROM_ADR_PARAMSET_BEGIN + (setnumber-1)*(sizeof(ParamSet_t)+EEPROM_CHECKSUMMED_BLOCK_OVERHEAD);
107
  writeChecksummedBlock(EEPARAM_REVISION, (uint8_t*)&staticParams, offset, sizeof(ParamSet_t));
108
  writeChecksummedBlock(EEPARAM_REVISION, (uint8_t*)&staticParams, offset, sizeof(ParamSet_t));
108
}
109
}
109
 
110
 
110
void paramSet_readOrDefault() {
111
void paramSet_readOrDefault() {
111
  uint8_t setnumber = getActiveParamSet();
112
  uint8_t setnumber = getActiveParamSet();
112
  // parameter version  check
113
  // parameter version  check
113
  if (setnumber<1 ||setnumber>5 || paramSet_readFromEEProm(setnumber)) {
114
  if (setnumber<1 ||setnumber>5 || paramSet_readFromEEProm(setnumber)) {
114
    // if version check faild
115
    // if version check faild
115
    printf("\n\rwriting default parameter sets");
116
    printf("\n\rwriting default parameter sets");
116
    for (uint8_t i=5; i>0; i--) {
117
    for (uint8_t i=5; i>0; i--) {
117
      paramSet_default(i);
118
      paramSet_default(i);
118
      paramSet_writeToEEProm(i);
119
      paramSet_writeToEEProm(i);
119
    }
120
    }
120
    // default-Setting is parameter set 1
121
    // default-Setting is parameter set 1
121
    setActiveParamSet(1);
122
    setActiveParamSet(1);
122
    paramSet_readFromEEProm(getActiveParamSet());
123
    paramSet_readFromEEProm(getActiveParamSet());
123
    // For some strange reason, the read will have no effect.
124
    // For some strange reason, the read will have no effect.
124
    // Lets reset...
125
    // Lets reset...
125
    // wdt_enable(WDTO_500MS);
126
    // wdt_enable(WDTO_500MS);
126
  }
127
  }
127
  printf("\n\r\rUsing Parameter Set %d", getActiveParamSet());
128
  printf("\n\r\rUsing Parameter Set %d", getActiveParamSet());
128
}
129
}
129
 
130
 
130
/***************************************************/
131
/***************************************************/
131
/*          Read IMU Config from EEPROM            */
132
/*          Read IMU Config from EEPROM            */
132
/***************************************************/
133
/***************************************************/
133
uint8_t IMUConfig_readFromEEprom(void) {
134
uint8_t IMUConfig_readFromEEprom(void) {
134
  return readChecksummedBlock(IMUCONFIG_REVISION, (uint8_t*)&IMUConfig, EEPROM_ADR_IMU_CONFIG, sizeof(IMUConfig_t));
135
  return readChecksummedBlock(IMUCONFIG_REVISION, (uint8_t*)&IMUConfig, EEPROM_ADR_IMU_CONFIG, sizeof(IMUConfig_t));
135
}
136
}
136
 
137
 
137
/***************************************************/
138
/***************************************************/
138
/*          Write IMU Config to EEPROM             */
139
/*          Write IMU Config to EEPROM             */
139
/***************************************************/
140
/***************************************************/
140
void IMUConfig_writeToEEprom(void) {
141
void IMUConfig_writeToEEprom(void) {
141
  writeChecksummedBlock(IMUCONFIG_REVISION, (uint8_t*)&IMUConfig, EEPROM_ADR_IMU_CONFIG, sizeof(IMUConfig_t));
142
  writeChecksummedBlock(IMUCONFIG_REVISION, (uint8_t*)&IMUConfig, EEPROM_ADR_IMU_CONFIG, sizeof(IMUConfig_t));
142
}
143
}
143
 
144
 
144
void IMUConfig_readOrDefault(void) {
145
void IMUConfig_readOrDefault(void) {
145
    if(IMUConfig_readFromEEprom()) {
146
    if(IMUConfig_readFromEEprom()) {
146
      printf("\n\rwriting default IMU config");
147
      printf("\n\rwriting default IMU config");
147
      IMUConfig_default();
148
      IMUConfig_default();
148
      IMUConfig_writeToEEprom();
149
      IMUConfig_writeToEEprom();
149
    }
150
    }
150
}
151
}
151
 
152
 
152
/***************************************************/
153
/***************************************************/
153
/* MixerTable                                      */
154
/* MixerTable                                      */
154
/***************************************************/
155
/***************************************************/
155
void motorMixer_writeToEEProm(void) {
156
void outputMixer_writeToEEProm(void) {
156
  writeChecksummedBlock(EEMIXER_REVISION, (uint8_t*)&motorMixer, EEPROM_ADR_MIXER_TABLE, sizeof(MotorMixer_t));
157
  writeChecksummedBlock(EEMIXER_REVISION, (uint8_t*)&outputMixer, EEPROM_ADR_MIXER_TABLE, sizeof(OutputMixer_t));
157
}
158
}
158
 
159
 
159
void motorMixer_readOrDefault(void) {
160
void outputMixer_readOrDefault(void) {
160
  // load mixer table
161
  // load mixer table
161
  if (readChecksummedBlock(EEMIXER_REVISION, (uint8_t*)&motorMixer, EEPROM_ADR_MIXER_TABLE, sizeof(MotorMixer_t))) {
162
  if (readChecksummedBlock(EEMIXER_REVISION, (uint8_t*)&outputMixer, EEPROM_ADR_MIXER_TABLE, sizeof(OutputMixer_t))) {
162
    printf("\n\rwriting default motor mixer");
163
    printf("\n\rwriting default motor mixer");
163
    motorMixer_default(); // Quadro
164
    outputMixer_default(); // Quadro
164
    motorMixer_writeToEEProm();
165
    outputMixer_writeToEEProm();
165
  }
-
 
166
  // determine motornumber
-
 
167
  requiredMotors = 0;
-
 
168
  for (uint8_t i=0; i<MAX_MOTORS; i++) {
-
 
169
    if (motorMixer.matrix[i][MIX_THROTTLE])
-
 
170
      requiredMotors++;
-
 
171
  }
-
 
172
 
-
 
173
  printf("\n\rMixer-Config: '%s' (%u Motors)", motorMixer.name, requiredMotors);
-
 
174
  printf("\n\r===================================");
166
  }
175
}
167
}
176
 
168
 
177
/***************************************************/
169
/***************************************************/
178
/* ChannelMap                                      */
170
/* ChannelMap                                      */
179
/***************************************************/
171
/***************************************************/
180
void channelMap_writeToEEProm(void) {
172
void channelMap_writeToEEProm(void) {
181
  writeChecksummedBlock(CHANNELMAP_REVISION, (uint8_t*)&channelMap, EEPROM_ADR_CHANNELMAP, sizeof(ChannelMap_t));
173
  writeChecksummedBlock(CHANNELMAP_REVISION, (uint8_t*)&channelMap, EEPROM_ADR_CHANNELMAP, sizeof(ChannelMap_t));
182
}
174
}
183
 
175
 
184
void channelMap_readOrDefault(void) {
176
void channelMap_readOrDefault(void) {
185
  if (readChecksummedBlock(CHANNELMAP_REVISION, (uint8_t*)&channelMap, EEPROM_ADR_CHANNELMAP, sizeof(ChannelMap_t))) {
177
  if (readChecksummedBlock(CHANNELMAP_REVISION, (uint8_t*)&channelMap, EEPROM_ADR_CHANNELMAP, sizeof(ChannelMap_t))) {
186
    printf("\n\rwriting default channel map");
178
    printf("\n\rwriting default channel map");
187
    channelMap_default();
179
    channelMap_default();
188
    channelMap_writeToEEProm();
180
    channelMap_writeToEEProm();
189
        wdt_enable(WDTO_500MS);
181
        wdt_enable(WDTO_500MS);
190
  }
182
  }
191
}
183
}
192
 
184
 
193
/***************************************************/
185
/***************************************************/
194
/* Sensor offsets                                  */
186
/* Sensor offsets                                  */
195
/***************************************************/
187
/***************************************************/
196
uint8_t gyroAmplifierOffset_readFromEEProm(void) {
188
uint8_t gyroAmplifierOffset_readFromEEProm(void) {
197
  return readChecksummedBlock(SENSOROFFSET_REVISION, (uint8_t*)&gyroAmplifierOffset, EEPROM_ADR_GYROAMPLIFIER, sizeof(sensorOffset_t));
189
  return readChecksummedBlock(SENSOROFFSET_REVISION, (uint8_t*)&gyroAmplifierOffset, EEPROM_ADR_GYROAMPLIFIER, sizeof(sensorOffset_t));
198
}
190
}
199
 
191
 
200
void gyroAmplifierOffset_writeToEEProm(void) {
192
void gyroAmplifierOffset_writeToEEProm(void) {
201
  return writeChecksummedBlock(SENSOROFFSET_REVISION, (uint8_t*)&gyroAmplifierOffset, EEPROM_ADR_GYROAMPLIFIER, sizeof(sensorOffset_t));
193
  return writeChecksummedBlock(SENSOROFFSET_REVISION, (uint8_t*)&gyroAmplifierOffset, EEPROM_ADR_GYROAMPLIFIER, sizeof(sensorOffset_t));
202
}
194
}
203
 
195
 
204
uint8_t gyroOffset_readFromEEProm(void) {
196
uint8_t gyroOffset_readFromEEProm(void) {
205
  return readChecksummedBlock(SENSOROFFSET_REVISION, (uint8_t*)&gyroOffset, EEPROM_ADR_GYROOFFSET, sizeof(sensorOffset_t));
197
  return readChecksummedBlock(SENSOROFFSET_REVISION, (uint8_t*)&gyroOffset, EEPROM_ADR_GYROOFFSET, sizeof(sensorOffset_t));
206
}
198
}
207
 
199
 
208
void gyroOffset_writeToEEProm(void) {
200
void gyroOffset_writeToEEProm(void) {
209
  writeChecksummedBlock(SENSOROFFSET_REVISION, (uint8_t*)&gyroOffset, EEPROM_ADR_GYROOFFSET, sizeof(sensorOffset_t));
201
  writeChecksummedBlock(SENSOROFFSET_REVISION, (uint8_t*)&gyroOffset, EEPROM_ADR_GYROOFFSET, sizeof(sensorOffset_t));
210
}
202
}
211
 
203
 
212
uint8_t accOffset_readFromEEProm(void) {
204
uint8_t accelOffset_readFromEEProm(void) {
213
  return readChecksummedBlock(SENSOROFFSET_REVISION, (uint8_t*)&accOffset, EEPROM_ADR_ACCOFFSET, sizeof(sensorOffset_t));
205
  return readChecksummedBlock(SENSOROFFSET_REVISION, (uint8_t*)&accelOffset, EEPROM_ADR_ACCELOFFSET, sizeof(sensorOffset_t));
214
}
206
}
215
 
207
 
216
void accOffset_writeToEEProm(void) {
208
void accelOffset_writeToEEProm(void) {
217
  writeChecksummedBlock(SENSOROFFSET_REVISION, (uint8_t*)&accOffset, EEPROM_ADR_ACCOFFSET, sizeof(sensorOffset_t));
209
  writeChecksummedBlock(SENSOROFFSET_REVISION, (uint8_t*)&accelOffset, EEPROM_ADR_ACCELOFFSET, sizeof(sensorOffset_t));
218
}
210
}
219
 
211
 
220
/***************************************************/
212
/***************************************************/
221
/*       Get active parameter set                  */
213
/*       Get active parameter set                  */
222
/***************************************************/
214
/***************************************************/
223
uint8_t getActiveParamSet(void) {
215
uint8_t getActiveParamSet(void) {
224
  uint8_t setnumber;
216
  uint8_t setnumber;
225
  setnumber = eeprom_read_byte(&EEPromArray[PID_ACTIVE_SET]);
217
  setnumber = eeprom_read_byte(&EEPromArray[PID_ACTIVE_SET]);
226
  if (setnumber > 5) {
218
  if (setnumber > 5) {
227
    setActiveParamSet(setnumber = 1);
219
    setActiveParamSet(setnumber = 1);
228
  }
220
  }
229
  return setnumber;
221
  return setnumber;
230
}
222
}
231
 
223
 
232
/***************************************************/
224
/***************************************************/
233
/*       Set active parameter set                  */
225
/*       Set active parameter set                  */
234
/***************************************************/
226
/***************************************************/
235
void setActiveParamSet(uint8_t setnumber) {
227
void setActiveParamSet(uint8_t setnumber) {
236
  eeprom_write_byte(&EEPromArray[PID_ACTIVE_SET], setnumber);
228
  eeprom_write_byte(&EEPromArray[PID_ACTIVE_SET], setnumber);
237
}
229
}
238
 
230
 
239
 
231