// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// + Copyright (c) 04.2007 Holger Buss
// + Nur für den privaten Gebrauch
// + www.MikroKopter.com
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// + Es gilt für das gesamte Projekt (Hardware, Software, Binärfiles, Sourcecode und Dokumentation),
// + dass eine Nutzung (auch auszugsweise) nur f�r den privaten und nicht-kommerziellen Gebrauch zulässig ist.
// + Sollten direkte oder indirekte kommerzielle Absichten verfolgt werden, ist mit uns (info@mikrokopter.de) Kontakt
// + bzgl. der Nutzungsbedingungen aufzunehmen.
// + Eine kommerzielle Nutzung ist z.B.Verkauf von MikroKoptern, Bestückung und Verkauf von Platinen oder Bausätzen,
// + Verkauf von Luftbildaufnahmen, usw.
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// + Werden Teile des Quellcodes (mit oder ohne Modifikation) weiterverwendet oder veröffentlicht,
// + unterliegen sie auch diesen Nutzungsbedingungen und diese Nutzungsbedingungen incl. Copyright müssen dann beiliegen
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// + Sollte die Software (auch auszugesweise) oder sonstige Informationen des MikroKopter-Projekts
// + auf anderen Webseiten oder Medien veröffentlicht werden, muss unsere Webseite "http://www.mikrokopter.de"
// + eindeutig als Ursprung verlinkt und genannt werden
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// + Keine Gewähr auf Fehlerfreiheit, Vollständigkeit oder Funktion
// + Benutzung auf eigene Gefahr
// + Wir übernehmen keinerlei Haftung für direkte oder indirekte Personen- oder Sachschäden
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// + Die Portierung der Software (oder Teile davon) auf andere Systeme (ausser der Hardware von www.mikrokopter.de) ist nur
// + mit unserer Zustimmung zulässig
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// + Die Funktion printf_P() unterliegt ihrer eigenen Lizenz und ist hiervon nicht betroffen
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// + Redistributions of source code (with or without modifications) must retain the above copyright notice,
// + this list of conditions and the following disclaimer.
// + * Neither the name of the copyright holders nor the names of contributors may be used to endorse or promote products derived
// + from this software without specific prior written permission.
// + * The use of this project (hardware, software, binary files, sources and documentation) is only permittet
// + for non-commercial use (directly or indirectly)
// + Commercial use (for example: selling of MikroKopters, selling of PCBs, assembly, ...) is only permitted
// + with our written permission
// + * If sources or documentations are redistributet on other webpages, out webpage (http://www.MikroKopter.de) must be
// + clearly linked as origin
// + * porting to systems other than hardware from www.mikrokopter.de is not allowed
// + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
// + ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
// + LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
// + CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
// + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
// + INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
// + CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
// + ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
// + POSSIBILITY OF SUCH DAMAGE.
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// + Contant Values
// + 0-250 -> normale Values
// + 251 -> Poti1
// + 252 -> Poti2
// + 253 -> Poti3
// + 254 -> Poti4
// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
#ifndef EEMEM
#define EEMEM __attribute__ ((section (".eeprom")))
#endif
#include "eeprom.h"
#include "printf_P.h"
#include "output.h"
#include <avr/eeprom.h>
// byte array in eeprom
uint8_t EEPromArray
[E2END
+ 1] EEMEM
;
/***************************************************/
/* Read Parameter from EEPROM as byte */
/***************************************************/
uint8_t getParamByte
(uint16_t param_id
) {
return eeprom_read_byte
(&EEPromArray
[EEPROM_ADR_PARAM_BEGIN
+ param_id
]);
}
/***************************************************/
/* Write Parameter to EEPROM as byte */
/***************************************************/
void setParamByte
(uint16_t param_id
, uint8_t value
) {
eeprom_write_byte
(&EEPromArray
[EEPROM_ADR_PARAM_BEGIN
+ param_id
], value
);
}
/***************************************************/
/* Read Parameter from EEPROM as word */
/***************************************************/
uint16_t getParamWord
(uint16_t param_id
) {
return eeprom_read_word
((uint16_t *) &EEPromArray
[EEPROM_ADR_PARAM_BEGIN
+ param_id
]);
}
/***************************************************/
/* Write Parameter to EEPROM as word */
/***************************************************/
void setParamWord
(uint16_t param_id
, uint16_t value
) {
eeprom_write_word
((uint16_t *) &EEPromArray
[EEPROM_ADR_PARAM_BEGIN
+ param_id
], value
);
}
uint8_t calculateChecksum
(uint8_t* data
, uint16_t length
) {
uint8_t result
= 0;
for (uint16_t i
=0; i
<length
; i
++) {
result
+= data
[i
];
}
return result
;
}
// offset is where the checksum is stored, offset+1 is the revision number, and offset+2... are the data.
// length is the length of the pure data not including checksum and revision number.
void writeChecksummedBlock
(uint8_t revisionNumber
, uint8_t* data
, uint16_t offset
, uint16_t length
) {
uint8_t checksum
= calculateChecksum
(data
, length
);
eeprom_write_byte
(&EEPromArray
[offset
], checksum
);
eeprom_write_byte
(&EEPromArray
[offset
+1], revisionNumber
);
eeprom_write_block
(data
, &EEPromArray
[offset
+2], length
);
}
// offset is where the checksum is stored, offset+1 is the revision number, and offset+2... are the data.
// length is the length of the pure data not including checksum and revision number.
uint8_t readChecksummedBlock
(uint8_t revisionNumber
, uint8_t* target
, uint16_t offset
, uint16_t length
) {
uint8_t checksumRead
= eeprom_read_byte
(&EEPromArray
[offset
]);
uint8_t revisionNumberRead
= eeprom_read_byte
(&EEPromArray
[offset
+1]);
eeprom_read_block
(target
, &EEPromArray
[offset
+2], length
);
uint8_t checksumCalculated
= calculateChecksum
(target
, length
);
uint8_t checksumError
= (checksumRead
!= checksumCalculated
);
uint8_t revisionMismatch
= (revisionNumber
!= revisionNumberRead
);
if (checksumError
&& revisionMismatch
) printf("\n\rEEPROM checksum error and revision mismatch, ");
else if (checksumError
) printf("\n\rEEPROM checksum error, ");
else if (revisionMismatch
) printf("\n\rEEPROM revision mismatch, ");
return (checksumError
|| revisionMismatch
);
}
/***************************************************/
/* Read Parameter Set from EEPROM */
/***************************************************/
// setnumber [1..5]
uint8_t paramSet_readFromEEProm
(uint8_t setnumber
) {
uint16_t offset
= EEPROM_ADR_PARAMSET_BEGIN
+ (setnumber
-1)*(sizeof(paramset_t
)+2);
output_init
(); // what's that doing here??
return readChecksummedBlock
(EEPARAM_REVISION
, (uint8_t*)&staticParams
, offset
, sizeof(paramset_t
));
}
/***************************************************/
/* Write Parameter Set to EEPROM */
/***************************************************/
void paramSet_writeToEEProm
(uint8_t setnumber
) {
uint16_t offset
= EEPROM_ADR_PARAMSET_BEGIN
+ (setnumber
-1)*(sizeof(paramset_t
)+2);
writeChecksummedBlock
(EEPARAM_REVISION
, (uint8_t*)&staticParams
, offset
, sizeof(paramset_t
));
// set this parameter set to active set
setActiveParamSet
(setnumber
);
output_init
(); // what's that doing here??
}
void paramSet_readOrDefault
() {
uint8_t setnumber
= getActiveParamSet
();
// parameter version check
if (setnumber
<1 ||setnumber
>5 || paramSet_readFromEEProm
(setnumber
)) {
// if version check faild
printf("writing default parameter sets");
for (uint8_t i
=5; i
>0; i
--) {
paramSet_default
(i
);
paramSet_writeToEEProm
(i
);
}
// default-Setting is parameter set 3
setActiveParamSet
(1);
}
printf("\n\r\rUsing Parameter Set %d", getActiveParamSet
());
}
/***************************************************/
/* MixerTable */
/***************************************************/
uint8_t mixerMatrix_readFromEEProm
(void) {
return readChecksummedBlock
(EEMIXER_REVISION
, (uint8_t*)&mixerMatrix
, EEPROM_ADR_MIXER_TABLE
, sizeof(mixerMatrix_t
));
}
void mixerMatrix_writeToEEProm
(void) {
writeChecksummedBlock
(EEMIXER_REVISION
, (uint8_t*)&mixerMatrix
, EEPROM_ADR_MIXER_TABLE
, sizeof(mixerMatrix_t
));
}
void mixerMatrix_readOrDefault
(void) {
// load mixer table
if (mixerMatrix_readFromEEProm
()) {
printf("writing default mixerMatrix");
mixerMatrix_default
(); // Quadro
mixerMatrix_writeToEEProm
();
}
// determine motornumber
requiredMotors
= 0;
for (uint8_t i
=0; i
<MAX_MOTORS
; i
++) {
if (mixerMatrix.
motor[i
][MIX_THROTTLE
])
requiredMotors
++;
}
printf("\n\r\rMixer-Config: '%s' (%u Motors)",mixerMatrix.
name, requiredMotors
);
printf("\n\r\r==============================");
}
/***************************************************/
/* ChannelMap */
/***************************************************/
uint8_t channelMap_readFromEEProm
(void) {
return readChecksummedBlock
(CHANNELMAP_REVISION
, (uint8_t*)&channelMap
, EEPROM_ADR_CHANNELMAP
, sizeof(channelMap_t
));
}
void channelMap_writeToEEProm
(void) {
writeChecksummedBlock
(CHANNELMAP_REVISION
, (uint8_t*)&channelMap
, EEPROM_ADR_CHANNELMAP
, sizeof(channelMap_t
));
}
void channelMap_readOrDefault
(void) {
if (channelMap_readFromEEProm
()) {
printf("writing default channel map");
channelMap_default
();
channelMap_writeToEEProm
();
}
}
/***************************************************/
/* Sensor offsets */
/***************************************************/
uint8_t gyroOffset_readFromEEProm
(void) {
return readChecksummedBlock
(SENSOROFFSET_REVISION
, (uint8_t*)&gyroOffset
, EEPROM_ADR_GYROOFFSET
, sizeof(sensorOffset_t
));
}
void gyroOffset_writeToEEProm
(void) {
writeChecksummedBlock
(SENSOROFFSET_REVISION
, (uint8_t*)&gyroOffset
, EEPROM_ADR_GYROOFFSET
, sizeof(sensorOffset_t
));
}
uint8_t accOffset_readFromEEProm
(void) {
return readChecksummedBlock
(SENSOROFFSET_REVISION
, (uint8_t*)&accOffset
, EEPROM_ADR_ACCOFFSET
, sizeof(sensorOffset_t
));
}
void accOffset_writeToEEProm
(void) {
writeChecksummedBlock
(SENSOROFFSET_REVISION
, (uint8_t*)&accOffset
, EEPROM_ADR_ACCOFFSET
, sizeof(sensorOffset_t
));
}
/***************************************************/
/* Get active parameter set */
/***************************************************/
uint8_t getActiveParamSet
(void) {
uint8_t setnumber
;
setnumber
= eeprom_read_byte
(&EEPromArray
[PID_ACTIVE_SET
]);
if (setnumber
> 4) {
setActiveParamSet
(setnumber
= 0);
}
return setnumber
;
}
/***************************************************/
/* Set active parameter set */
/***************************************************/
void setActiveParamSet
(uint8_t setnumber
) {
eeprom_write_byte
(&EEPromArray
[PID_ACTIVE_SET
], setnumber
);
}