/tags/V2.12a/FlightCtrl.aps |
---|
0,0 → 1,0 |
<AVRStudio><MANAGEMENT><ProjectName>FlightCtrl</ProjectName><Created>15-May-2007 11:20:41</Created><LastEdit>11-Oct-2007 22:58:54</LastEdit><ICON>241</ICON><ProjectType>0</ProjectType><Created>15-May-2007 11:20:41</Created><Version>4</Version><Build>4, 13, 0, 528</Build><ProjectTypeName>AVR GCC</ProjectTypeName></MANAGEMENT><CODE_CREATION><ObjectFile>default\Flight-Ctrl.elf</ObjectFile><EntryFile></EntryFile><SaveFolder>F:\SVN\MikroKopter\FlightCtrl\branches\V0.64_ZeroWarnings\</SaveFolder></CODE_CREATION><DEBUG_TARGET><CURRENT_TARGET>AVR Simulator</CURRENT_TARGET><CURRENT_PART>ATmega644.xml</CURRENT_PART><BREAKPOINTS></BREAKPOINTS><IO_EXPAND><HIDE>false</HIDE></IO_EXPAND><REGISTERNAMES><Register>R00</Register><Register>R01</Register><Register>R02</Register><Register>R03</Register><Register>R04</Register><Register>R05</Register><Register>R06</Register><Register>R07</Register><Register>R08</Register><Register>R09</Register><Register>R10</Register><Register>R11</Register><Register>R12</Register><Register>R13</Register><Register>R14</Register><Register>R15</Register><Register>R16</Register><Register>R17</Register><Register>R18</Register><Register>R19</Register><Register>R20</Register><Register>R21</Register><Register>R22</Register><Register>R23</Register><Register>R24</Register><Register>R25</Register><Register>R26</Register><Register>R27</Register><Register>R28</Register><Register>R29</Register><Register>R30</Register><Register>R31</Register></REGISTERNAMES><COM>Auto</COM><COMType>0</COMType><WATCHNUM>0</WATCHNUM><WATCHNAMES><Pane0></Pane0><Pane1></Pane1><Pane2></Pane2><Pane3></Pane3></WATCHNAMES><BreakOnTrcaeFull>0</BreakOnTrcaeFull></DEBUG_TARGET><Debugger><Triggers></Triggers></Debugger><AVRGCCPLUGIN><FILES><SOURCEFILE>uart.c</SOURCEFILE><SOURCEFILE>analog.c</SOURCEFILE><SOURCEFILE>eeprom.c</SOURCEFILE><SOURCEFILE>fc.c</SOURCEFILE><SOURCEFILE>GPS.c</SOURCEFILE><SOURCEFILE>main.c</SOURCEFILE><SOURCEFILE>menu.c</SOURCEFILE><SOURCEFILE>printf_P.c</SOURCEFILE><SOURCEFILE>rc.c</SOURCEFILE><SOURCEFILE>timer0.c</SOURCEFILE><SOURCEFILE>twimaster.c</SOURCEFILE><HEADERFILE>uart.h</HEADERFILE><HEADERFILE>_Settings.h</HEADERFILE><HEADERFILE>analog.h</HEADERFILE><HEADERFILE>fc.h</HEADERFILE><HEADERFILE>gps.h</HEADERFILE><HEADERFILE>main.h</HEADERFILE><HEADERFILE>menu.h</HEADERFILE><HEADERFILE>old_macros.h</HEADERFILE><HEADERFILE>printf_P.h</HEADERFILE><HEADERFILE>rc.h</HEADERFILE><HEADERFILE>Settings.h</HEADERFILE><HEADERFILE>timer0.h</HEADERFILE><HEADERFILE>twimaster.h</HEADERFILE></FILES><CONFIGS><CONFIG><NAME>default</NAME><USESEXTERNALMAKEFILE>NO</USESEXTERNALMAKEFILE><EXTERNALMAKEFILE></EXTERNALMAKEFILE><PART>atmega644</PART><HEX>1</HEX><LIST>1</LIST><MAP>1</MAP><OUTPUTFILENAME>Flight-Ctrl.elf</OUTPUTFILENAME><OUTPUTDIR>default\</OUTPUTDIR><ISDIRTY>1</ISDIRTY><OPTIONS><OPTION><FILE>GPS.c</FILE><OPTIONLIST></OPTIONLIST></OPTION><OPTION><FILE>analog.c</FILE><OPTIONLIST></OPTIONLIST></OPTION><OPTION><FILE>eeprom.c</FILE><OPTIONLIST></OPTIONLIST></OPTION><OPTION><FILE>fc.c</FILE><OPTIONLIST></OPTIONLIST></OPTION><OPTION><FILE>main.c</FILE><OPTIONLIST></OPTIONLIST></OPTION><OPTION><FILE>menu.c</FILE><OPTIONLIST></OPTIONLIST></OPTION><OPTION><FILE>printf_P.c</FILE><OPTIONLIST></OPTIONLIST></OPTION><OPTION><FILE>rc.c</FILE><OPTIONLIST></OPTIONLIST></OPTION><OPTION><FILE>timer0.c</FILE><OPTIONLIST></OPTIONLIST></OPTION><OPTION><FILE>twimaster.c</FILE><OPTIONLIST></OPTIONLIST></OPTION><OPTION><FILE>uart.c</FILE><OPTIONLIST></OPTIONLIST></OPTION></OPTIONS><INCDIRS/><LIBDIRS/><LIBS><LIB>libc.a</LIB><LIB>libm.a</LIB></LIBS><LINKOBJECTS/><OPTIONSFORALL>-Wall -gdwarf-2 -Wstrict-prototypes -std=gnu99 -Os -funsigned-char -funsigned-bitfields -fpack-struct -fshort-enums -DVERSION_HAUPTVERSION=0 -DVERSION_NEBENVERSION=64 -DVERSION_KOMPATIBEL=5</OPTIONSFORALL><LINKEROPTIONS></LINKEROPTIONS><SEGMENTS/></CONFIG></CONFIGS><LASTCONFIG>default</LASTCONFIG><USES_WINAVR>1</USES_WINAVR><GCC_LOC>C:\Program Files\WinAVR\bin\avr-gcc.exe</GCC_LOC><MAKE_LOC>C:\Program Files\WinAVR\utils\bin\make.exe</MAKE_LOC></AVRGCCPLUGIN><IOView><usergroups/></IOView><Files><File00000><FileId>00000</FileId><FileName>main.c</FileName><Status>1</Status></File00000><File00001><FileId>00001</FileId><FileName>uart.c</FileName><Status>1</Status></File00001><File00002><FileId>00002</FileId><FileName>menu.c</FileName><Status>1</Status></File00002><File00003><FileId>00003</FileId><FileName>timer0.c</FileName><Status>1</Status></File00003><File00004><FileId>00004</FileId><FileName>fc.c</FileName><Status>1</Status></File00004><File00005><FileId>00005</FileId><FileName>fc.h</FileName><Status>1</Status></File00005><File00006><FileId>00006</FileId><FileName>menu.h</FileName><Status>1</Status></File00006><File00007><FileId>00007</FileId><FileName>TWIMASTER.C</FileName><Status>1</Status></File00007><File00008><FileId>00008</FileId><FileName>twimaster.h</FileName><Status>1</Status></File00008><File00009><FileId>00009</FileId><FileName>uart.h</FileName><Status>1</Status></File00009><File00010><FileId>00010</FileId><FileName>_Settings.h</FileName><Status>1</Status></File00010><File00011><FileId>00011</FileId><FileName>analog.h</FileName><Status>1</Status></File00011><File00012><FileId>00012</FileId><FileName>gps.h</FileName><Status>1</Status></File00012><File00013><FileId>00013</FileId><FileName>main.h</FileName><Status>1</Status></File00013><File00014><FileId>00014</FileId><FileName>old_macros.h</FileName><Status>1</Status></File00014><File00015><FileId>00015</FileId><FileName>printf_P.h</FileName><Status>1</Status></File00015><File00016><FileId>00016</FileId><FileName>rc.h</FileName><Status>1</Status></File00016><File00017><FileId>00017</FileId><FileName>Settings.h</FileName><Status>1</Status></File00017><File00018><FileId>00018</FileId><FileName>timer0.h</FileName><Status>1</Status></File00018></Files><Events><Bookmarks></Bookmarks></Events><Trace><Filters></Filters></Trace></AVRStudio> |
/tags/V2.12a/GPS.c |
---|
0,0 → 1,16 |
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
// + Copyright (c) Holger Buss, Ingo Busker |
// + only for non-profit use |
// + www.MikroKopter.com |
// + see the File "License.txt" for further Informations |
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
#include "main.h" |
signed int GPS_Nick = 0; |
signed int GPS_Roll = 0; |
unsigned char GPS_Aid_StickMultiplikator = 0; // 64 = 100% |
/tags/V2.12a/Hex-Files/License.txt |
---|
0,0 → 1,69 |
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
// + www.MikroKopter.com |
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
// + Software Nutzungsbedingungen (english version: see below) |
// + der Fa. HiSystems GmbH, Flachsmeerstrasse 2, 26802 Moormerland - nachfolgend Lizenzgeber genannt - |
// + |
// + Der Lizenzgeber räumt dem Kunden ein nicht-ausschließliches, zeitlich und räumlich* unbeschränktes Recht ein, die im den |
// + Mikrocontroller verwendete Firmware für die Hardware Flight-Ctrl, Navi-Ctrl, BL-Ctrl, MK3Mag & PC-Programm MikroKopter-Tool |
// + - nachfolgend Software genannt - nur für private Zwecke zu nutzen. |
// + Der Einsatz dieser Software ist nur auf oder mit Produkten des Lizenzgebers zulässig. |
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
// + Die vom Lizenzgeber gelieferte Software ist urheberrechtlich geschützt. Alle Rechte an der Software sowie an sonstigen im |
// + Rahmen der Vertragsanbahnung und Vertragsdurchführung überlassenen Unterlagen stehen im Verhältnis der Vertragspartner ausschließlich dem Lizenzgeber zu. |
// + Die in der Software enthaltenen Copyright-Vermerke, Markenzeichen, andere Rechtsvorbehalte, Seriennummern sowie |
// + sonstige der Programmidentifikation dienenden Merkmale dürfen vom Kunden nicht verändert oder unkenntlich gemacht werden. |
// + Der Kunde trifft angemessene Vorkehrungen für den sicheren Einsatz der Software. Er wird die Software gründlich auf deren |
// + Verwendbarkeit zu dem von ihm beabsichtigten Zweck testen, bevor er diese operativ einsetzt. |
// + Die Haftung des Lizenzgebers wird - soweit gesetzlich zulässig - begrenzt in Höhe des typischen und vorhersehbaren |
// + Schadens. Die gesetzliche Haftung bei Personenschäden und nach dem Produkthaftungsgesetz bleibt unberührt. Dem Lizenzgeber steht jedoch der Einwand |
// + des Mitverschuldens offen. |
// + Der Kunde trifft angemessene Vorkehrungen für den Fall, dass die Software ganz oder teilweise nicht ordnungsgemäß arbeitet. |
// + Er wird die Software gründlich auf deren Verwendbarkeit zu dem von ihm beabsichtigten Zweck testen, bevor er diese operativ einsetzt. |
// + Der Kunde wird er seine Daten vor Einsatz der Software nach dem Stand der Technik sichern. |
// + Der Kunde ist darüber unterrichtet, dass der Lizenzgeber seine Daten im zur Vertragsdurchführung erforderlichen Umfang |
// + und auf Grundlage der Datenschutzvorschriften erhebt, speichert, verarbeitet und, sofern notwendig, an Dritte übermittelt. |
// + *) Die räumliche Nutzung bezieht sich nur auf den Einsatzort, nicht auf die Reichweite der programmierten Software. |
// + #### ENDE DER NUTZUNGSBEDINGUNGEN ####' |
// + Hinweis: Informationen über erweiterte Nutzungsrechte (wie z.B. Nutzung für nicht-private Zwecke) sind auf Anfrage per Email an info(@)hisystems.de verfügbar. |
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
// + Software LICENSING TERMS |
// + of HiSystems GmbH, Flachsmeerstrasse 2, 26802 Moormerland, Germany - the Licensor - |
// + |
// + The Licensor grants the customer a non-exclusive license to use the microcontroller firmware of the Flight-Ctrl, Navi-Ctrl, BL-Ctrl, and MK3Mag hardware |
// + (the Software) exclusively for private purposes. The License is unrestricted with respect to time and territory*. |
// + The Software may only be used with the Licensor's products. |
// + The Software provided by the Licensor is protected by copyright. With respect to the relationship between the parties to this |
// + agreement, all rights pertaining to the Software and other documents provided during the preparation and execution of this |
// + agreement shall be the property of the Licensor. |
// + The information contained in the Software copyright notices, trademarks, other legal reservations, serial numbers and other |
// + features that can be used to identify the program may not be altered or defaced by the customer. |
// + The customer shall be responsible for taking reasonable precautions |
// + for the safe use of the Software. The customer shall test the Software thoroughly regarding its suitability for the |
// + intended purpose before implementing it for actual operation. The Licensor's liability shall be limited to the extent of typical and |
// + foreseeable damage to the extent permitted by law, notwithstanding statutory liability for bodily injury and product |
// + liability. However, the Licensor shall be entitled to the defense of contributory negligence. |
// + The customer will take adequate precautions in the case, that the software is not working properly. The customer will test |
// + the software for his purpose before any operational usage. The customer will backup his data before using the software. |
// + The customer understands that the Licensor collects, stores and processes, and, where required, forwards, customer data |
// + to third parties to the extent necessary for executing the agreement, subject to applicable data protection and privacy regulations. |
// + *) The territory aspect only refers to the place where the Software is used, not its programmed range. |
// + #### END OF LICENSING TERMS #### |
// + Note: For information on license extensions (e.g. commercial use), please contact us at info(@)hisystems.de. |
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
// + |
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
// + * porting the sources to other systems or using the software on other systems (except 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. |
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
/tags/V2.12a/Hex-Files/REDUNDANCE |
---|
Property changes: |
Added: bugtraq:number |
+true |
\ No newline at end of property |
Added: tsvn:logminsize |
+8 |
\ No newline at end of property |
/tags/V2.12a/Hex-Files/WasIstWas.txt |
---|
0,0 → 1,14 |
+++++++++++++++++++++++++ |
+ Flight-Ctrl: |
+++++++++++++++++++++++++ |
Flight-Ctrl_MEGA1284_Vx_yy.hex |
Flight-Ctrl_MEGA644_Vx_yy.hex |
Aktuelle Firmware |
Wird per serielle Schnittstelle (durch den Bootloader) eingespielt |
Achtung: Die Programme für den ATMEGA1284 dürfen ausschliesslich per Bootloader, also seriell (MKUSB) eingespielt werden und NICHT per ISP |
Warning: do not program the ATMEGA1284 (FC2.1) via SPI. Only use the MKUSB and the Koptertool for update! |
/tags/V2.12a/License.txt |
---|
0,0 → 1,52 |
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
// + www.MikroKopter.com |
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
// + Software Nutzungsbedingungen (english version: see below) |
// + der Fa. HiSystems GmbH, Flachsmeerstrasse 2, 26802 Moormerland - nachfolgend Lizenzgeber genannt - |
// + Der Lizenzgeber räumt dem Kunden ein nicht-ausschließliches, zeitlich und räumlich* unbeschränktes Recht ein, die im den |
// + Mikrocontroller verwendete Firmware für die Hardware Flight-Ctrl, Navi-Ctrl, BL-Ctrl, MK3Mag & PC-Programm MikroKopter-Tool |
// + - nachfolgend Software genannt - nur für private Zwecke zu nutzen. |
// + Der Einsatz dieser Software ist nur auf oder mit Produkten des Lizenzgebers zulässig. |
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
// + Die vom Lizenzgeber gelieferte Software ist urheberrechtlich geschützt. Alle Rechte an der Software sowie an sonstigen im |
// + Rahmen der Vertragsanbahnung und Vertragsdurchführung überlassenen Unterlagen stehen im Verhältnis der Vertragspartner ausschließlich dem Lizenzgeber zu. |
// + Die in der Software enthaltenen Copyright-Vermerke, Markenzeichen, andere Rechtsvorbehalte, Seriennummern sowie |
// + sonstige der Programmidentifikation dienenden Merkmale dürfen vom Kunden nicht verändert oder unkenntlich gemacht werden. |
// + Der Kunde trifft angemessene Vorkehrungen für den sicheren Einsatz der Software. Er wird die Software gründlich auf deren |
// + Verwendbarkeit zu dem von ihm beabsichtigten Zweck testen, bevor er diese operativ einsetzt. |
// + Die Haftung des Lizenzgebers wird - soweit gesetzlich zulässig - begrenzt in Höhe des typischen und vorhersehbaren |
// + Schadens. Die gesetzliche Haftung bei Personenschäden und nach dem Produkthaftungsgesetz bleibt unberührt. Dem Lizenzgeber steht jedoch der Einwand |
// + des Mitverschuldens offen. |
// + Der Kunde trifft angemessene Vorkehrungen für den Fall, dass die Software ganz oder teilweise nicht ordnungsgemäß arbeitet. |
// + Er wird die Software gründlich auf deren Verwendbarkeit zu dem von ihm beabsichtigten Zweck testen, bevor er diese operativ einsetzt. |
// + Der Kunde wird er seine Daten vor Einsatz der Software nach dem Stand der Technik sichern. |
// + Der Kunde ist darüber unterrichtet, dass der Lizenzgeber seine Daten im zur Vertragsdurchführung erforderlichen Umfang |
// + und auf Grundlage der Datenschutzvorschriften erhebt, speichert, verarbeitet und, sofern notwendig, an Dritte übermittelt. |
// + *) Die räumliche Nutzung bezieht sich nur auf den Einsatzort, nicht auf die Reichweite der programmierten Software. |
// + #### ENDE DER NUTZUNGSBEDINGUNGEN ####' |
// + Hinweis: Informationen über erweiterte Nutzungsrechte (wie z.B. Nutzung für nicht-private Zwecke) sind auf Anfrage per Email an info(@)hisystems.de verfügbar. |
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
// + Software LICENSING TERMS |
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
// + of HiSystems GmbH, Flachsmeerstrasse 2, 26802 Moormerland, Germany - the Licensor - |
// + The Licensor grants the customer a non-exclusive license to use the microcontroller firmware of the Flight-Ctrl, Navi-Ctrl, BL-Ctrl, and MK3Mag hardware |
// + (the Software) exclusively for private purposes. The License is unrestricted with respect to time and territory*. |
// + The Software may only be used with the Licensor's products. |
// + The Software provided by the Licensor is protected by copyright. With respect to the relationship between the parties to this |
// + agreement, all rights pertaining to the Software and other documents provided during the preparation and execution of this |
// + agreement shall be the property of the Licensor. |
// + The information contained in the Software copyright notices, trademarks, other legal reservations, serial numbers and other |
// + features that can be used to identify the program may not be altered or defaced by the customer. |
// + The customer shall be responsible for taking reasonable precautions |
// + for the safe use of the Software. The customer shall test the Software thoroughly regarding its suitability for the |
// + intended purpose before implementing it for actual operation. The Licensor's liability shall be limited to the extent of typical and |
// + foreseeable damage to the extent permitted by law, notwithstanding statutory liability for bodily injury and product |
// + liability. However, the Licensor shall be entitled to the defense of contributory negligence. |
// + The customer will take adequate precautions in the case, that the software is not working properly. The customer will test |
// + the software for his purpose before any operational usage. The customer will backup his data before using the software. |
// + The customer understands that the Licensor collects, stores and processes, and, where required, forwards, customer data |
// + to third parties to the extent necessary for executing the agreement, subject to applicable data protection and privacy regulations. |
// + *) The territory aspect only refers to the place where the Software is used, not its programmed range. |
// + #### END OF LICENSING TERMS #### |
// + Note: For information on license extensions (e.g. commercial use), please contact us at info(@)hisystems.de. |
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
/tags/V2.12a/M-Link.c |
---|
0,0 → 1,70 |
//############################################################################ |
// MULTIPLEX Servo protocol SRXL16 & SRXL12 |
//############################################################################ |
#if (defined(__AVR_ATmega1284__) || defined(__AVR_ATmega1284P__)) |
#include "Spektrum.h" |
#include "M-Link.h" |
#include "main.h" |
unsigned char NewMlinkData = 0; |
unsigned char MlinkData[36]; |
//############################################################################ |
// Initializes the UART here |
//############################################################################ |
void MlinkUartInit(void) |
{ |
SpektrumUartInit(); // same like Spektrum |
}; |
//############################################################################ |
// Is called by the uart RX interrupt |
// UDR contains the received byte |
//############################################################################ |
void MlinkParser(unsigned char udr) |
{ |
static unsigned char state = 0, lenght = 0; |
if(!SpektrumTimer) // Timeout-> block finished |
{ |
if(state > 24 && state < 36) // udr = 0xA1 oder A2 |
{ |
if(udr == 0xA1) lenght = 12 * 2 + 2; // 12 channels plus CRC |
else |
if(udr == 0xA2) lenght = 16 * 2 + 2; // 16 channels plus CRC |
else lenght = 0; |
} else lenght = 0; |
state = 0; |
} |
else |
{ |
if(state < sizeof(MlinkData)) |
{ |
MlinkData[state++] = udr; |
if(state == lenght) // last Byte received |
{ |
NewMlinkData = lenght - 2; // without CRC |
lenght = 0; |
} |
} |
} |
SpektrumTimer = 100; // 10ms Timeout |
}; |
void ProcessMlinkData(void) |
{ |
unsigned char i = 0; |
unsigned int tmp; |
while(i < NewMlinkData) |
{ |
tmp = (unsigned int) MlinkData[i] * 256 + MlinkData[i + 1]; |
tmp /= 13; |
i += 2; |
s_update(i/2, (signed int) tmp - 156); // copies the values into the Channel-Data and calculates the PPM_Diff |
SenderOkay = 220; |
} |
Channels = i/2 + 1; |
NewPpmData = 0; // Null bedeutet: Neue Daten |
NewMlinkData = 0; |
} |
#endif |
/tags/V2.12a/M-Link.h |
---|
0,0 → 1,9 |
#ifndef _MLINK_H |
#define _MLINK_H |
extern unsigned char NewMlinkData; |
extern void MlinkParser(unsigned char); |
extern void MlinkUartInit(void); |
extern void ProcessMlinkData(void); |
#endif |
/tags/V2.12a/Settings.h |
---|
--- tags/V2.12a/Spektrum.c (nonexistent) |
+++ tags/V2.12a/Spektrum.c (revision 2580) |
@@ -0,0 +1,406 @@ |
+/*####################################################################################### |
+Decodieren eines RC Summen Signals oder Spektrum Empfänger-Satellit |
+#######################################################################################*/ |
+ |
+#include "Spektrum.h" |
+#include "main.h" |
+ |
+unsigned char SpektrumTimer = 0; |
+ |
+// Achtung: RECEIVER_SPEKTRUM_DX7EXP oder RECEIVER_SPEKTRUM_DX8EXP wird in der main.h gesetzt |
+#if defined (RECEIVER_SPEKTRUM_DX7EXP) || defined (RECEIVER_SPEKTRUM_DX8EXP) |
+unsigned char s_excnt = 0; // Bitcounter for Spektrum-Expander |
+unsigned char s_exparity = 0; // Parity Bit for Spektrum-Expander |
+signed char s_exdata[11]; // Data for Spektrum-Expander |
+#endif |
+ |
+void s_update(unsigned char channel, signed int value) // Channel-Diff numbercrunching and finally assign new stickvalue to PPM_in |
+{ |
+ if(SenderOkay >= 180) PPM_diff[channel] = ((value - PPM_in[channel]) / 3) * 3; |
+ else PPM_diff[channel] = 0; |
+ PPM_in[channel] = value; |
+} |
+ |
+//############################################################################ |
+// USART1 initialisation from killagreg |
+void SpektrumUartInit(void) |
+//############################################################################ |
+ { |
+ // -- Start of USART1 initialisation for Spekturm seriell-mode |
+ // USART1 Control and Status Register A, B, C and baud rate register |
+ uint8_t sreg = SREG; |
+ |
+ uint16_t ubrr = (uint16_t) ((uint32_t) SYSCLK/(8 * 115200) - 1); |
+ |
+ // disable all interrupts before reconfiguration |
+ cli(); |
+ // disable RX-Interrupt |
+ UCSR1B &= ~(1 << RXCIE1); |
+ // disable TX-Interrupt |
+ UCSR1B &= ~(1 << TXCIE1); |
+ // disable DRE-Interrupt |
+ UCSR1B &= ~(1 << UDRIE1); |
+/* |
+ // set direction of RXD1 and TXD1 pins |
+ // set RXD1 (PD2) as an input pin |
+ PORTD |= (1 << PORTD2); |
+ DDRD &= ~(1 << DDD2); |
+ // set TXD1 (PD3) as an output pin |
+ PORTD |= (1 << PORTD3); |
+ DDRD |= (1 << DDD3); |
+*/ |
+ // USART0 Baud Rate Register |
+ // set clock divider |
+ UBRR1H = (uint8_t)(ubrr>>8); |
+ UBRR1L = (uint8_t)ubrr; |
+ // enable double speed operation |
+ UCSR1A |= (1 << U2X1); |
+ // enable receiver and transmitter |
+ //UCSR1B = (1<<RXEN1)|(1<<TXEN1); |
+ |
+ UCSR1B = (1<<RXEN1); |
+ // set asynchronous mode |
+ UCSR1C &= ~(1 << UMSEL11); |
+ UCSR1C &= ~(1 << UMSEL10); |
+ // no parity |
+ UCSR1C &= ~(1 << UPM11); |
+ UCSR1C &= ~(1 << UPM10); |
+ // 1 stop bit |
+ UCSR1C &= ~(1 << USBS1); |
+ // 8-bit |
+ UCSR1B &= ~(1 << UCSZ12); |
+ UCSR1C |= (1 << UCSZ11); |
+ UCSR1C |= (1 << UCSZ10); |
+ // flush receive buffer explicit |
+ while(UCSR1A & (1<<RXC1)) UDR1; |
+ // enable RX-interrupts at the end |
+ UCSR1B |= (1 << RXCIE1); |
+ // -- End of USART1 initialisation |
+ // restore global interrupt flags |
+ |
+ SREG = sreg; |
+ return; |
+ } |
+ |
+// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
+// + Copyright (c) Rainer Walther |
+// + RC-routines from original MK rc.c (c) H&I |
+// + Useful infos from Walter: http://www.rcgroups.com/forums/showthread.php?t=714299&page=2 |
+// + only for non-profit use |
+// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
+// |
+// 20080808 rw Modified for Spektrum AR6100 (PPM) |
+// 20080823 rw Add Spektrum satellite receiver on USART1 (644P only) |
+// 20081213 rw Add support for Spektrum DS9 Air-Tx-Module (9 channels) |
+// Replace AR6100-coding with original composit-signal routines |
+// |
+// --- |
+// Entweder Summensignal ODER Spektrum-Receiver anschließen. Nicht beides gleichzeitig betreiben! |
+// Binding is not implemented. Bind with external Receiver. |
+// Servo output J3, J4, J5 not serviced |
+// |
+// Anschuß Spektrum Receiver |
+// Orange: 3V von der FC (keinesfalls an 5V anschließen!) |
+// Schwarz: GND |
+// Grau: RXD1 (Pin 3) auf 10-Pol FC-Stecker |
+// |
+// --- |
+// Satellite-Reciever connected on USART1: |
+// |
+// DX7/DX6i: One data-frame at 115200 baud every 22ms. |
+// DX7se: One data-frame at 115200 baud every 11ms. |
+// byte1: unknown |
+// byte2: unknown |
+// byte3: and byte4: channel data (FLT-Mode) |
+// byte5: and byte6: channel data (Roll) |
+// byte7: and byte8: channel data (Nick) |
+// byte9: and byte10: channel data (Gier) |
+// byte11: and byte12: channel data (Gear Switch) |
+// byte13: and byte14: channel data (Gas) |
+// byte15: and byte16: channel data (AUX2) |
+// |
+// DS9 (9 Channel): One data-frame at 115200 baud every 11ms, alternating frame 1/2 for CH1-7 / CH8-9 |
+// 1st Frame: |
+// byte1: unknown |
+// byte2: unknown |
+// byte3: and byte4: channel data |
+// byte5: and byte6: channel data |
+// byte7: and byte8: channel data |
+// byte9: and byte10: channel data |
+// byte11: and byte12: channel data |
+// byte13: and byte14: channel data |
+// byte15: and byte16: channel data |
+// 2nd Frame: |
+// byte1: unknown |
+// byte2: unknown |
+// byte3: and byte4: channel data |
+// byte5: and byte6: channel data |
+// byte7: and byte8: 0xffff |
+// byte9: and byte10: 0xffff |
+// byte11: and byte12: 0xffff |
+// byte13: and byte14: 0xffff |
+// byte15: and byte16: 0xffff |
+// |
+// Each channel data (16 bit= 2byte, first msb, second lsb) is arranged as: |
+// |
+// Bits: F 0 C3 C2 C1 C0 D9 D8 D7 D6 D5 D4 D3 D2 D1 D0 |
+// |
+// 0 means a '0' bit |
+// F: 1 = indicates beginning of 2nd frame for CH8-9 (DS9 only) |
+// C3 to C0 is the channel number. 0 to 9 (4 bit, as assigned in the transmitter) |
+// D9 to D0 is the channel data (10 bit) 0xaa..0x200..0x356 for 100% transmitter-travel |
+// |
+// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
+ |
+#define MIN_FRAMEGAP 68 // 7ms |
+#define MAX_BYTEGAP 3 // 310us |
+ |
+ |
+//############################################################################ |
+// Wird im UART-Interrupt aufgerufen |
+//############################################################################ |
+void SpektrumParser(unsigned char c) |
+{ |
+ static unsigned char Sync=0, FrameCnt=0, ByteHigh=0, ReSync=1, Frame2=0; |
+ unsigned int Channel, index = 0; |
+ signed int signal = 0, tmp; |
+ int bCheckDelay; |
+// c = UDR1; // get data byte |
+ if(ReSync == 1) |
+ { |
+ // wait for beginning of new frame |
+ ReSync = 0; |
+ SpektrumTimer = MIN_FRAMEGAP; |
+ FrameCnt = 0; |
+ Sync = 0; |
+ ByteHigh = 0; |
+ } |
+ else |
+ { |
+ if(!SpektrumTimer) bCheckDelay = 1; else bCheckDelay = 0;//CheckDelay(FrameTimer); |
+ if ( Sync == 0 ) |
+ { |
+ if(bCheckDelay) |
+ { |
+ // nach einer Pause von mind. 7ms erstes Sync-Character gefunden |
+ // Zeichen ignorieren, da Bedeutung unbekannt |
+ Sync = 1; |
+ FrameCnt ++; |
+ SpektrumTimer = MAX_BYTEGAP; |
+ } |
+ else |
+ { |
+ // Zeichen kam vor Ablauf der 7ms Sync-Pause |
+ // warten auf erstes Sync-Zeichen |
+ SpektrumTimer = MIN_FRAMEGAP; |
+ FrameCnt = 0; |
+ Sync = 0; |
+ ByteHigh = 0; |
+ } |
+ } |
+ else if((Sync == 1) && !bCheckDelay) |
+ { |
+ // zweites Sync-Character ignorieren, Bedeutung unbekannt |
+ Sync = 2; |
+ FrameCnt ++; |
+ SpektrumTimer = MAX_BYTEGAP; |
+ } |
+ else if((Sync == 2) && !bCheckDelay) |
+ { |
+ SpektrumTimer = MAX_BYTEGAP; |
+ // Datenbyte high |
+ ByteHigh = c; |
+ if (FrameCnt == 2) |
+ { |
+ // is 1st Byte of Channel-data |
+ // Frame 1 with Channel 1-7 comming next |
+ Frame2 = 0; |
+ if(ByteHigh & 0x80) |
+ { |
+ // DS9: Frame 2 with Channel 8-9 comming next |
+ Frame2 = 1; |
+ } |
+ } |
+ Sync = 3; |
+ FrameCnt ++; |
+ } |
+ else if((Sync == 3) && !bCheckDelay) |
+ { |
+ // Datenbyte low |
+ // High-Byte for next channel comes next |
+ SpektrumTimer = MAX_BYTEGAP; |
+ Sync = 2; |
+ FrameCnt ++; |
+ Channel = ((unsigned int)ByteHigh << 8) | c; |
+ if(EE_Parameter.Receiver == RECEIVER_SPEKTRUM) |
+ { |
+ signal = Channel & 0x3ff; |
+ signal -= 0x200; // Offset, range 0x000..0x3ff? |
+ signal = signal/3; // scaling to fit PPM resolution |
+ index = (ByteHigh >> 2) & 0x0f; |
+ } |
+ else |
+ if(EE_Parameter.Receiver == RECEIVER_SPEKTRUM_HI_RES) |
+ { |
+ signal = Channel & 0x7ff; |
+ signal -= 0x400; // Offset, range 0x000..0x7ff? |
+ signal = signal/6; // scaling to fit PPM resolution |
+ index = (ByteHigh >> 3) & 0x0f; |
+ } |
+ else |
+ //if(EE_Parameter.Receiver == RECEIVER_SPEKTRUM_LOW_RES) |
+ { |
+ signal = Channel & 0x3ff; |
+ signal -= 360; // Offset, range 0x000..0x3ff? |
+ signal = signal/2; // scaling to fit PPM resolution |
+ index = (ByteHigh >> 2) & 0x0f; |
+ } |
+ |
+ index++; |
+ if(index < 13) |
+ { |
+ // Stabiles Signal |
+#if defined (RECEIVER_SPEKTRUM_DX7EXP) || defined (RECEIVER_SPEKTRUM_DX8EXP) |
+ if (index == 2) index = 4; // Analog channel reassigment (2 <-> 4) for logical numbering (1,2,3,4) |
+ else if (index == 4) index = 2; |
+#endif |
+ if(abs(signal - PPM_in[index]) < 6) |
+ { |
+ if(EE_Parameter.FailsafeChannel == 0 || PPM_in[EE_Parameter.FailsafeChannel] < 100) // forces Failsafe if the receiver doesn't have 'signal loss' on Failsafe |
+ { |
+ if(SenderOkay < 200) SenderOkay += 10; |
+ else |
+ { |
+ SenderOkay = 200; |
+ TIMSK1 &= ~_BV(ICIE1); // disable PPM-Input |
+ } |
+ } |
+ } |
+ tmp = (3 * (PPM_in[index]) + signal) / 4; |
+ if(tmp > signal+1) tmp--; else |
+ if(tmp < signal-1) tmp++; |
+ |
+#ifdef RECEIVER_SPEKTRUM_DX7EXP |
+ if(index == 6) // FLIGHT-MODE - The channel used for our data uplink |
+ { |
+ if (signal > 100) // SYNC received |
+ { |
+ if (s_exdata[s_excnt] == 125) s_exparity = ~s_exparity; // Bit = 1 -> Re-Invert parity bit |
+ if ((s_excnt == 6 && ((s_exparity != 0 && s_exdata[s_excnt] == -125) || (s_exparity == 0 && s_exdata[s_excnt] == 125))) || (s_excnt == 9 && ((s_exparity == 0 && s_exdata[s_excnt] == -125) || (s_exparity != 0 && s_exdata[s_excnt] == 125)))) // Parity check |
+ { |
+ if (s_exdata[1] == 125 && s_exdata[2] == -125) s_update(5,-125); // Reconstruct tripole Flight-Mode value (CH5) |
+ else if (s_exdata[1] == -125 && s_exdata[2] == -125) s_update(5,0); // Reconstruct tripole Flight-Mode value (CH5) |
+ else if (s_exdata[1] == -125 && s_exdata[2] == 125) s_update(5,125); // Reconstruct tripole Flight-Mode value (CH5) |
+ s_update(6,s_exdata[3]); // Elevator (CH6) |
+ s_update(11,s_exdata[4]); // Aileron (CH11) |
+ s_update(12,s_exdata[5]); // Rudder (CH12) |
+ |
+ if (s_excnt == 9) // New Mode (12 Channels) |
+ { |
+ if (s_exdata[7] == 125) s_update(8,PPM_in[8]+5); // Hover Pitch UP (CH8) |
+ if (s_exdata[8] == 125) s_update(8,PPM_in[8]-5); // Hover Pitch DN (CH8) |
+ if (PPM_in[8] < -125) PPM_in[8] = -125; // Range-Limit |
+ else if (PPM_in[8] > 125) PPM_in[8] = 125; // Range-Limit |
+ s_update(10,s_exdata[6]); // AUX2 (CH10) |
+ } |
+ } |
+ |
+ s_excnt = 0; // Reset bitcounter |
+ s_exparity = 0; // Reset parity bit |
+ } |
+ |
+ if (signal < 10) s_exdata[++s_excnt] = -125; // Bit = 0 -> value = -125 (min) |
+ if (s_excnt == 10) s_excnt = 0; // Overflow protection |
+ if (signal < -100) |
+ { |
+ s_exdata[s_excnt] = 125; // Bit = 1 -> value = 125 (max) |
+ s_exparity = ~s_exparity; // Bit = 1 -> Invert parity bit |
+ } |
+ |
+ } |
+ |
+ if (index < 5 ) s_update(index,tmp); // Update normal potis (CH1-4) |
+ else if (index == 5) s_update(7,signal); // Gear (CH7) |
+ else if (index == 7) s_update(9,signal); // Hover Throttle (CH9) |
+ |
+#elif defined RECEIVER_SPEKTRUM_DX8EXP |
+ if(index == 6) // FLIGHT-MODE - The channel used for our data uplink |
+ { |
+ if (signal > 100) // SYNC received |
+ { |
+ if (s_exdata[s_excnt] == 125) s_exparity = ~s_exparity; // Bit = 1 -> Re-Invert parity bit |
+ if (s_excnt == 9 && ((s_exparity == 0 && s_exdata[s_excnt] == -125) || (s_exparity != 0 && s_exdata[s_excnt] == 125))) // Parity check |
+ { |
+ if (s_exdata[1] == 125 && s_exdata[2] == -125) s_update(5,-125); // Reconstruct tripole Flight-Mode value (CH5) |
+ else if (s_exdata[1] == -125 && s_exdata[2] == -125) s_update(5,0); // Reconstruct tripole Flight-Mode value (CH5) |
+ else if (s_exdata[1] == -125 && s_exdata[2] == 125) s_update(5,125); // Reconstruct tripole Flight-Mode value (CH5) |
+ |
+ if (s_exdata[3] == 125 && s_exdata[6] == -125) s_update(6,125); // Reconstruct tripole Elev D/R value (CH6) |
+ else if (s_exdata[3] == -125 && s_exdata[6] == -125) s_update(6,0); // Reconstruct tripole Elev D/R value (CH6) |
+ else if (s_exdata[3] == -125 && s_exdata[6] == 125) s_update(6,-125); // Reconstruct tripole Elev D/R value (CH6) |
+ |
+ |
+ if (s_exdata[7] == 125 && s_exdata[8] == -125) s_update(9,-125); // Reconstruct tripole AIL D/R value (CH9) |
+ else if (s_exdata[7] == -125 && s_exdata[8] == -125) s_update(9,0); // Reconstruct tripole AIL D/R value (CH9) |
+ else if (s_exdata[7] == -125 && s_exdata[8] == 125) s_update(9,125); // Reconstruct tripole AIL D/R value (CH9) |
+ |
+ s_update(10,s_exdata[5]); // Gear (CH10) |
+ s_update(12,s_exdata[4]); // Mix (CH12) |
+ } |
+ |
+ s_excnt = 0; // Reset bitcounter |
+ s_exparity = 0; // Reset parity bit |
+ } |
+ |
+ if (signal < 10) s_exdata[++s_excnt] = -125; // Bit = 0 -> value = -125 (min) |
+ if (s_excnt == 10) s_excnt = 0; // Overflow protection |
+ if (signal < -100) |
+ { |
+ s_exdata[s_excnt] = 125; // Bit = 1 -> value = 125 (max) |
+ s_exparity = ~s_exparity; // Bit = 1 -> Invert parity bit |
+ } |
+ |
+ } |
+ |
+ if (index < 5 ) s_update(index,tmp); // Update normal potis (CH1-4) |
+ else if (index == 7) s_update(7,signal); // R Trim (CH7) |
+ else if (index == 5) s_update(8,signal); // AUX2 (CH8) |
+ else if (index == 8) s_update(11,signal); // AUX3 (CH11) |
+ |
+#else |
+ if(SenderOkay >= 180) PPM_diff[index] = ((tmp - PPM_in[index]) / 3) * 3; |
+ else PPM_diff[index] = 0; |
+ PPM_in[index] = tmp; |
+#endif |
+ } |
+ else if(index > 17) ReSync = 1; // hier stimmt was nicht: neu synchronisieren |
+ } |
+ else |
+ { |
+ // hier stimmt was nicht: neu synchronisieren |
+ ReSync = 1; |
+ FrameCnt = 0; |
+ Frame2 = 0; |
+ // new frame next, nach fruehestens 7ms erwartet |
+ SpektrumTimer = MIN_FRAMEGAP; |
+ } |
+ |
+ // 16 Bytes eingetroffen -> Komplett |
+ if(FrameCnt >= 16) |
+ { |
+ // Frame complete |
+ if(Frame2 == 0) |
+ { |
+ // Null bedeutet: Neue Daten |
+ // nur beim ersten Frame (CH 0-7) setzen |
+ if(!ReSync) NewPpmData = 0; |
+ } |
+ FrameCnt = 0; |
+ Frame2 = 0; |
+ Sync = 0; |
+ SpektrumTimer = MIN_FRAMEGAP; |
+ } |
+ } |
+} |
+ |
+ |
/tags/V2.12a/Spektrum.h |
---|
0,0 → 1,13 |
/*####################################################################################### |
Dekodieren eines Spektrum Signals |
#######################################################################################*/ |
#ifndef _SPEKTRUM_H |
#define _SPEKTRUM_H |
void SpektrumUartInit(void); |
void SpektrumBinding(void); |
extern unsigned char SpektrumTimer; |
extern void SpektrumParser(unsigned char c); |
void s_update(unsigned char channel, signed int value); // Channel-Diff numbercrunching and finally assign new stickvalue to PPM_in |
#endif //_RC_H |
/tags/V2.12a/analog.c |
---|
0,0 → 1,397 |
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
// + www.MikroKopter.com |
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
// + Software Nutzungsbedingungen (english version: see below) |
// + der Fa. HiSystems GmbH, Flachsmeerstrasse 2, 26802 Moormerland - nachfolgend Lizenzgeber genannt - |
// + Der Lizenzgeber räumt dem Kunden ein nicht-ausschließliches, zeitlich und räumlich* unbeschränktes Recht ein, die im den |
// + Mikrocontroller verwendete Firmware für die Hardware Flight-Ctrl, Navi-Ctrl, BL-Ctrl, MK3Mag & PC-Programm MikroKopter-Tool |
// + - nachfolgend Software genannt - nur für private Zwecke zu nutzen. |
// + Der Einsatz dieser Software ist nur auf oder mit Produkten des Lizenzgebers zulässig. |
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
// + Die vom Lizenzgeber gelieferte Software ist urheberrechtlich geschützt. Alle Rechte an der Software sowie an sonstigen im |
// + Rahmen der Vertragsanbahnung und Vertragsdurchführung überlassenen Unterlagen stehen im Verhältnis der Vertragspartner ausschließlich dem Lizenzgeber zu. |
// + Die in der Software enthaltenen Copyright-Vermerke, Markenzeichen, andere Rechtsvorbehalte, Seriennummern sowie |
// + sonstige der Programmidentifikation dienenden Merkmale dürfen vom Kunden nicht verändert oder unkenntlich gemacht werden. |
// + Der Kunde trifft angemessene Vorkehrungen für den sicheren Einsatz der Software. Er wird die Software gründlich auf deren |
// + Verwendbarkeit zu dem von ihm beabsichtigten Zweck testen, bevor er diese operativ einsetzt. |
// + Die Haftung des Lizenzgebers wird - soweit gesetzlich zulässig - begrenzt in Höhe des typischen und vorhersehbaren |
// + Schadens. Die gesetzliche Haftung bei Personenschäden und nach dem Produkthaftungsgesetz bleibt unberührt. Dem Lizenzgeber steht jedoch der Einwand |
// + des Mitverschuldens offen. |
// + Der Kunde trifft angemessene Vorkehrungen für den Fall, dass die Software ganz oder teilweise nicht ordnungsgemäß arbeitet. |
// + Er wird die Software gründlich auf deren Verwendbarkeit zu dem von ihm beabsichtigten Zweck testen, bevor er diese operativ einsetzt. |
// + Der Kunde wird er seine Daten vor Einsatz der Software nach dem Stand der Technik sichern. |
// + Der Kunde ist darüber unterrichtet, dass der Lizenzgeber seine Daten im zur Vertragsdurchführung erforderlichen Umfang |
// + und auf Grundlage der Datenschutzvorschriften erhebt, speichert, verarbeitet und, sofern notwendig, an Dritte übermittelt. |
// + *) Die räumliche Nutzung bezieht sich nur auf den Einsatzort, nicht auf die Reichweite der programmierten Software. |
// + #### ENDE DER NUTZUNGSBEDINGUNGEN ####' |
// + Hinweis: Informationen über erweiterte Nutzungsrechte (wie z.B. Nutzung für nicht-private Zwecke) sind auf Anfrage per Email an info(@)hisystems.de verfügbar. |
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
// + Software LICENSING TERMS |
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
// + of HiSystems GmbH, Flachsmeerstrasse 2, 26802 Moormerland, Germany - the Licensor - |
// + The Licensor grants the customer a non-exclusive license to use the microcontroller firmware of the Flight-Ctrl, Navi-Ctrl, BL-Ctrl, and MK3Mag hardware |
// + (the Software) exclusively for private purposes. The License is unrestricted with respect to time and territory*. |
// + The Software may only be used with the Licensor's products. |
// + The Software provided by the Licensor is protected by copyright. With respect to the relationship between the parties to this |
// + agreement, all rights pertaining to the Software and other documents provided during the preparation and execution of this |
// + agreement shall be the property of the Licensor. |
// + The information contained in the Software copyright notices, trademarks, other legal reservations, serial numbers and other |
// + features that can be used to identify the program may not be altered or defaced by the customer. |
// + The customer shall be responsible for taking reasonable precautions |
// + for the safe use of the Software. The customer shall test the Software thoroughly regarding its suitability for the |
// + intended purpose before implementing it for actual operation. The Licensor's liability shall be limited to the extent of typical and |
// + foreseeable damage to the extent permitted by law, notwithstanding statutory liability for bodily injury and product |
// + liability. However, the Licensor shall be entitled to the defense of contributory negligence. |
// + The customer will take adequate precautions in the case, that the software is not working properly. The customer will test |
// + the software for his purpose before any operational usage. The customer will backup his data before using the software. |
// + The customer understands that the Licensor collects, stores and processes, and, where required, forwards, customer data |
// + to third parties to the extent necessary for executing the agreement, subject to applicable data protection and privacy regulations. |
// + *) The territory aspect only refers to the place where the Software is used, not its programmed range. |
// + #### END OF LICENSING TERMS #### |
// + Note: For information on license extensions (e.g. commercial use), please contact us at info(@)hisystems.de. |
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
#include "main.h" |
#include "eeprom.h" |
volatile int Aktuell_Nick,Aktuell_Roll,Aktuell_Gier,Aktuell_ax, Aktuell_ay,Aktuell_az, UBat = 150; |
volatile int AdWertNickFilter = 0, AdWertRollFilter = 0, AdWertGierFilter = 0; |
volatile int HiResNick = 2500, HiResRoll = 2500; |
volatile int AdWertNick = 0, AdWertRoll = 0, AdWertGier = 0; |
volatile int AdWertAccRoll = 0,AdWertAccNick = 0,AdWertAccHoch = 0; |
volatile long Luftdruck = 32000; |
volatile long SummenHoehe = 0; |
volatile long StartLuftdruck; |
volatile unsigned int MessLuftdruck = 1023; |
unsigned char DruckOffsetSetting; |
signed char ExpandBaro = 0; |
volatile int VarioMeter = 0; |
volatile unsigned int ZaehlMessungen = 0; |
unsigned char AnalogOffsetNick = 115,AnalogOffsetRoll = 115,AnalogOffsetGier = 115; |
volatile unsigned char AdReady = 1; |
unsigned int BaroStep = 500; |
long ExpandBaroStep = 0; |
long HoehenWertF = 0; |
long HoehenWert_Mess = 0; |
#if (defined(__AVR_ATmega1284__) || defined(__AVR_ATmega1284P__)) |
long HoehenWertF_Mess = 0; |
unsigned char CalAthmospheare = 16; |
unsigned char AD_ACC_Y = 6; |
unsigned char AD_ACC_X = 7; |
#endif |
//####################################################################################### |
void ADC_Init(void) |
//####################################################################################### |
{ |
ADMUX = 0;//Referenz ist extern |
ANALOG_ON; |
} |
#define DESIRED_H_ADC 800 |
void CalcExpandBaroStep(void) |
{ |
if(ACC_AltitudeControl) ExpandBaroStep = BaroStep * (long)ExpandBaro; |
else ExpandBaroStep = (16 * BaroStep) * (long)ExpandBaro - 4; |
} |
void SucheLuftruckOffset(void) |
{ |
unsigned int off; |
ExpandBaro = 0; |
CalcExpandBaroStep(); |
off = GetParamByte(PID_PRESSURE_OFFSET); |
if(off < 240) off += 10; |
OCR0A = off; |
OCR0B = 255-off; |
Delay_ms_Mess(150); |
if(MessLuftdruck > DESIRED_H_ADC) off = 240; |
for(; off > 5; off--) |
{ |
OCR0A = off; |
OCR0B = 255-off; |
Delay_ms_Mess(100); |
printf("."); |
if(MessLuftdruck > DESIRED_H_ADC) break; |
} |
DruckOffsetSetting = off; |
SetParamByte(PID_PRESSURE_OFFSET, off); |
if((EE_Parameter.GlobalConfig & CFG_HOEHENREGELUNG) && (DruckOffsetSetting < 10 || DruckOffsetSetting >= 230)) VersionInfo.HardwareError[0] |= FC_ERROR0_PRESSURE; |
#if (defined(__AVR_ATmega1284__) || defined(__AVR_ATmega1284P__)) |
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
// + correction of the altitude error in higher altitudes |
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
CalAthmospheare = 15; // re-claibrated from 16 to 15 at 2.09 -> the baro-Altimeter was about 7% too high |
if(ACC_AltitudeControl) |
{ |
if(PlatinenVersion < 23) { if(off < 140) CalAthmospheare += (160 - off) / 26; } |
// else { if(off < 170) CalAthmospheare += (188 - off) / 19; } |
else { if(off < 170) CalAthmospheare += (188 - off) / 15; } // rescaled at 2.09 |
} |
Luftdruck = MessLuftdruck * CalAthmospheare; |
#endif |
Delay_ms_Mess(300); |
} |
/* |
void SucheGyroOffset(void) |
{ |
unsigned char i, ready = 0; |
int timeout; |
timeout = SetDelay(2000); |
for(i=140; i != 0; i--) |
{ |
if(ready == 3 && i > 10) i = 9; |
ready = 0; |
if(AdWertNick < 1020) AnalogOffsetNick--; else if(AdWertNick > 1030) AnalogOffsetNick++; else ready++; |
if(AdWertRoll < 1020) AnalogOffsetRoll--; else if(AdWertRoll > 1030) AnalogOffsetRoll++; else ready++; |
if(AdWertGier < 1020) AnalogOffsetGier--; else if(AdWertGier > 1030) AnalogOffsetGier++; else ready++; |
I2C_Start(TWI_STATE_GYRO_OFFSET_TX); |
if(AnalogOffsetNick < 10) { VersionInfo.HardwareError[0] |= FC_ERROR0_GYRO_NICK; AnalogOffsetNick = 10;}; if(AnalogOffsetNick > 245) { VersionInfo.HardwareError[0] |= FC_ERROR0_GYRO_NICK; AnalogOffsetNick = 245;}; |
if(AnalogOffsetRoll < 10) { VersionInfo.HardwareError[0] |= FC_ERROR0_GYRO_ROLL; AnalogOffsetRoll = 10;}; if(AnalogOffsetRoll > 245) { VersionInfo.HardwareError[0] |= FC_ERROR0_GYRO_ROLL; AnalogOffsetRoll = 245;}; |
if(AnalogOffsetGier < 10) { VersionInfo.HardwareError[0] |= FC_ERROR0_GYRO_YAW; AnalogOffsetGier = 10;}; if(AnalogOffsetGier > 245) { VersionInfo.HardwareError[0] |= FC_ERROR0_GYRO_YAW; AnalogOffsetGier = 245;}; |
while(twi_state) if(CheckDelay(timeout)) {printf("\n\r DAC or I2C ERROR! Check I2C, 3Vref, DAC and BL-Ctrl"); break;} |
AdReady = 0; |
ANALOG_ON; |
while(!AdReady); |
if(i<10) Delay_ms_Mess(10); |
} |
Delay_ms_Mess(70); |
} |
*/ |
/* |
0 n |
1 r |
2 g |
3 y |
4 x |
5 n |
6 r |
7 u |
8 z |
9 L |
10 n |
11 r |
12 g |
13 y |
14 x |
15 n |
16 r |
17 L |
*/ |
//####################################################################################### |
// |
ISR(ADC_vect) |
//####################################################################################### |
{ |
static unsigned char kanal=0,state = 0; |
static signed int subcount = 0; |
static signed int gier1, roll1, nick1, nick_filter, roll_filter; |
static signed int accy, accx; |
static long tmpLuftdruck = 0; |
static char messanzahl_Druck = 0; |
switch(state++) |
{ |
case 0: |
nick1 = ADC; |
kanal = AD_ROLL; |
break; |
case 1: |
roll1 = ADC; |
kanal = AD_GIER; |
break; |
case 2: |
gier1 = ADC; |
kanal = AD_ACC_Y; |
break; |
case 3: |
Aktuell_ay = NeutralAccY - ADC; |
accy = Aktuell_ay; |
kanal = AD_ACC_X; |
break; |
case 4: |
Aktuell_ax = ADC - NeutralAccX; |
accx = Aktuell_ax; |
kanal = AD_NICK; |
break; |
case 5: |
nick1 += ADC; |
kanal = AD_ROLL; |
break; |
case 6: |
roll1 += ADC; |
kanal = AD_UBAT; |
break; |
case 7: |
#if (defined(__AVR_ATmega1284__) || defined(__AVR_ATmega1284P__)) |
if(EE_Parameter.ExtraConfig & CFG_3_3V_REFERENCE) UBat = (3 * UBat + (11 * ADC) / 30) / 4; // there were some single FC2.1 with 3.3V reference |
else |
#endif |
{ |
static unsigned int tmpVoltage = 0; |
if(!tmpVoltage) tmpVoltage = (10 * ADC); |
if(tmpVoltage <= (10 * ADC)) tmpVoltage += 2; else tmpVoltage -= 2; |
UBat = tmpVoltage / 31; |
} |
kanal = AD_ACC_Z; |
break; |
case 8: |
Aktuell_az = ADC; |
AdWertAccHoch = Aktuell_az - NeutralAccZ - (int) NeutralAccZfine; |
if(!ACC_AltitudeControl) // The Offset must be corrected, because of the ACC-Drift from vibrations |
{ |
if(AdWertAccHoch > 1) |
{ |
if(NeutralAccZ < 750) |
{ |
subcount += 5; |
if(modell_fliegt < 500) subcount += 10; |
if(subcount > 100) { NeutralAccZ++; subcount -= 100;} |
} |
} |
else if(AdWertAccHoch < -1) |
{ |
if(NeutralAccZ > 550) |
{ |
subcount -= 5; |
if(modell_fliegt < 500) subcount -= 10; |
if(subcount < -100) { NeutralAccZ--; subcount += 100;} |
} |
} |
} |
#if (defined(__AVR_ATmega1284__) || defined(__AVR_ATmega1284P__)) |
else |
if(CosAttitude > 8192 - 50) // horizontal leveled within 6° |
{ |
if(AdWertAccHoch > 1) |
{ |
if(++subcount > 5000) |
{ |
if(NeutralAccZfine < 6) NeutralAccZfine++; |
subcount -= 5000; |
} |
} |
else |
if(AdWertAccHoch < -1) |
{ |
if(--subcount < -5000) |
{ |
if(NeutralAccZfine > -6) NeutralAccZfine--; |
subcount += 5000; |
} |
} |
} |
#endif |
Mess_Integral_Hoch += AdWertAccHoch; // Integrieren |
Mess_Integral_Hoch -= Mess_Integral_Hoch / 1024; // dämfen |
kanal = AD_DRUCK; |
break; |
// "case 9:" fehlt hier absichtlich |
case 10: |
nick1 += ADC; |
kanal = AD_ROLL; |
break; |
case 11: |
roll1 += ADC; |
kanal = AD_GIER; |
break; |
case 12: |
/* if(PlatinenVersion == 10) AdWertGier = (ADC + gier1 + 1) / 2; |
else |
if(PlatinenVersion >= 20) AdWertGier = 2047 - (ADC + gier1); |
else AdWertGier = (ADC + gier1); |
*/ |
AdWertGier = 2047 - (ADC + gier1); |
kanal = AD_ACC_Y; |
break; |
case 13: |
Aktuell_ay = NeutralAccY - ADC; |
AdWertAccRoll = (Aktuell_ay + accy); |
kanal = AD_ACC_X; |
break; |
case 14: |
Aktuell_ax = ADC - NeutralAccX; |
AdWertAccNick = (Aktuell_ax + accx); |
kanal = AD_NICK; |
break; |
case 15: |
nick1 += ADC; |
//if(PlatinenVersion == 10) nick1 *= 2; else |
nick1 *= 4; |
AdWertNick = nick1 / 8; |
nick_filter = (nick_filter + nick1) / 2; |
HiResNick = nick_filter - AdNeutralNick; |
AdWertNickFilter = (AdWertNickFilter + HiResNick) / 2; |
kanal = AD_ROLL; |
break; |
case 16: |
roll1 += ADC; |
//if(PlatinenVersion == 10) roll1 *= 2; else |
roll1 *= 4; |
AdWertRoll = roll1 / 8; |
roll_filter = (roll_filter + roll1) / 2; |
HiResRoll = roll_filter - AdNeutralRoll; |
AdWertRollFilter = (AdWertRollFilter + HiResRoll) / 2; |
kanal = AD_DRUCK; |
break; |
case 17: |
#if (defined(__AVR_ATmega1284__) || defined(__AVR_ATmega1284P__)) |
if(ACC_AltitudeControl) |
{ |
HoehenWertF_Mess = (ACC_AltitudeFusion(0) + SA_FILTER/2)/SA_FILTER; // cm |
} |
else HoehenWertF_Mess = HoehenWert; |
#endif |
state = 0; |
AdReady = 1; |
ZaehlMessungen++; |
// "break" fehlt hier absichtlich |
case 9: |
MessLuftdruck = ADC; |
#if (defined(__AVR_ATmega1284__) || defined(__AVR_ATmega1284P__)) |
if(ACC_AltitudeControl) |
{ |
tmpLuftdruck = MessLuftdruck - ExpandBaroStep; // -523 counts per offset step |
if(BaroExpandActive) |
{ |
if(BaroExpandActive < 10) Luftdruck = tmpLuftdruck * CalAthmospheare; |
} |
else |
{ |
Luftdruck -= Luftdruck / CalAthmospheare; // 16 |
Luftdruck += tmpLuftdruck; |
HoehenWert_Mess = StartLuftdruck - Luftdruck; // cm |
} |
} |
else |
#endif |
{ // old version (until FC V2.1) |
tmpLuftdruck += MessLuftdruck; |
if(++messanzahl_Druck >= 16) // war bis 0.86 "18" |
{ |
signed int tmp; |
Luftdruck = (7 * Luftdruck + tmpLuftdruck - ExpandBaroStep) / 8; // -523.19 counts per 10 counts offset step |
HoehenWert_Mess = StartLuftdruck - Luftdruck; |
SummenHoehe -= SummenHoehe/SM_FILTER; |
SummenHoehe += HoehenWert_Mess; |
tmp = (HoehenWert_Mess - SummenHoehe/SM_FILTER); |
if(tmp > 1024) tmp = 1024; else if(tmp < -1024) tmp = -1024; |
if(abs(VarioMeter) > 700) VarioMeter = (15 * VarioMeter + 8 * tmp)/16; |
else VarioMeter = (31 * VarioMeter + 8 * tmp)/32; |
tmpLuftdruck /= 2; |
messanzahl_Druck = 16/2; |
} |
} |
kanal = AD_NICK; |
break; |
default: |
kanal = 0; state = 0; kanal = AD_NICK; |
break; |
} |
ADMUX = kanal; |
if(state != 0) ANALOG_ON; |
} |
/tags/V2.12a/analog.h |
---|
0,0 → 1,60 |
#ifndef _ANALOG_H |
#define _ANALOG_H |
/*####################################################################################### |
#######################################################################################*/ |
#define SM_FILTER 16 |
#define SA_FILTER 512 |
extern volatile int UBat; |
extern volatile int AdWertNick, AdWertRoll, AdWertGier; |
extern volatile int AdWertAccRoll,AdWertAccNick,AdWertAccHoch; |
extern volatile int HiResNick, HiResRoll; |
extern volatile int AdWertNickFilter, AdWertRollFilter, AdWertGierFilter; |
extern volatile int Aktuell_Nick,Aktuell_Roll,Aktuell_Gier,Aktuell_ax, Aktuell_ay,Aktuell_az; |
extern volatile long Luftdruck; |
extern volatile long SummenHoehe; |
extern volatile char messanzahl_Druck; |
extern volatile unsigned int ZaehlMessungen; |
extern unsigned char DruckOffsetSetting; |
extern signed char ExpandBaro; |
extern volatile int VarioMeter; |
extern volatile unsigned int MessLuftdruck; |
extern volatile long StartLuftdruck; |
extern volatile char MessanzahlNick; |
extern unsigned char AnalogOffsetNick,AnalogOffsetRoll,AnalogOffsetGier; |
extern volatile unsigned char AdReady; |
extern unsigned int BaroStep; |
extern long HoehenWertF; |
extern long HoehenWert_Mess; |
extern long HoehenWertF_Mess; |
unsigned int ReadADC(unsigned char adc_input); |
void ADC_Init(void); |
void SucheLuftruckOffset(void); |
//void SucheGyroOffset(void); |
void CalcExpandBaroStep(void); |
#if (defined(__AVR_ATmega1284__) || defined(__AVR_ATmega1284P__)) |
extern unsigned char CalAthmospheare; |
#endif |
#define AD_GIER 0 |
#define AD_ROLL 1 |
#define AD_NICK 2 |
#define AD_DRUCK 3 |
#define AD_UBAT 4 |
#define AD_ACC_Z 5 |
#if (defined(__AVR_ATmega1284__) || defined(__AVR_ATmega1284P__)) |
extern unsigned char AD_ACC_Y; |
extern unsigned char AD_ACC_X; |
#else |
#define AD_ACC_Y 6 |
#define AD_ACC_X 7 |
#endif |
#define ANALOG_OFF ADCSRA=0 |
#define ANALOG_ON ADCSRA=(1<<ADEN)|(1<<ADSC)|(0<<ADATE)|(1<<ADPS2)|(1<<ADPS1)|(1<<ADPS0)|(1<<ADIE) |
//Signle trigger Mode, Interrupt on |
#endif //_ANALOG_H |
/tags/V2.12a/capacity.c |
---|
0,0 → 1,167 |
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
// + www.MikroKopter.com |
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
// + Software Nutzungsbedingungen (english version: see below) |
// + der Fa. HiSystems GmbH, Flachsmeerstrasse 2, 26802 Moormerland - nachfolgend Lizenzgeber genannt - |
// + Der Lizenzgeber räumt dem Kunden ein nicht-ausschließliches, zeitlich und räumlich* unbeschränktes Recht ein, die im den |
// + Mikrocontroller verwendete Firmware für die Hardware Flight-Ctrl, Navi-Ctrl, BL-Ctrl, MK3Mag & PC-Programm MikroKopter-Tool |
// + - nachfolgend Software genannt - nur für private Zwecke zu nutzen. |
// + Der Einsatz dieser Software ist nur auf oder mit Produkten des Lizenzgebers zulässig. |
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
// + Die vom Lizenzgeber gelieferte Software ist urheberrechtlich geschützt. Alle Rechte an der Software sowie an sonstigen im |
// + Rahmen der Vertragsanbahnung und Vertragsdurchführung überlassenen Unterlagen stehen im Verhältnis der Vertragspartner ausschließlich dem Lizenzgeber zu. |
// + Die in der Software enthaltenen Copyright-Vermerke, Markenzeichen, andere Rechtsvorbehalte, Seriennummern sowie |
// + sonstige der Programmidentifikation dienenden Merkmale dürfen vom Kunden nicht verändert oder unkenntlich gemacht werden. |
// + Der Kunde trifft angemessene Vorkehrungen für den sicheren Einsatz der Software. Er wird die Software gründlich auf deren |
// + Verwendbarkeit zu dem von ihm beabsichtigten Zweck testen, bevor er diese operativ einsetzt. |
// + Die Haftung des Lizenzgebers wird - soweit gesetzlich zulässig - begrenzt in Höhe des typischen und vorhersehbaren |
// + Schadens. Die gesetzliche Haftung bei Personenschäden und nach dem Produkthaftungsgesetz bleibt unberührt. Dem Lizenzgeber steht jedoch der Einwand |
// + des Mitverschuldens offen. |
// + Der Kunde trifft angemessene Vorkehrungen für den Fall, dass die Software ganz oder teilweise nicht ordnungsgemäß arbeitet. |
// + Er wird die Software gründlich auf deren Verwendbarkeit zu dem von ihm beabsichtigten Zweck testen, bevor er diese operativ einsetzt. |
// + Der Kunde wird er seine Daten vor Einsatz der Software nach dem Stand der Technik sichern. |
// + Der Kunde ist darüber unterrichtet, dass der Lizenzgeber seine Daten im zur Vertragsdurchführung erforderlichen Umfang |
// + und auf Grundlage der Datenschutzvorschriften erhebt, speichert, verarbeitet und, sofern notwendig, an Dritte übermittelt. |
// + *) Die räumliche Nutzung bezieht sich nur auf den Einsatzort, nicht auf die Reichweite der programmierten Software. |
// + #### ENDE DER NUTZUNGSBEDINGUNGEN ####' |
// + Hinweis: Informationen über erweiterte Nutzungsrechte (wie z.B. Nutzung für nicht-private Zwecke) sind auf Anfrage per Email an info(@)hisystems.de verfügbar. |
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
// + Software LICENSING TERMS |
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
// + of HiSystems GmbH, Flachsmeerstrasse 2, 26802 Moormerland, Germany - the Licensor - |
// + The Licensor grants the customer a non-exclusive license to use the microcontroller firmware of the Flight-Ctrl, Navi-Ctrl, BL-Ctrl, and MK3Mag hardware |
// + (the Software) exclusively for private purposes. The License is unrestricted with respect to time and territory*. |
// + The Software may only be used with the Licensor's products. |
// + The Software provided by the Licensor is protected by copyright. With respect to the relationship between the parties to this |
// + agreement, all rights pertaining to the Software and other documents provided during the preparation and execution of this |
// + agreement shall be the property of the Licensor. |
// + The information contained in the Software copyright notices, trademarks, other legal reservations, serial numbers and other |
// + features that can be used to identify the program may not be altered or defaced by the customer. |
// + The customer shall be responsible for taking reasonable precautions |
// + for the safe use of the Software. The customer shall test the Software thoroughly regarding its suitability for the |
// + intended purpose before implementing it for actual operation. The Licensor's liability shall be limited to the extent of typical and |
// + foreseeable damage to the extent permitted by law, notwithstanding statutory liability for bodily injury and product |
// + liability. However, the Licensor shall be entitled to the defense of contributory negligence. |
// + The customer will take adequate precautions in the case, that the software is not working properly. The customer will test |
// + the software for his purpose before any operational usage. The customer will backup his data before using the software. |
// + The customer understands that the Licensor collects, stores and processes, and, where required, forwards, customer data |
// + to third parties to the extent necessary for executing the agreement, subject to applicable data protection and privacy regulations. |
// + *) The territory aspect only refers to the place where the Software is used, not its programmed range. |
// + #### END OF LICENSING TERMS #### |
// + Note: For information on license extensions (e.g. commercial use), please contact us at info(@)hisystems.de. |
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
#include "capacity.h" |
#include "twimaster.h" |
#include "main.h" |
#include "timer0.h" |
#include "analog.h" |
//#define CAPACITY_UPDATE_INTERVAL 10 // 10 ms |
#define CAPACITY_UPDATE_INTERVAL 50 // 50 ms = 20Hz |
#define FC_OFFSET_CURRENT 5 // calculate with a current of 0.5A |
#define BL_OFFSET_CURRENT 2 // calculate with a current of 0.2A |
// global varialbles |
unsigned short update_timer = 0; |
Capacity_t Capacity; |
// initialize capacity calculation |
void Capacity_Init(void) |
{ |
Capacity.ActualCurrent = 0; |
Capacity.UsedCapacity = 0; |
Capacity.ActualPower = 0; |
Capacity.MinOfMaxPWM = 0; |
update_timer = SetDelay(CAPACITY_UPDATE_INTERVAL); |
} |
// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
// + extended Current measurement -> 200 = 20A 201 = 21A 255 = 75A (20+55) |
// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
unsigned int BL3_Current(unsigned char who) // in 0,1A |
{ |
if(Motor[who].Current == 255) return(0); // invalid |
if(Motor[who].Current <= 200) return(Motor[who].Current); |
else |
{ |
if(Motor[who].Version & MOTOR_STATE_BL30) return(200 + 10 * ((unsigned int)Motor[who].Current-200)); |
else return(Motor[who].Current); |
} |
} |
// called in main loop at a regular interval |
void Capacity_Update(void) |
{ |
unsigned short Current, SetSum; // max value will be 255 * 12 = 3060 |
static unsigned short SubCounter = 0; |
static unsigned short CurrentOffset = 0; |
static unsigned long SumCurrentOffset = 0; |
unsigned char i, NumOfMotors, MinOfMaxPWM; |
if(CheckDelay(update_timer)) |
{ |
update_timer += CAPACITY_UPDATE_INTERVAL; // do not use SetDelay to avoid timing leaks |
// determine sum of all present BL currents and setpoints |
Current = 0; |
SetSum = 0; |
NumOfMotors = 0; |
MinOfMaxPWM = 255; |
if(Capacity.MinOfMaxPWM == 254) FC_StatusFlags3 |= FC_STATUS3_REDUNDANCE_AKTIVE; |
// else if(Capacity.MinOfMaxPWM == 255) FC_StatusFlags3 &= ~FC_STATUS3_REDUNDANCE_AKTIVE; |
for(i = 0; i < MAX_MOTORS; i++) |
{ |
if(Motor[i].State & MOTOR_STATE_PRESENT_MASK/* && Mixer.Motor[i][MIX_GAS]*/) |
{ |
NumOfMotors++; |
if(Motor[i].Current > 200) |
{ |
Current += BL3_Current(i); // extended Current measurement -> 200 = 20A 201 = 21A 255 = 75A (20+55) |
} |
else Current += (unsigned int)(Motor[i].Current); |
SetSum += (unsigned int)(Motor[i].SetPoint); |
if(Motor[i].MaxPWM <= MinOfMaxPWM) MinOfMaxPWM = Motor[i].MaxPWM; |
else |
if(Motor[i].MaxPWM == 255) FC_StatusFlags3 &= ~FC_STATUS3_REDUNDANCE_AKTIVE; |
} |
} |
Capacity.MinOfMaxPWM = MinOfMaxPWM; |
if(SetSum == 0) // if all setpoints are 0 |
{ // determine offsets of motor currents |
#define CURRENT_AVERAGE 8 // 8bit = 256 * 10 ms = 2.56s average time |
CurrentOffset = (unsigned int)(SumCurrentOffset>>CURRENT_AVERAGE); |
SumCurrentOffset -= CurrentOffset; |
SumCurrentOffset += Current; |
// after averaging set current to static offset |
Current = FC_OFFSET_CURRENT; |
FC_StatusFlags3 &= ~FC_STATUS3_REDUNDANCE_AKTIVE; |
} |
else // some motors are running, includes also motor test condition, where "MotorRunning" is false |
{ // subtract offset |
if(Current > CurrentOffset) Current -= CurrentOffset; |
else Current = 0; |
// add the FC and BL Offsets |
Current += FC_OFFSET_CURRENT + NumOfMotors * BL_OFFSET_CURRENT; |
} |
// update actual Current |
Capacity.ActualCurrent = Current; |
// update actual Power |
if(Current < 255) Capacity.ActualPower = (UBat * Current) / 100; // in W higher resolution |
else Capacity.ActualPower = (UBat * (Current/4)) / 25; // in W |
// update used capacity |
SubCounter += Current; |
// 100mA * 1ms * CAPACITY_UPDATE_INTERVAL = 1 mA * 100 ms * CAPACITY_UPDATE_INTERVAL |
// = 1mA * 0.1s * CAPACITY_UPDATE_INTERVAL = 1mA * 1min / (600 / CAPACITY_UPDATE_INTERVAL) |
// = 1mAh / (36000 / CAPACITY_UPDATE_INTERVAL) |
#define SUB_COUNTER_LIMIT (36000 / CAPACITY_UPDATE_INTERVAL) |
while(SubCounter > SUB_COUNTER_LIMIT) |
{ |
Capacity.UsedCapacity++; // we have one mAh more |
SubCounter -= SUB_COUNTER_LIMIT; // keep the remaining sub part |
} |
} // EOF check delay update timer |
} |
/tags/V2.12a/capacity.h |
---|
0,0 → 1,18 |
#ifndef _CAPACITY_H |
#define _CAPACITY_H |
typedef struct |
{ |
unsigned short ActualCurrent; // in 0.1A Steps |
unsigned short ActualPower; // in 0.1W |
unsigned short UsedCapacity; // in mAh |
unsigned char MinOfMaxPWM; // BL Power Limit |
} __attribute__((packed)) Capacity_t; |
extern Capacity_t Capacity; |
void Capacity_Init(void); |
void Capacity_Update(void); |
#endif //_CAPACITY_H |
/tags/V2.12a/debug.c |
---|
0,0 → 1,48 |
#include "main.h" |
#include "debug.h" |
#ifdef DEBUG // only include functions if DEBUG is defined in main.h |
#warning : "### DEBUG-Funktion aktiv ###" |
unsigned char Debug_BufPtr = 0; |
struct str_Debug tDebug; |
unsigned char SendDebugOutput = 0; |
// function called from _printf_P to output character |
void Debug_Putchar(char c) |
{ |
if (!SendDebugOutput) |
{ |
tDebug.Text[Debug_BufPtr++] = c; // copy character to buffer |
if (Debug_BufPtr > 30) Debug_BufPtr = 30; // avoid buffer overflow |
} |
} |
void DebugSend(unsigned char cmd) |
{ |
if (!SendDebugOutput) |
{ |
tDebug.Cmd = cmd; |
tDebug.Text[Debug_BufPtr] = '\0'; // end of text marker |
Debug_BufPtr = 0; // set bufferindex to 0 |
SendDebugOutput = 1; // set flag to trasmit data the next time in serial transmit function |
} |
} |
#endif |
/* |
add the following code block to the serial transmit function |
#ifdef DEBUG // only include functions if DEBUG is defined |
if(SendDebugOutput && UebertragungAbgeschlossen) |
{ |
SendOutData('0', FC_ADDRESS, 1, (unsigned char *) &tDebug, sizeof(tDebug)); |
SendDebugOutput = 0; |
} |
#endif |
*/ |
/tags/V2.12a/debug.h |
---|
0,0 → 1,60 |
#ifndef _DEBUG_H |
#define _DEBUG_H |
// ---------------------------------------------- |
#define CMD_NONE 0x00 |
#define CMD_RAW_OUTPUT 0x01 |
#define CMD_ERROR_MSG 0x02 |
#define CMD_WARNING_MSG 0x04 |
#define CMD_GREEN_MSG 0x08 |
// debug console in MK-Tool can also handle ANSI ESC seq. |
#define ANSI_ATTRIBUTE_OFF "\033[0m" |
#define ANSI_BOLD "\033[1m" |
#define ANSI_UNDERSCORE "\033[4m" |
#define ANSI_BLINK "\033[5m" |
#define ANSI_INVERSE "\033[7m" |
#define ANSI_INVISIBLE "\033[8m" |
#define ANSI_COLOR_BLACK "\033[30m" |
#define ANSI_COLOR_RED "\033[31m" |
#define ANSI_COLOR_GREEN "\033[32m" |
#define ANSI_COLOR_YELLOW "\033[33m" |
#define ANSI_COLOR_BLUE "\033[34m" |
#define ANSI_COLOR_VIOLETT "\033[35m" |
#define ANSI_COLOR_KOBALTBLUE "\033[36m" |
#define ANSI_COLOR_WHITE "\033[37m" |
#define ANSI_CLEAR "\033[2J" |
#define ANSI_HOME "\033[H" |
// macros for easier use |
#ifdef DEBUG // only include functions if DEBUG is defined in main.h |
#define Debug(format, args...) { _printf_P(&Debug_Putchar, PSTR(format) , ## args); DebugSend(CMD_NONE); } |
#define Debug_Raw(format, args...) { _printf_P(&Debug_Putchar, PSTR(format) , ## args); DebugSend(CMD_RAW_OUTPUT); } |
#define Debug_Warning(format, args...) { _printf_P(&Debug_Putchar, PSTR(format) , ## args); DebugSend(CMD_WARNING_MSG); } |
#define Debug_Error(format, args...) { _printf_P(&Debug_Putchar, PSTR(format) , ## args); DebugSend(CMD_ERROR_MSG); } |
#define Debug_OK(format, args...) { _printf_P(&Debug_Putchar, PSTR(format) , ## args); DebugSend(CMD_GREEN_MSG); } |
struct str_Debug |
{ |
unsigned char Cmd; // bitcoded command |
char Text[32]; |
}; |
extern struct str_Debug tDebug; |
unsigned char SendDebugOutput; |
void Debug_Putchar(char c); |
void DebugSend(unsigned char cmd); |
#else // dummy macros (won't waste flash, if #DEBUG is disabled) |
#define Debug(format, args...) ; |
#define Debug_Raw(format, args...) ; |
#define Debug_Warning(format, args...) ; |
#define Debug_Error(format, args...) ; |
#define Debug_OK(format, args...) ; |
#endif |
// ---------------------------------------------- |
#endif |
/tags/V2.12a/eeprom.c |
---|
0,0 → 1,686 |
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
// + www.MikroKopter.com |
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
// + Software Nutzungsbedingungen (english version: see below) |
// + der Fa. HiSystems GmbH, Flachsmeerstrasse 2, 26802 Moormerland - nachfolgend Lizenzgeber genannt - |
// + Der Lizenzgeber räumt dem Kunden ein nicht-ausschließliches, zeitlich und räumlich* unbeschränktes Recht ein, die im den |
// + Mikrocontroller verwendete Firmware für die Hardware Flight-Ctrl, Navi-Ctrl, BL-Ctrl, MK3Mag & PC-Programm MikroKopter-Tool |
// + - nachfolgend Software genannt - nur für private Zwecke zu nutzen. |
// + Der Einsatz dieser Software ist nur auf oder mit Produkten des Lizenzgebers zulässig. |
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
// + Die vom Lizenzgeber gelieferte Software ist urheberrechtlich geschützt. Alle Rechte an der Software sowie an sonstigen im |
// + Rahmen der Vertragsanbahnung und Vertragsdurchführung überlassenen Unterlagen stehen im Verhältnis der Vertragspartner ausschließlich dem Lizenzgeber zu. |
// + Die in der Software enthaltenen Copyright-Vermerke, Markenzeichen, andere Rechtsvorbehalte, Seriennummern sowie |
// + sonstige der Programmidentifikation dienenden Merkmale dürfen vom Kunden nicht verändert oder unkenntlich gemacht werden. |
// + Der Kunde trifft angemessene Vorkehrungen für den sicheren Einsatz der Software. Er wird die Software gründlich auf deren |
// + Verwendbarkeit zu dem von ihm beabsichtigten Zweck testen, bevor er diese operativ einsetzt. |
// + Die Haftung des Lizenzgebers wird - soweit gesetzlich zulässig - begrenzt in Höhe des typischen und vorhersehbaren |
// + Schadens. Die gesetzliche Haftung bei Personenschäden und nach dem Produkthaftungsgesetz bleibt unberührt. Dem Lizenzgeber steht jedoch der Einwand |
// + des Mitverschuldens offen. |
// + Der Kunde trifft angemessene Vorkehrungen für den Fall, dass die Software ganz oder teilweise nicht ordnungsgemäß arbeitet. |
// + Er wird die Software gründlich auf deren Verwendbarkeit zu dem von ihm beabsichtigten Zweck testen, bevor er diese operativ einsetzt. |
// + Der Kunde wird er seine Daten vor Einsatz der Software nach dem Stand der Technik sichern. |
// + Der Kunde ist darüber unterrichtet, dass der Lizenzgeber seine Daten im zur Vertragsdurchführung erforderlichen Umfang |
// + und auf Grundlage der Datenschutzvorschriften erhebt, speichert, verarbeitet und, sofern notwendig, an Dritte übermittelt. |
// + *) Die räumliche Nutzung bezieht sich nur auf den Einsatzort, nicht auf die Reichweite der programmierten Software. |
// + #### ENDE DER NUTZUNGSBEDINGUNGEN ####' |
// + Hinweis: Informationen über erweiterte Nutzungsrechte (wie z.B. Nutzung für nicht-private Zwecke) sind auf Anfrage per Email an info(@)hisystems.de verfügbar. |
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
// + Software LICENSING TERMS |
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
// + of HiSystems GmbH, Flachsmeerstrasse 2, 26802 Moormerland, Germany - the Licensor - |
// + The Licensor grants the customer a non-exclusive license to use the microcontroller firmware of the Flight-Ctrl, Navi-Ctrl, BL-Ctrl, and MK3Mag hardware |
// + (the Software) exclusively for private purposes. The License is unrestricted with respect to time and territory*. |
// + The Software may only be used with the Licensor's products. |
// + The Software provided by the Licensor is protected by copyright. With respect to the relationship between the parties to this |
// + agreement, all rights pertaining to the Software and other documents provided during the preparation and execution of this |
// + agreement shall be the property of the Licensor. |
// + The information contained in the Software copyright notices, trademarks, other legal reservations, serial numbers and other |
// + features that can be used to identify the program may not be altered or defaced by the customer. |
// + The customer shall be responsible for taking reasonable precautions |
// + for the safe use of the Software. The customer shall test the Software thoroughly regarding its suitability for the |
// + intended purpose before implementing it for actual operation. The Licensor's liability shall be limited to the extent of typical and |
// + foreseeable damage to the extent permitted by law, notwithstanding statutory liability for bodily injury and product |
// + liability. However, the Licensor shall be entitled to the defense of contributory negligence. |
// + The customer will take adequate precautions in the case, that the software is not working properly. The customer will test |
// + the software for his purpose before any operational usage. The customer will backup his data before using the software. |
// + The customer understands that the Licensor collects, stores and processes, and, where required, forwards, customer data |
// + to third parties to the extent necessary for executing the agreement, subject to applicable data protection and privacy regulations. |
// + *) The territory aspect only refers to the place where the Software is used, not its programmed range. |
// + #### END OF LICENSING TERMS #### |
// + Note: For information on license extensions (e.g. commercial use), please contact us at info(@)hisystems.de. |
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
#ifndef EEMEM |
#define EEMEM __attribute__ ((section (".eeprom"))) |
#endif |
#include <avr/eeprom.h> |
#include <string.h> |
#include "eeprom.h" |
#include "uart.h" |
#include "led.h" |
#include "main.h" |
#include "fc.h" |
#include "twimaster.h" |
paramset_t EE_Parameter; |
MixerTable_t Mixer; |
uint8_t RequiredMotors; |
uint8_t RAM_Checksum(uint8_t* pBuffer, uint16_t len) |
{ |
uint8_t crc = 0xAA; |
uint16_t i; |
for(i=0; i<len; i++) |
{ |
crc += pBuffer[i]; |
} |
return crc; |
} |
uint8_t EEProm_Checksum(uint16_t EEAddr, uint16_t len) |
{ |
uint8_t crc = 0xAA; |
uint16_t off; |
for(off=0; off<len; off++) |
{ |
crc += eeprom_read_byte((uint8_t*)(EEAddr + off));; |
} |
return crc; |
} |
void ParamSet_DefaultStickMapping(void) |
{ |
EE_Parameter.Kanalbelegung[K_GAS] = 1; |
EE_Parameter.Kanalbelegung[K_ROLL] = 2; |
EE_Parameter.Kanalbelegung[K_NICK] = 3; |
EE_Parameter.Kanalbelegung[K_GIER] = 4; |
EE_Parameter.Kanalbelegung[K_POTI1] = 5; |
EE_Parameter.Kanalbelegung[K_POTI2] = 6; |
EE_Parameter.Kanalbelegung[K_POTI3] = 7; |
EE_Parameter.Kanalbelegung[K_POTI4] = 8; |
EE_Parameter.Kanalbelegung[K_POTI5] = 9; |
EE_Parameter.Kanalbelegung[K_POTI6] = 10; |
EE_Parameter.Kanalbelegung[K_POTI7] = 11; |
EE_Parameter.Kanalbelegung[K_POTI8] = 12; |
} |
/***************************************************/ |
/* Default Values for parameter set 1 */ |
/***************************************************/ |
void CommonDefaults(void) |
{ |
EE_Parameter.Revision = EEPARAM_REVISION; |
memset(EE_Parameter.Name,0,12); // delete name |
// if(PlatinenVersion >= 20) |
{ |
EE_Parameter.Gyro_D = 10; |
EE_Parameter.Driftkomp = 0; |
EE_Parameter.GyroAccFaktor = 27; |
EE_Parameter.WinkelUmschlagNick = 78; |
EE_Parameter.WinkelUmschlagRoll = 78; |
} |
/* else |
{ |
EE_Parameter.Gyro_D = 3; |
EE_Parameter.Driftkomp = 32; |
EE_Parameter.GyroAccFaktor = 30; |
EE_Parameter.WinkelUmschlagNick = 85; |
EE_Parameter.WinkelUmschlagRoll = 85; |
} |
*/ |
EE_Parameter.GyroAccAbgleich = 32; // 1/k |
EE_Parameter.BitConfig = 0; // Looping usw. |
EE_Parameter.GlobalConfig = CFG_ACHSENKOPPLUNG_AKTIV | CFG_KOMPASS_AKTIV | CFG_GPS_AKTIV | CFG_HOEHEN_SCHALTER; |
EE_Parameter.ExtraConfig = CFG_GPS_AID | CFG2_VARIO_BEEP | CFG_LEARNABLE_CAREFREE | CFG_NO_RCOFF_BEEPING; |
EE_Parameter.GlobalConfig3 = CFG3_SPEAK_ALL | CFG3_NO_GPSFIX_NO_START;// |
#if (defined(__AVR_ATmega1284__) || defined(__AVR_ATmega1284P__)) |
EE_Parameter.Receiver = RECEIVER_HOTT; |
#else |
EE_Parameter.Receiver = RECEIVER_JETI; |
#endif |
EE_Parameter.MotorSafetySwitch = 0; |
EE_Parameter.ExternalControl = 0; |
EE_Parameter.Gas_Min = 8; // Wert : 0-32 |
EE_Parameter.Gas_Max = 230; // Wert : 33-247 |
EE_Parameter.KompassWirkung = 64; // Wert : 0-247 |
EE_Parameter.HoeheChannel = 5; // Wert : 0-32 |
EE_Parameter.Hoehe_MinGas = 30; |
EE_Parameter.Hoehe_TiltCompensation = 110; // in % |
#if (defined(__AVR_ATmega1284__) || defined(__AVR_ATmega1284P__)) |
if(ACC_AltitudeControl) |
{ |
EE_Parameter.Hoehe_P = 20; // Wert : 0-32 |
EE_Parameter.Luftdruck_D = 40; // Wert : 0-247 |
EE_Parameter.Hoehe_ACC_Wirkung = 30; // Wert : 0-247 |
EE_Parameter.Hoehe_HoverBand = 1; // Wert : 0-247 |
EE_Parameter.Hoehe_StickNeutralPoint = 127;// Wert : 0-247 (0 = Hover-Estimation) |
EE_Parameter.FailSafeTime = 60; // 0 = off |
} |
else |
#endif |
{ |
EE_Parameter.Hoehe_P = 15; // Wert : 0-32 |
EE_Parameter.Luftdruck_D = 30; // Wert : 0-247 |
EE_Parameter.Hoehe_ACC_Wirkung = 0; // Wert : 0-247 |
EE_Parameter.Hoehe_HoverBand = 8; // Wert : 0-247 |
EE_Parameter.Hoehe_StickNeutralPoint = 0;// Wert : 0-247 (0 = Hover-Estimation) |
EE_Parameter.FailSafeTime = 0; // 0 = off |
} |
EE_Parameter.Hoehe_Verstaerkung = 15; // Wert : 0-50 (15 -> ca. +/- 5m/sek bei Stick-Voll-Ausschlag) |
EE_Parameter.StartLandChannel = 0; |
EE_Parameter.LandingSpeed = 12; |
EE_Parameter.UserParam1 = 0; // zur freien Verwendung |
EE_Parameter.UserParam2 = 0; // zur freien Verwendung |
EE_Parameter.UserParam3 = 0; // zur freien Verwendung |
EE_Parameter.UserParam4 = 0; // zur freien Verwendung |
EE_Parameter.UserParam5 = 0; // zur freien Verwendung |
EE_Parameter.UserParam6 = 0; // zur freien Verwendung |
EE_Parameter.UserParam7 = 0; // zur freien Verwendung |
EE_Parameter.UserParam8 = 0; // zur freien Verwendung |
EE_Parameter.ServoNickControl = 128; // Wert : 0-247 // Stellung des Servos |
EE_Parameter.ServoNickComp = 50; // Wert : 0-247 // Einfluss Gyro/Servo |
EE_Parameter.ServoCompInvert = 2; // Wert : 0-247 // Richtung Einfluss Gyro/Servo |
EE_Parameter.ServoNickMin = 24; // Wert : 0-247 // Anschlag |
EE_Parameter.ServoNickMax = 230; // Wert : 0-247 // Anschlag |
EE_Parameter.ServoNickRefresh = 3; |
EE_Parameter.Servo3 = 125; |
EE_Parameter.Servo4 = 125; |
EE_Parameter.Servo5 = 125; |
EE_Parameter.ServoRollControl = 128; // Wert : 0-247 // Stellung des Servos |
EE_Parameter.ServoRollComp = 85; // Wert : 0-247 // Einfluss Gyro/Servo |
EE_Parameter.ServoRollMin = 70; // Wert : 0-247 // Anschlag |
EE_Parameter.ServoRollMax = 220; // Wert : 0-247 // Anschlag |
EE_Parameter.ServoManualControlSpeed = 60; |
EE_Parameter.CamOrientation = 0; // Wert : 0-24 -> 0-360 -> 15° steps |
EE_Parameter.J16Bitmask = 0xAA; |
EE_Parameter.J17Bitmask = 0xCC; |
EE_Parameter.WARN_J16_Bitmask = 0x00; |
EE_Parameter.WARN_J17_Bitmask = 0xAA; |
EE_Parameter.J16Timing = 40; |
EE_Parameter.J17Timing = 40; |
EE_Parameter.AutoPhotoDistance = 0; // Photo release in meter |
EE_Parameter.AutoPhotoAtitudes = 0; // Photo release in meter |
EE_Parameter.SingleWpSpeed = 50; // Speed when flying the single points |
EE_Parameter.LoopGasLimit = 50; |
EE_Parameter.LoopThreshold = 90; // Wert: 0-247 Schwelle für Stickausschlag |
EE_Parameter.LoopHysterese = 50; |
EE_Parameter.NaviGpsModeChannel = 6; // Kanal 6 |
EE_Parameter.NaviGpsGain = 100; |
EE_Parameter.NaviGpsP = 100; |
EE_Parameter.NaviGpsI = 90; |
EE_Parameter.NaviGpsD = 120; |
EE_Parameter.NaviGpsA = 40; |
EE_Parameter.NaviGpsPLimit = 75; |
EE_Parameter.NaviGpsILimit = 85; |
EE_Parameter.NaviGpsDLimit = 75; |
EE_Parameter.NaviGpsMinSat = 6; |
EE_Parameter.NaviStickThreshold = 8; |
EE_Parameter.NaviWindCorrection = 50; |
EE_Parameter.NaviAccCompensation = 42; |
EE_Parameter.NaviMaxFlyingRange = 0; |
EE_Parameter.NaviDescendRange = 0; |
EE_Parameter.NaviAngleLimitation = 140; |
EE_Parameter.NaviPH_LoginTime = 2; |
EE_Parameter.OrientationAngle = 0; |
EE_Parameter.CareFreeChannel = 0; |
EE_Parameter.NotGas = 65; // Wert : 0-247 // Gaswert bei Empangsverlust (ggf. in Prozent) |
EE_Parameter.NotGasZeit = 90; // Wert : 0-247 // Zeit bis auf NotGas geschaltet wird, wg. Rx-Problemen |
EE_Parameter.MotorSmooth = 0; |
EE_Parameter.ComingHomeAltitude = 0; // 0 = don't change |
EE_Parameter.MaxAltitude = 150; // 0 = off |
EE_Parameter.AchsKopplung1 = 125; |
EE_Parameter.AchsKopplung2 = 52; |
EE_Parameter.FailsafeChannel = 0; |
EE_Parameter.ServoFilterNick = 0; |
EE_Parameter.ServoFilterRoll = 0; |
EE_Parameter.Servo3OnValue = 140; |
EE_Parameter.Servo3OffValue = 70; |
EE_Parameter.Servo4OnValue = 140; |
EE_Parameter.Servo4OffValue = 70; |
EE_Parameter.ServoFS_Pos[0] = 0; |
EE_Parameter.ServoFS_Pos[1] = 0; |
EE_Parameter.ServoFS_Pos[2] = 0; |
EE_Parameter.ServoFS_Pos[3] = 0; |
EE_Parameter.ServoFS_Pos[4] = 0; |
EE_Parameter.CompassOffset = 0; |
EE_Parameter.UnterspannungsWarnung = 32; // Wert : 0-247 ( Automatische Zellenerkennung bei < 50) |
EE_Parameter.ComingHomeVoltage = 31; |
EE_Parameter.AutoLandingVoltage = 30; |
EE_Parameter.LandingPulse = 960 / 4; |
EE_Parameter.SingleWpControlChannel = 0; |
EE_Parameter.MenuKeyChannel = 0; |
} |
/* |
void ParamSet_DefaultSet1(void) // sport |
{ |
CommonDefaults(); |
EE_Parameter.Stick_P = 14; // Wert : 1-20 |
EE_Parameter.Stick_D = 16; // Wert : 0-20 |
EE_Parameter.StickGier_P = 12; // Wert : 1-20 |
EE_Parameter.Gyro_P = 80; // Wert : 0-247 |
EE_Parameter.Gyro_I = 150; // Wert : 0-247 |
EE_Parameter.Gyro_Gier_P = 80; // Wert : 0-247 |
EE_Parameter.Gyro_Gier_I = 150; // Wert : 0-247 |
EE_Parameter.Gyro_Stability = 6; // Wert : 1-8 |
EE_Parameter.I_Faktor = 32; |
EE_Parameter.CouplingYawCorrection = 1; |
EE_Parameter.GyroAccAbgleich = 16; // 1/k; |
EE_Parameter.DynamicStability = 100; |
memcpy(EE_Parameter.Name, "Sport\0", 12); |
EE_Parameter.crc = RAM_Checksum((uint8_t*)(&EE_Parameter), sizeof(EE_Parameter)-1); |
} |
*/ |
/***************************************************/ |
/* Default Values for parameter set 1 */ |
/***************************************************/ |
void ParamSet_DefaultSet1(void) // normal |
{ |
CommonDefaults(); |
EE_Parameter.Stick_P = 10; // Wert : 1-20 |
EE_Parameter.Stick_D = 16; // Wert : 0-20 |
EE_Parameter.StickGier_P = 6; // Wert : 1-20 |
EE_Parameter.Gyro_P = 90; // Wert : 0-247 |
EE_Parameter.Gyro_I = 120; // Wert : 0-247 |
EE_Parameter.Gyro_Gier_P = 90; // Wert : 0-247 |
EE_Parameter.Gyro_Gier_I = 120; // Wert : 0-247 |
EE_Parameter.Gyro_Stability = 6; // Wert : 1-8 |
EE_Parameter.I_Faktor = 32; |
EE_Parameter.CouplingYawCorrection = 60; |
EE_Parameter.DynamicStability = 75; |
memcpy(EE_Parameter.Name, "Fast",4); |
EE_Parameter.crc = RAM_Checksum((uint8_t*)(&EE_Parameter), sizeof(EE_Parameter)-1); |
} |
/***************************************************/ |
/* Default Values for parameter set 2 */ |
/***************************************************/ |
void ParamSet_DefaultSet2(void) // Agil |
{ |
CommonDefaults(); |
EE_Parameter.Stick_P = 8; // Wert : 1-20 |
EE_Parameter.Stick_D = 16; // Wert : 0-20 |
EE_Parameter.StickGier_P = 6; // Wert : 1-20 |
EE_Parameter.Gyro_P = 100; // Wert : 0-247 |
EE_Parameter.Gyro_I = 120; // Wert : 0-247 |
EE_Parameter.Gyro_Gier_P = 100; // Wert : 0-247 |
EE_Parameter.Gyro_Gier_I = 120; // Wert : 0-247 |
EE_Parameter.Gyro_Stability = 6; // Wert : 1-8 |
EE_Parameter.I_Faktor = 16; |
EE_Parameter.CouplingYawCorrection = 70; |
EE_Parameter.DynamicStability = 70; |
memcpy(EE_Parameter.Name, "Agile",5); |
EE_Parameter.crc = RAM_Checksum((uint8_t*)(&EE_Parameter), sizeof(EE_Parameter)-1); |
} |
/***************************************************/ |
/* Default Values for parameter set 3 */ |
/***************************************************/ |
void ParamSet_DefaultSet3(void) // Easy |
{ |
CommonDefaults(); |
EE_Parameter.Stick_P = 6; // Wert : 1-20 |
EE_Parameter.Stick_D = 10; // Wert : 0-20 |
EE_Parameter.StickGier_P = 4; // Wert : 1-20 |
EE_Parameter.Gyro_P = 100; // Wert : 0-247 |
EE_Parameter.Gyro_I = 120; // Wert : 0-247 |
EE_Parameter.Gyro_Gier_P = 100; // Wert : 0-247 |
EE_Parameter.Gyro_Gier_I = 120; // Wert : 0-247 |
EE_Parameter.Gyro_Stability = 6; // Wert : 1-8 |
EE_Parameter.I_Faktor = 16; |
EE_Parameter.CouplingYawCorrection = 70; |
EE_Parameter.DynamicStability = 70; |
memcpy(EE_Parameter.Name, "Easy", 4); |
EE_Parameter.crc = RAM_Checksum((uint8_t*)(&EE_Parameter), sizeof(EE_Parameter)-1); |
} |
/***************************************************/ |
/* Read Parameter from EEPROM as byte */ |
/***************************************************/ |
uint8_t GetParamByte(uint16_t param_id) |
{ |
return eeprom_read_byte((uint8_t*)(EEPROM_ADR_PARAM_BEGIN + param_id)); |
} |
/***************************************************/ |
/* Write Parameter to EEPROM as byte */ |
/***************************************************/ |
void SetParamByte(uint16_t param_id, uint8_t value) |
{ |
eeprom_write_byte((uint8_t*)(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 *)(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*)(EEPROM_ADR_PARAM_BEGIN + param_id), value); |
} |
/***************************************************/ |
/* Read Parameter Set from EEPROM */ |
/***************************************************/ |
// number [1..5] |
uint8_t ParamSet_ReadFromEEProm(uint8_t setnumber) |
{ |
uint8_t crc; |
uint16_t eeaddr; |
// range the setnumber |
if((1 > setnumber) || (setnumber > 5)) setnumber = 3; |
// calculate eeprom addr |
eeaddr = EEPROM_ADR_PARAMSET + PARAMSET_STRUCT_LEN * (setnumber - 1); |
// calculate checksum from eeprom |
crc = EEProm_Checksum(eeaddr, PARAMSET_STRUCT_LEN - 1); |
// check crc |
if(crc != eeprom_read_byte((uint8_t*)(eeaddr + PARAMSET_STRUCT_LEN - 1))) return 0; |
// check revision |
if(eeprom_read_byte((uint8_t*)(eeaddr)) != EEPARAM_REVISION) return 0; |
// read paramset from eeprom |
eeprom_read_block((void *) &EE_Parameter, (void*)(EEPROM_ADR_PARAMSET + PARAMSET_STRUCT_LEN * (setnumber - 1)), PARAMSET_STRUCT_LEN); |
LED_Init(); |
#if (defined(__AVR_ATmega1284__) || defined(__AVR_ATmega1284P__)) |
LIBFC_HoTT_Clear(); |
#endif |
if(EE_Parameter.LandingPulse < 760 / 4) EE_Parameter.LandingPulse = 0; |
return 1; |
} |
/***************************************************/ |
/* Write Parameter Set to EEPROM */ |
/***************************************************/ |
// number [1..5] |
uint8_t ParamSet_WriteToEEProm(uint8_t setnumber) |
{ |
uint8_t crc; |
if(EE_Parameter.Revision == EEPARAM_REVISION) // write only the right revision to eeprom |
{ |
if(setnumber > 5) setnumber = 5; |
if(setnumber < 1) return 0; |
LIBFC_CheckSettings(); |
if(EE_Parameter.GlobalConfig3 & CFG3_VARIO_FAILSAFE) // check the Setting: Not more than 100% emergency gas |
{ |
if(EE_Parameter.NotGas > 99) EE_Parameter.NotGas = 80; // i.e. 80% of Hovergas |
} |
// update checksum |
EE_Parameter.crc = RAM_Checksum((uint8_t*)(&EE_Parameter), sizeof(EE_Parameter)-1); |
// write paramset to eeprom |
eeprom_write_block((void *) &EE_Parameter, (void*)(EEPROM_ADR_PARAMSET + PARAMSET_STRUCT_LEN * (setnumber - 1)), PARAMSET_STRUCT_LEN); |
// backup channel settings to separate block in eeprom |
eeprom_write_block( (void*)(EE_Parameter.Kanalbelegung), (void*)(EEPROM_ADR_CHANNELS), sizeof(EE_Parameter.Kanalbelegung)); |
// write crc of channel block to eeprom |
crc = RAM_Checksum((uint8_t*)(EE_Parameter.Kanalbelegung), sizeof(EE_Parameter.Kanalbelegung)); |
eeprom_write_byte((uint8_t*)(EEPROM_ADR_CHANNELS + sizeof(EE_Parameter.Kanalbelegung)), crc); |
// update active settings number |
SetActiveParamSet(setnumber); |
LED_Init(); |
#if (defined(__AVR_ATmega1284__) || defined(__AVR_ATmega1284P__)) |
LIBFC_HoTT_Clear(); |
#endif |
return 1; |
} |
// wrong revision |
return 0; |
} |
/***************************************************/ |
/* Read MixerTable from EEPROM */ |
/***************************************************/ |
uint8_t MixerTable_ReadFromEEProm(void) |
{ |
uint8_t crc; |
// calculate checksum in eeprom |
crc = EEProm_Checksum(EEPROM_ADR_MIXERTABLE, sizeof(Mixer) - 1); |
// check crc |
if( crc != eeprom_read_byte((uint8_t*)(EEPROM_ADR_MIXERTABLE + sizeof(Mixer) - 1)) ) return 0; |
// check revision |
if(eeprom_read_byte((uint8_t*)(EEPROM_ADR_MIXERTABLE)) != EEMIXER_REVISION) return 0; |
// read mixer table |
eeprom_read_block((void *) &Mixer, (void*)(EEPROM_ADR_MIXERTABLE), sizeof(Mixer)); |
return 1; |
} |
/***************************************************/ |
/* Write Mixer Table to EEPROM */ |
/***************************************************/ |
uint8_t MixerTable_WriteToEEProm(void) |
{ |
if(Mixer.Revision == EEMIXER_REVISION) |
{ |
// update crc |
Mixer.crc = RAM_Checksum((uint8_t*)(&Mixer), sizeof(Mixer) - 1); |
// write to eeprom |
eeprom_write_block((void *) &Mixer, (void*)(EEPROM_ADR_MIXERTABLE), sizeof(Mixer)); |
return 1; |
} |
else return 0; |
} |
/***************************************************/ |
/* Default Values for Mixer Table */ |
/***************************************************/ |
void MixerTable_Default(void) // Quadro |
{ |
uint8_t i; |
Mixer.Revision = EEMIXER_REVISION; |
// clear mixer table |
for(i = 0; i < 16; i++) |
{ |
Mixer.Motor[i][MIX_GAS] = 0; |
Mixer.Motor[i][MIX_NICK] = 0; |
Mixer.Motor[i][MIX_ROLL] = 0; |
Mixer.Motor[i][MIX_YAW] = 0; |
} |
// default = Quadro |
Mixer.Motor[0][MIX_GAS] = 64; Mixer.Motor[0][MIX_NICK] = +64; Mixer.Motor[0][MIX_ROLL] = 0; Mixer.Motor[0][MIX_YAW] = +64; |
Mixer.Motor[1][MIX_GAS] = 64; Mixer.Motor[1][MIX_NICK] = -64; Mixer.Motor[1][MIX_ROLL] = 0; Mixer.Motor[1][MIX_YAW] = +64; |
Mixer.Motor[2][MIX_GAS] = 64; Mixer.Motor[2][MIX_NICK] = 0; Mixer.Motor[2][MIX_ROLL] = -64; Mixer.Motor[2][MIX_YAW] = -64; |
Mixer.Motor[3][MIX_GAS] = 64; Mixer.Motor[3][MIX_NICK] = 0; Mixer.Motor[3][MIX_ROLL] = +64; Mixer.Motor[3][MIX_YAW] = -64; |
memcpy(Mixer.Name, "Quadro\0\0\0\0\0\0", 12); |
Mixer.crc = RAM_Checksum((uint8_t*)(&Mixer), sizeof(Mixer) - 1); |
} |
/***************************************************/ |
/* Get active parameter set */ |
/***************************************************/ |
uint8_t GetActiveParamSet(void) |
{ |
uint8_t setnumber; |
setnumber = eeprom_read_byte((uint8_t*)(EEPROM_ADR_PARAM_BEGIN + PID_ACTIVE_SET)); |
if(setnumber > 5) |
{ |
setnumber = 3; |
eeprom_write_byte((void*)(EEPROM_ADR_PARAM_BEGIN+PID_ACTIVE_SET), setnumber); |
} |
ActiveParamSet = setnumber; |
return(setnumber); |
} |
/***************************************************/ |
/* Set active parameter set */ |
/***************************************************/ |
void SetActiveParamSet(uint8_t setnumber) |
{ |
if(setnumber > 5) setnumber = 5; |
if(setnumber < 1) setnumber = 1; |
ActiveParamSet = setnumber; |
eeprom_write_byte((uint8_t*)(EEPROM_ADR_PARAM_BEGIN + PID_ACTIVE_SET), setnumber); |
} |
/***************************************************/ |
/* Set default parameter set */ |
/***************************************************/ |
void SetDefaultParameter(uint8_t set, uint8_t restore_channels) |
{ |
if(set > 5) set = 5; |
else if(set < 1) set = 1; |
switch(set) |
{ |
case 1: |
ParamSet_DefaultSet1(); // Fill ParamSet Structure to default parameter set 1 (Sport) |
break; |
case 2: |
ParamSet_DefaultSet2(); // Kamera |
break; |
case 3: |
ParamSet_DefaultSet3(); // Beginner |
break; |
default: |
ParamSet_DefaultSet3(); // Beginner |
break; |
} |
if(restore_channels) |
{ |
uint8_t crc; |
// 1st check for a valid channel backup in eeprom |
crc = EEProm_Checksum(EEPROM_ADR_CHANNELS, sizeof(EE_Parameter.Kanalbelegung)); |
if(crc == eeprom_read_byte((uint8_t*)(EEPROM_ADR_CHANNELS + sizeof(EE_Parameter.Kanalbelegung))) ) |
{ |
eeprom_read_block((void *)EE_Parameter.Kanalbelegung, (void*)(EEPROM_ADR_CHANNELS), sizeof(EE_Parameter.Kanalbelegung)); |
} |
else ParamSet_DefaultStickMapping(); |
} |
else ParamSet_DefaultStickMapping(); |
ParamSet_WriteToEEProm(set); |
} |
/***************************************************/ |
/* Initialize EEPROM Parameter Sets */ |
/***************************************************/ |
void ParamSet_Init(void) |
{ |
uint8_t channel_backup = 0, bad_params = 0, ee_default = 0,i; |
#if (defined(__AVR_ATmega1284__) || defined(__AVR_ATmega1284P__)) |
if(PlatinenVersion != GetParamByte(PID_HARDWARE_VERSION)) |
{ |
J4High; // switch pullup high |
printf("\n\r--> Hardware Version Byte Changed <--"); |
if(PlatinenVersion == 22 && GetParamByte(PID_HARDWARE_VERSION) == 21 && !(PIND & 0x10)) SetParamByte(PID_EE_REVISION,0); // reset the Settings if the Version changed to V2.2 |
SetParamByte(PID_HARDWARE_VERSION,PlatinenVersion); // Remember the Version number |
wdt_enable(WDTO_15MS); // Reset-Commando |
while(1); |
} |
#endif |
if((EEPARAM_REVISION) != GetParamByte(PID_EE_REVISION)) |
{ |
ee_default = 1; // software update or forced by mktool |
} |
// 1st check for a valid channel backup in eeprom |
i = EEProm_Checksum(EEPROM_ADR_CHANNELS, sizeof(EE_Parameter.Kanalbelegung)); |
if(i == eeprom_read_byte((uint8_t*)(EEPROM_ADR_CHANNELS + sizeof(EE_Parameter.Kanalbelegung)))) channel_backup = 1; |
// parameter check |
// check all 5 parameter settings |
for (i = 1;i < 6; i++) |
{ |
if(ee_default || !ParamSet_ReadFromEEProm(i)) // could not read paramset from eeprom |
{ |
bad_params = 1; |
printf("\n\rGenerating default Parameter Set %d",i); |
switch(i) |
{ |
case 1: |
ParamSet_DefaultSet1(); // Fill ParamSet Structure to default parameter set 1 (Sport) |
break; |
case 2: |
ParamSet_DefaultSet2(); // Normal |
break; |
default: |
ParamSet_DefaultSet3(); // Easy |
break; |
} |
if(channel_backup) // if we have an channel mapping backup in eeprom |
{ // restore it from eeprom |
eeprom_read_block((void *)EE_Parameter.Kanalbelegung, (void*)(EEPROM_ADR_CHANNELS), sizeof(EE_Parameter.Kanalbelegung)); |
} |
else |
{ // use default mapping |
ParamSet_DefaultStickMapping(); |
} |
ParamSet_WriteToEEProm(i); |
} |
} |
if(bad_params) // at least one of the parameter settings were invalid |
{ |
// default-Setting is parameter set 3 |
SetActiveParamSet(3); |
} |
// read active parameter set to ParamSet stucture |
i = GetActiveParamSet(); |
ParamSet_ReadFromEEProm(i); |
printf("\n\rUsing Parameter Set %d", i); |
// load mixer table |
if(GetParamByte(PID_EE_REVISION) == 0xff || !MixerTable_ReadFromEEProm() ) |
{ |
printf("\n\rGenerating default Mixer Table"); |
MixerTable_Default(); // Quadro |
MixerTable_WriteToEEProm(); |
} |
if(ee_default) SetParamByte(PID_EE_REVISION, (EEPARAM_REVISION)); |
// determine motornumber |
RequiredMotors = 0; |
for(i = 0; i < MAX_MOTORS; i++) |
{ |
if(Mixer.Motor[i][MIX_GAS] > 0) RequiredMotors++; |
else |
{ |
Mixer.Motor[i][MIX_GAS] = 0; |
Mixer.Motor[i][MIX_NICK] = 0; |
Mixer.Motor[i][MIX_ROLL] = 0; |
Mixer.Motor[i][MIX_YAW] = 0; |
} |
//printf("\n\r%2i:%i:%i:%i:%i",i,Mixer.Motor[i][0],Mixer.Motor[i][1],Mixer.Motor[i][2],Mixer.Motor[i][3]); |
} |
printf("\n\rMixer-Config: '%s' (%u Motors)",Mixer.Name, RequiredMotors); |
PrintLine();// ("\n\r==================================="); |
} |
/tags/V2.12a/eeprom.h |
---|
0,0 → 1,299 |
#ifndef _EEPROM_H |
#define _EEPROM_H |
#include <inttypes.h> |
#include "twimaster.h" |
#define EEPARAM_REVISION 106 // is count up, if paramater stucture has changed (compatibility) |
#define EEMIXER_REVISION 1 // is count up, if mixer stucture has changed (compatibility) |
#define EEPROM_ADR_PARAM_BEGIN 0 |
#define EE_DUMMY 0 // Byte |
#define PID_EE_REVISION 1 // byte |
#define PID_ACTIVE_SET 2 // byte |
#define PID_PRESSURE_OFFSET 3 // byte |
#define PID_ACC_NICK 4 // word |
#define PID_ACC_ROLL 6 // word |
#define PID_ACC_TOP 8 // word |
#define PID_FLIGHT_MINUTES_TOTAL 10 // word |
#define PID_FLIGHT_MINUTES 14 // word |
#define PID_SPEAK_HOTT_CFG 16 // Byte |
#define PID_HARDWARE_VERSION 17 // Byte |
#define PID_GYRO_NICK 18 // word |
#define PID_GYRO_ROLL 20 // word |
#define PID_GYRO_YAW 22 // word |
#define EEPROM_ADR_CHANNELS 80 // 80 - 93, 12 bytes + 1 byte crc |
#define EEPROM_ADR_PARAMSET 100 // 100 - 770, 5 * 134 bytes (V1.06) |
#define EEPROM_ADR_MIXERTABLE 1000 // 1000 - 1078, 78 bytes |
//#define EEPROM_ADR_BLCONFIG 1200 // 1200 - 1296, 12 * 8 bytes |
#define MIX_GAS 0 |
#define MIX_NICK 1 |
#define MIX_ROLL 2 |
#define MIX_YAW 3 |
typedef struct |
{ |
uint8_t Revision; |
int8_t Name[12]; |
int8_t Motor[16][4]; |
uint8_t crc; |
} __attribute__((packed)) MixerTable_t; |
extern MixerTable_t Mixer; |
extern uint8_t RequiredMotors; |
//GlobalConfig3 |
#define CFG3_NO_SDCARD_NO_START 0x01 |
//#define CFG3_DPH_MAX_RADIUS 0x02 |
#define CFG3_VARIO_FAILSAFE 0x04 |
#define CFG3_MOTOR_SWITCH_MODE 0x08 |
#define CFG3_NO_GPSFIX_NO_START 0x10 |
#define CFG3_USE_NC_FOR_OUT1 0x20 |
#define CFG3_SPEAK_ALL 0x40 |
#define CFG3_SERVO_NICK_COMP_OFF 0x80 |
//GlobalConfig |
#define CFG_HOEHENREGELUNG 0x01 |
#define CFG_HOEHEN_SCHALTER 0x02 |
#define CFG_HEADING_HOLD 0x04 |
#define CFG_KOMPASS_AKTIV 0x08 |
#define CFG_KOMPASS_FIX 0x10 |
#define CFG_GPS_AKTIV 0x20 |
#define CFG_ACHSENKOPPLUNG_AKTIV 0x40 |
#define CFG_DREHRATEN_BEGRENZER 0x80 |
//BitConfig |
#define CFG_LOOP_OBEN 0x01 |
#define CFG_LOOP_UNTEN 0x02 |
#define CFG_LOOP_LINKS 0x04 |
#define CFG_LOOP_RECHTS 0x08 |
#define CFG_MOTOR_BLINK1 0x10 |
#define CFG_MOTOR_OFF_LED1 0x20 |
#define CFG_MOTOR_OFF_LED2 0x40 |
#define CFG_MOTOR_BLINK2 0x80 |
// ExtraConfig |
#define CFG2_HEIGHT_LIMIT 0x01 |
#define CFG2_VARIO_BEEP 0x02 |
//#define CFG_SENSITIVE_RC 0x04 |
#define CFG_3_3V_REFERENCE 0x08 |
#define CFG_NO_RCOFF_BEEPING 0x10 |
#define CFG_GPS_AID 0x20 |
#define CFG_LEARNABLE_CAREFREE 0x40 |
#define CFG_IGNORE_MAG_ERR_AT_STARTUP 0x80 |
// bitcoding for EE_Parameter.ServoCompInvert |
#define SERVO_NICK_INV 0x01 |
#define SERVO_ROLL_INV 0x02 |
#define SERVO_RELATIVE 0x04 // direct poti control or relative moving of the servo value |
#define CH_DIRECTION_1 0x08 |
#define CH_DIRECTION_2 0x10 |
//CH Orientation ServoBits 0x08 0x10 |
// --> no change 0 0 |
// --> front to starting point 0 1 |
// --> rear to to starting point 1 0 |
//-> start orientation 1 1 |
// defines for the receiver selection |
#define RECEIVER_PPM 0 |
#define RECEIVER_SPEKTRUM 1 |
#define RECEIVER_SPEKTRUM_HI_RES 2 |
#define RECEIVER_SPEKTRUM_LOW_RES 3 |
#define RECEIVER_JETI 4 |
#define RECEIVER_ACT_DSL 5 |
#define RECEIVER_HOTT 6 |
#define RECEIVER_SBUS 7 |
#define RECEIVER_MLINK 8 |
#define RECEIVER_USER 9 |
#define RECEIVER_UNKNOWN 0xFF |
// defines for lookup ParamSet.ChannelAssignment |
#define K_NICK 0 |
#define K_ROLL 1 |
#define K_GAS 2 |
#define K_GIER 3 |
#define K_POTI1 4 |
#define K_POTI2 5 |
#define K_POTI3 6 |
#define K_POTI4 7 |
#define K_POTI5 8 |
#define K_POTI6 9 |
#define K_POTI7 10 |
#define K_POTI8 11 |
// values above 247 representing poti1 to poti8 |
// poti1 = 255 |
// poti2 = 254 |
// poti3 = 253 |
// poti4 = 252 |
// poti5 = 251 |
// poti6 = 250 |
// poti7 = 249 |
// poti8 = 248 |
typedef struct |
{ |
unsigned char Revision; |
unsigned char Kanalbelegung[12]; // GAS[0], GIER[1],NICK[2], ROLL[3], POTI1, POTI2, POTI3 |
unsigned char GlobalConfig; // 0x01=Höhenregler aktiv,0x02=Kompass aktiv, 0x04=GPS aktiv, 0x08=Heading Hold aktiv |
unsigned char Hoehe_MinGas; // Wert : 0-100 |
unsigned char Luftdruck_D; // Wert : 0-250 |
unsigned char HoeheChannel; // Wert : 0-32 |
unsigned char Hoehe_P; // Wert : 0-32 |
unsigned char Hoehe_Verstaerkung; // Wert : 0-50 |
unsigned char Hoehe_ACC_Wirkung; // Wert : 0-250 |
unsigned char Hoehe_HoverBand; // Wert : 0-250 |
unsigned char Hoehe_TiltCompensation; // Wert : 0-250 |
unsigned char Hoehe_StickNeutralPoint;// Wert : 0-250 |
unsigned char Stick_P; // Wert : 1-6 |
unsigned char Stick_D; // Wert : 0-64 |
unsigned char StickGier_P; // Wert : 1-20 |
unsigned char Gas_Min; // Wert : 0-32 |
unsigned char Gas_Max; // Wert : 33-250 |
unsigned char GyroAccFaktor; // Wert : 1-64 |
unsigned char KompassWirkung; // Wert : 0-32 |
unsigned char Gyro_P; // Wert : 10-250 |
unsigned char Gyro_I; // Wert : 0-250 |
unsigned char Gyro_D; // Wert : 0-250 |
unsigned char Gyro_Gier_P; // Wert : 10-250 |
unsigned char Gyro_Gier_I; // Wert : 0-250 |
unsigned char Gyro_Stability; // Wert : 0-16 |
unsigned char UnterspannungsWarnung; // Wert : 0-250 |
unsigned char NotGas; // Wert : 0-250 //Gaswert bei Empängsverlust |
unsigned char NotGasZeit; // Wert : 0-250 // Zeitbis auf NotGas geschaltet wird, wg. Rx-Problemen |
unsigned char Receiver; // 0= Summensignal, 1= Spektrum, 2 =Jeti, 3=ACT DSL, 4=ACT S3D |
unsigned char I_Faktor; // Wert : 0-250 |
unsigned char UserParam1; // Wert : 0-250 |
unsigned char UserParam2; // Wert : 0-250 |
unsigned char UserParam3; // Wert : 0-250 |
unsigned char UserParam4; // Wert : 0-250 |
unsigned char ServoNickControl; // Wert : 0-250 // Stellung des Servos |
unsigned char ServoNickComp; // Wert : 0-250 // Einfluss Gyro/Servo |
unsigned char ServoNickMin; // Wert : 0-250 // Anschlag |
unsigned char ServoNickMax; // Wert : 0-250 // Anschlag |
//--- Seit V0.75 |
unsigned char ServoRollControl; // Wert : 0-250 // Stellung des Servos |
unsigned char ServoRollComp; // Wert : 0-250 |
unsigned char ServoRollMin; // Wert : 0-250 |
unsigned char ServoRollMax; // Wert : 0-250 |
//--- |
unsigned char ServoNickRefresh; // Speed of the Servo |
unsigned char ServoManualControlSpeed;// |
unsigned char CamOrientation; // |
unsigned char Servo3; // Value or mapping of the Servo Output |
unsigned char Servo4; // Value or mapping of the Servo Output |
unsigned char Servo5; // Value or mapping of the Servo Output |
unsigned char LoopGasLimit; // Wert: 0-250 max. Gas während Looping |
unsigned char LoopThreshold; // Wert: 0-250 Schwelle für Stickausschlag |
unsigned char LoopHysterese; // Wert: 0-250 Hysterese für Stickausschlag |
unsigned char AchsKopplung1; // Wert: 0-250 Faktor, mit dem Gier die Achsen Roll und Nick koppelt (NickRollMitkopplung) |
unsigned char AchsKopplung2; // Wert: 0-250 Faktor, mit dem Nick und Roll verkoppelt werden |
unsigned char CouplingYawCorrection; // Wert: 0-250 Faktor, mit dem Nick und Roll verkoppelt werden |
unsigned char WinkelUmschlagNick; // Wert: 0-250 180°-Punkt |
unsigned char WinkelUmschlagRoll; // Wert: 0-250 180°-Punkt |
unsigned char GyroAccAbgleich; // 1/k (Koppel_ACC_Wirkung) |
unsigned char Driftkomp; |
unsigned char DynamicStability; |
unsigned char UserParam5; // Wert : 0-250 |
unsigned char UserParam6; // Wert : 0-250 |
unsigned char UserParam7; // Wert : 0-250 |
unsigned char UserParam8; // Wert : 0-250 |
//---Output --------------------------------------------- |
unsigned char J16Bitmask; // for the J16 Output |
unsigned char J16Timing; // for the J16 Output |
unsigned char J17Bitmask; // for the J17 Output |
unsigned char J17Timing; // for the J17 Output |
// seit version V0.75c |
unsigned char WARN_J16_Bitmask; // for the J16 Output |
unsigned char WARN_J17_Bitmask; // for the J17 Output |
//---NaviCtrl--------------------------------------------- |
unsigned char AutoPhotoDistance; // Auto Photo |
unsigned char NaviGpsModeChannel; // Parameters for the Naviboard |
unsigned char NaviGpsGain; |
unsigned char NaviGpsP; |
unsigned char NaviGpsI; |
unsigned char NaviGpsD; |
unsigned char NaviGpsPLimit; |
unsigned char NaviGpsILimit; |
unsigned char NaviGpsDLimit; |
unsigned char NaviGpsA; |
unsigned char NaviGpsMinSat; |
unsigned char NaviStickThreshold; |
unsigned char NaviWindCorrection; |
unsigned char NaviAccCompensation; // New since 0.86 -> was: SpeedCompensation |
unsigned char NaviMaxFlyingRange; // in 10m |
unsigned char NaviAngleLimitation; |
unsigned char NaviPH_LoginTime; |
unsigned char NaviDescendRange; |
//---Ext.Ctrl--------------------------------------------- |
unsigned char ExternalControl; // for serial Control |
//---CareFree--------------------------------------------- |
unsigned char OrientationAngle; // Where is the front-direction? |
unsigned char CareFreeChannel; // switch for CareFree |
unsigned char MotorSafetySwitch; |
unsigned char MotorSmooth; |
unsigned char ComingHomeAltitude; |
unsigned char FailSafeTime; |
unsigned char MaxAltitude; |
unsigned char FailsafeChannel; // if the value of this channel is > 100, the MK reports "RC-Lost" |
unsigned char ServoFilterNick; |
unsigned char ServoFilterRoll; |
unsigned char Servo3OnValue; |
unsigned char Servo3OffValue; |
unsigned char Servo4OnValue; |
unsigned char Servo4OffValue; |
unsigned char ServoFS_Pos[5]; |
unsigned char StartLandChannel; |
unsigned char LandingSpeed; |
unsigned char CompassOffset; |
unsigned char AutoLandingVoltage; // in 0,1V 0 -> disabled |
unsigned char ComingHomeVoltage; // in 0,1V 0 -> disabled |
unsigned char AutoPhotoAtitudes; |
unsigned char SingleWpSpeed; |
unsigned char LandingPulse; |
unsigned char SingleWpControlChannel; |
unsigned char MenuKeyChannel; |
//------------------------------------------------ |
unsigned char BitConfig; // (war Loop-Cfg) Bitcodiert: 0x01=oben, 0x02=unten, 0x04=links, 0x08=rechts / wird getrennt behandelt |
unsigned char ServoCompInvert; // // 0x01 = Nick, 0x02 = Roll, 0x04 = relative moving // WICHTIG!!! am Ende lassen |
unsigned char ExtraConfig; // bitcodiert |
unsigned char GlobalConfig3; // bitcodiert |
char Name[12]; |
unsigned char crc; // must be the last byte! |
} paramset_t; // 134 bytes (V1.06) |
#define PARAMSET_STRUCT_LEN sizeof(paramset_t) |
extern paramset_t EE_Parameter; |
extern uint8_t RAM_Checksum(uint8_t* pBuffer, uint16_t len); |
extern void ParamSet_Init(void); |
extern void SetDefaultParameter(uint8_t set, uint8_t restore_channels); |
extern uint8_t ParamSet_ReadFromEEProm(uint8_t setnumber); |
extern uint8_t ParamSet_WriteToEEProm(uint8_t setnumber); |
extern uint8_t GetActiveParamSet(void); |
extern void SetActiveParamSet(uint8_t setnumber); |
extern uint8_t MixerTable_ReadFromEEProm(void); |
extern uint8_t MixerTable_WriteToEEProm(void); |
extern uint8_t GetParamByte(uint16_t param_id); |
extern void SetParamByte(uint16_t param_id, uint8_t value); |
extern uint16_t GetParamWord(uint16_t param_id); |
extern void SetParamWord(uint16_t param_id, uint16_t value); |
#endif //_EEPROM_H |
/tags/V2.12a/fc.c |
---|
0,0 → 1,2261 |
/*####################################################################################### |
Flight Control |
#######################################################################################*/ |
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
// + www.MikroKopter.com |
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
// + Software Nutzungsbedingungen (english version: see below) |
// + der Fa. HiSystems GmbH, Flachsmeerstrasse 2, 26802 Moormerland - nachfolgend Lizenzgeber genannt - |
// + Der Lizenzgeber räumt dem Kunden ein nicht-ausschließliches, zeitlich und räumlich* unbeschränktes Recht ein, die im den |
// + Mikrocontroller verwendete Firmware für die Hardware Flight-Ctrl, Navi-Ctrl, BL-Ctrl, MK3Mag & PC-Programm MikroKopter-Tool |
// + - nachfolgend Software genannt - nur für private Zwecke zu nutzen. |
// + Der Einsatz dieser Software ist nur auf oder mit Produkten des Lizenzgebers zulässig. |
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
// + Die vom Lizenzgeber gelieferte Software ist urheberrechtlich geschützt. Alle Rechte an der Software sowie an sonstigen im |
// + Rahmen der Vertragsanbahnung und Vertragsdurchführung überlassenen Unterlagen stehen im Verhältnis der Vertragspartner ausschließlich dem Lizenzgeber zu. |
// + Die in der Software enthaltenen Copyright-Vermerke, Markenzeichen, andere Rechtsvorbehalte, Seriennummern sowie |
// + sonstige der Programmidentifikation dienenden Merkmale dürfen vom Kunden nicht verändert oder unkenntlich gemacht werden. |
// + Der Kunde trifft angemessene Vorkehrungen für den sicheren Einsatz der Software. Er wird die Software gründlich auf deren |
// + Verwendbarkeit zu dem von ihm beabsichtigten Zweck testen, bevor er diese operativ einsetzt. |
// + Die Haftung des Lizenzgebers wird - soweit gesetzlich zulässig - begrenzt in Höhe des typischen und vorhersehbaren |
// + Schadens. Die gesetzliche Haftung bei Personenschäden und nach dem Produkthaftungsgesetz bleibt unberührt. Dem Lizenzgeber steht jedoch der Einwand |
// + des Mitverschuldens offen. |
// + Der Kunde trifft angemessene Vorkehrungen für den Fall, dass die Software ganz oder teilweise nicht ordnungsgemäß arbeitet. |
// + Er wird die Software gründlich auf deren Verwendbarkeit zu dem von ihm beabsichtigten Zweck testen, bevor er diese operativ einsetzt. |
// + Der Kunde wird er seine Daten vor Einsatz der Software nach dem Stand der Technik sichern. |
// + Der Kunde ist darüber unterrichtet, dass der Lizenzgeber seine Daten im zur Vertragsdurchführung erforderlichen Umfang |
// + und auf Grundlage der Datenschutzvorschriften erhebt, speichert, verarbeitet und, sofern notwendig, an Dritte übermittelt. |
// + *) Die räumliche Nutzung bezieht sich nur auf den Einsatzort, nicht auf die Reichweite der programmierten Software. |
// + #### ENDE DER NUTZUNGSBEDINGUNGEN ####' |
// + Hinweis: Informationen über erweiterte Nutzungsrechte (wie z.B. Nutzung für nicht-private Zwecke) sind auf Anfrage per Email an info(@)hisystems.de verfügbar. |
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
// + Software LICENSING TERMS |
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
// + of HiSystems GmbH, Flachsmeerstrasse 2, 26802 Moormerland, Germany - the Licensor - |
// + The Licensor grants the customer a non-exclusive license to use the microcontroller firmware of the Flight-Ctrl, Navi-Ctrl, BL-Ctrl, and MK3Mag hardware |
// + (the Software) exclusively for private purposes. The License is unrestricted with respect to time and territory*. |
// + The Software may only be used with the Licensor's products. |
// + The Software provided by the Licensor is protected by copyright. With respect to the relationship between the parties to this |
// + agreement, all rights pertaining to the Software and other documents provided during the preparation and execution of this |
// + agreement shall be the property of the Licensor. |
// + The information contained in the Software copyright notices, trademarks, other legal reservations, serial numbers and other |
// + features that can be used to identify the program may not be altered or defaced by the customer. |
// + The customer shall be responsible for taking reasonable precautions |
// + for the safe use of the Software. The customer shall test the Software thoroughly regarding its suitability for the |
// + intended purpose before implementing it for actual operation. The Licensor's liability shall be limited to the extent of typical and |
// + foreseeable damage to the extent permitted by law, notwithstanding statutory liability for bodily injury and product |
// + liability. However, the Licensor shall be entitled to the defense of contributory negligence. |
// + The customer will take adequate precautions in the case, that the software is not working properly. The customer will test |
// + the software for his purpose before any operational usage. The customer will backup his data before using the software. |
// + The customer understands that the Licensor collects, stores and processes, and, where required, forwards, customer data |
// + to third parties to the extent necessary for executing the agreement, subject to applicable data protection and privacy regulations. |
// + *) The territory aspect only refers to the place where the Software is used, not its programmed range. |
// + #### END OF LICENSING TERMS #### |
// + Note: For information on license extensions (e.g. commercial use), please contact us at info(@)hisystems.de. |
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
#include "main.h" |
#include "mymath.h" |
#include "isqrt.h" |
unsigned char h,m,s; |
unsigned int BaroExpandActive = 0; |
int MesswertNick,MesswertRoll,MesswertGier,RohMesswertNick,RohMesswertRoll; |
int TrimNick, TrimRoll; |
int AdNeutralNick = 0,AdNeutralRoll = 0,AdNeutralGier = 0,StartNeutralRoll = 0,StartNeutralNick = 0; |
int BoatNeutralNick = 0,BoatNeutralRoll = 0,BoatNeutralGier = 0; |
int Mittelwert_AccNick, Mittelwert_AccRoll; |
unsigned int NeutralAccX=0, NeutralAccY=0; |
int NaviAccNick, NaviAccRoll,NaviCntAcc = 0; |
int NeutralAccZ = 0; |
signed char NeutralAccZfine = 0; |
unsigned char ControlHeading = 0;// in 2° |
long IntegralNick = 0; |
long IntegralRoll = 0; |
long Integral_Gier = 0; |
long Mess_IntegralNick = 0; |
long Mess_IntegralRoll = 0; |
long Mess_Integral_Gier = 0,Mess_Integral_Gier2 = 0; |
long MittelIntegralNick,MittelIntegralRoll; |
long SummeNick=0,SummeRoll=0; |
volatile long Mess_Integral_Hoch = 0; |
int KompassValue = -1; |
int KompassSollWert = 0; |
int NC_CompassSetpoint = -1; |
//int KompassRichtung = 0; |
char CalculateCompassTimer = 100; |
unsigned char KompassFusion = 32; |
unsigned int KompassSignalSchlecht = 50; |
unsigned char MAX_GAS,MIN_GAS; |
unsigned char HoehenReglerAktiv = 0; |
unsigned char TrichterFlug = 0; |
long Umschlag180Nick = 250000L, Umschlag180Roll = 250000L; |
long ErsatzKompass; |
int ErsatzKompassInGrad, CompassCorrected; // Kompasswert in Grad |
int GierGyroFehler = 0; |
char GyroFaktor,GyroFaktorGier; |
char IntegralFaktor,IntegralFaktorGier; |
int DiffNick,DiffRoll; |
unsigned int StickGasHover = 127; |
int HoverGasMin = 0, HoverGasMax = 1023; |
int StickNick = 0,StickRoll = 0,StickGier = 0,StickGas = 0; |
//int Poti1 = 0, Poti2 = 0, Poti3 = 0, Poti4 = 0, Poti5 = 0, Poti6 = 0, Poti7 = 0, Poti8 = 0; |
unsigned char Poti[9] = {0,0,0,0,0,0,0,0}; |
volatile unsigned char SenderOkay = 0; |
char MotorenEin = 0,StartTrigger = 0; |
long HoehenWert = 0; |
long SollHoehe = 0; |
signed int AltitudeSetpointTrimming = 0; |
long FromNC_AltitudeSetpoint = 0; |
unsigned char FromNC_AltitudeSpeed = 0; |
unsigned char carefree_old = 50; // to make the Beep when switching |
signed char WaypointTrimming = 0; |
int CompassGierSetpoint = 0; |
unsigned char CalibrationDone = 0; |
char NeueKompassRichtungMerken = 0; |
int LageKorrekturRoll = 0,LageKorrekturNick = 0, HoverGas = 0; |
//float Ki = FAKTOR_I; |
int Ki = 10300 / 33; |
unsigned char Looping_Nick = 0,Looping_Roll = 0; |
unsigned char Looping_Links = 0, Looping_Rechts = 0, Looping_Unten = 0, Looping_Oben = 0; |
unsigned char Parameter_Luftdruck_D = 48; // Wert : 0-250 |
unsigned char Parameter_HoehenSchalter = 0; // Wert : 0-250 |
unsigned char Parameter_Hoehe_P = 16; // Wert : 0-32 |
unsigned char Parameter_Hoehe_ACC_Wirkung = 58; // Wert : 0-250 |
unsigned char Parameter_KompassWirkung = 64; // Wert : 0-250 |
unsigned char Parameter_Hoehe_TiltCompensation = 100; // Wert : 0-250 |
unsigned char Parameter_Gyro_D = 8; // Wert : 0-250 |
unsigned char Parameter_Gyro_P = 150; // Wert : 10-250 |
unsigned char Parameter_Gyro_I = 150; // Wert : 0-250 |
unsigned char Parameter_Gyro_Gier_P = 150; // Wert : 10-250 |
unsigned char Parameter_Gyro_Gier_I = 150; // Wert : 10-250 |
unsigned char Parameter_Gier_P = 2; // Wert : 1-20 |
unsigned char Parameter_I_Faktor = 10; // Wert : 1-20 |
unsigned char Parameter_UserParam1 = 0; |
unsigned char Parameter_UserParam2 = 0; |
unsigned char Parameter_UserParam3 = 0; |
unsigned char Parameter_UserParam4 = 0; |
unsigned char Parameter_UserParam5 = 0; |
unsigned char Parameter_UserParam6 = 0; |
unsigned char Parameter_UserParam7 = 0; |
unsigned char Parameter_UserParam8 = 0; |
unsigned char Parameter_NickControl = 100; |
unsigned char Parameter_ServoNickControl = 100; |
unsigned char Parameter_ServoRollControl = 100; |
unsigned char Parameter_ServoNickComp = 50; |
unsigned char Parameter_ServoRollComp = 85; |
unsigned char Parameter_LoopGasLimit = 70; |
unsigned char Parameter_AchsKopplung1 = 90; |
unsigned char Parameter_AchsKopplung2 = 65; |
unsigned char Parameter_CouplingYawCorrection = 64; |
//unsigned char Parameter_AchsGegenKopplung1 = 0; |
unsigned char Parameter_DynamicStability = 100; |
unsigned char Parameter_J16Bitmask; // for the J16 Output |
unsigned char Parameter_J16Timing; // for the J16 Output |
unsigned char Parameter_J17Bitmask; // for the J17 Output |
unsigned char Parameter_J17Timing; // for the J17 Output |
unsigned char Parameter_NaviGpsGain; |
unsigned char Parameter_NaviGpsP; |
unsigned char Parameter_NaviGpsI; |
unsigned char Parameter_NaviGpsD; |
unsigned char Parameter_NaviGpsA; |
//unsigned char Parameter_NaviOperatingRadius; |
unsigned char Parameter_NaviWindCorrection; |
unsigned char Parameter_NaviSpeedCompensation; |
unsigned char Parameter_ExternalControl; |
unsigned char Parameter_GlobalConfig; |
unsigned char Parameter_ExtraConfig; |
unsigned char Parameter_MaximumAltitude; |
unsigned char Parameter_Servo3,Parameter_Servo4,Parameter_Servo5; |
unsigned char CareFree = 0; |
const signed char sintab[31] = { 0, 2, 4, 6, 7, 8, 8, 8, 7, 6, 4, 2, 0, -2, -4, -6, -7, -8, -8, -8, -7, -6, -4, -2, 0, 2, 4, 6, 7, 8, 8}; // 15° steps |
int MaxStickNick = 0,MaxStickRoll = 0; |
unsigned int modell_fliegt = 0; |
volatile unsigned char FC_StatusFlags = 0, FC_StatusFlags2 = 0; |
unsigned char FC_StatusFlags3 = 0; |
long GIER_GRAD_FAKTOR = 1291; |
signed int KopplungsteilNickRoll,KopplungsteilRollNick; |
signed int tmp_motorwert[MAX_MOTORS]; |
char VarioCharacter = ' '; |
unsigned int HooverGasEmergencyPercent = 0; // The gas value for Emergency landing |
unsigned int GasIsZeroCnt = 0; // to detect that the gas-stick is down for a while |
signed int Variance = 0; |
signed int CosAttitude; // for projection of hoover gas |
unsigned char ACC_AltitudeControl = 0; |
unsigned char LowVoltageLandingActive = 0; |
unsigned char LowVoltageHomeActive = 0; |
signed int DriftNick = 0, DriftRoll = 0; |
unsigned char ServoFailsafeActive = 0; // moves Servos into the FS-Position |
#if (defined(__AVR_ATmega1284__) || defined(__AVR_ATmega1284P__)) |
#define OPA_OFFSET_STEP 5 |
#else |
#define OPA_OFFSET_STEP 10 |
#endif |
// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
// Debugwerte zuordnen |
// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
void CopyDebugValues(void) |
{ |
DebugOut.Analog[0] = ToNaviCtrl.IntegralNick;//IntegralNick / (EE_Parameter.GyroAccFaktor * 4); |
DebugOut.Analog[1] = ToNaviCtrl.IntegralRoll;//IntegralRoll / (EE_Parameter.GyroAccFaktor * 4); |
DebugOut.Analog[2] = Mittelwert_AccNick / 4; |
DebugOut.Analog[3] = Mittelwert_AccRoll / 4; |
DebugOut.Analog[4] = (signed int) AdNeutralGier - AdWertGier; |
DebugOut.Analog[5] = HoehenWert/10; |
DebugOut.Analog[6] = Aktuell_az;//AdWertAccHoch;//(Mess_Integral_Hoch / 512); |
DebugOut.Analog[8] = KompassValue; |
DebugOut.Analog[9] = UBat; |
DebugOut.Analog[10] = SenderOkay; |
DebugOut.Analog[11] = ErsatzKompassInGrad; |
DebugOut.Analog[12] = Motor[0].SetPoint; |
DebugOut.Analog[13] = Motor[1].SetPoint; |
DebugOut.Analog[14] = Motor[2].SetPoint; |
DebugOut.Analog[15] = Motor[3].SetPoint; |
DebugOut.Analog[20] = ServoNickValue; |
DebugOut.Analog[21] = HoverGas; |
DebugOut.Analog[22] = Capacity.ActualCurrent; |
DebugOut.Analog[23] = Capacity.UsedCapacity; |
DebugOut.Analog[24] = SollHoehe/10; |
// DebugOut.Analog[27] = KompassSollWert; |
DebugOut.Analog[29] = Capacity.MinOfMaxPWM; |
DebugOut.Analog[30] = GPS_Nick; |
DebugOut.Analog[31] = GPS_Roll; |
if(VersionInfo.HardwareError[0] || VersionInfo.HardwareError[1]) DebugOut.Status[1] |= 1; else DebugOut.Status[1] &= 0xfe; |
//DebugOut.Analog[16] = MinBlTemperture; |
//DebugOut.Analog[17] = MaxBlTemperture; |
//DebugOut.Analog[16] = Variance; |
//DebugOut.Analog[17] = VarioMeter; |
//DebugOut.Analog[16] = GasIsZeroCnt; |
//DebugOut.Analog[18] = HoehenWertF; |
//DebugOut.Analog[25] = Parameter_Hoehe_P; |
//DebugOut.Analog[26] = Parameter_Luftdruck_D; |
} |
void Piep(unsigned char Anzahl, unsigned int dauer) |
{ |
unsigned int wait = 0; |
unsigned char update_spi = 12; |
if(MotorenEin) return; //auf keinen Fall im Flug! |
GRN_OFF; |
while(Anzahl--) |
{ |
beeptime = dauer; |
wait = dauer; |
while(beeptime || wait) |
{ |
if(UpdateMotor) |
{ |
UpdateMotor = 0; |
if(!beeptime) wait--; |
LIBFC_Polling(); |
update_spi--; |
}; |
if(update_spi == 0) // 41Hz |
{ |
if(SPI_StartTransmitPacket()) update_spi = 12; |
else |
if(BytegapSPI == 0) SPI_TransmitByte(); |
} |
else if(BytegapSPI == 0) SPI_TransmitByte(); |
} |
} |
GRN_ON; |
} |
//############################################################################ |
// Messwerte beim Ermitteln der Nullage |
void CalibrierMittelwert(void) |
//############################################################################ |
{ |
// if(PlatinenVersion == 13) SucheGyroOffset(); |
// ADC auschalten, damit die Werte sich nicht während der Berechnung ändern |
ANALOG_OFF; |
MesswertNick = AdWertNick; |
MesswertRoll = AdWertRoll; |
MesswertGier = AdWertGier; |
Mittelwert_AccNick = ACC_AMPLIFY * AdWertAccNick; |
Mittelwert_AccRoll = ACC_AMPLIFY * AdWertAccRoll; |
// ADC einschalten |
ANALOG_ON; |
Umschlag180Nick = (long) EE_Parameter.WinkelUmschlagNick * 2500L; |
Umschlag180Roll = (long) EE_Parameter.WinkelUmschlagRoll * 2500L; |
} |
void StoreNeutralToEeprom(void) |
{ |
BoatNeutralNick = AdNeutralNick; |
BoatNeutralRoll = AdNeutralRoll; |
BoatNeutralGier = AdNeutralGier; |
SetParamWord(PID_ACC_NICK, (uint16_t)NeutralAccX); |
SetParamWord(PID_ACC_ROLL, (uint16_t)NeutralAccY); |
SetParamWord(PID_GYRO_NICK,(uint16_t)BoatNeutralNick); |
SetParamWord(PID_GYRO_ROLL,(uint16_t)BoatNeutralRoll); |
SetParamWord(PID_GYRO_YAW,(uint16_t)BoatNeutralGier); |
} |
//############################################################################ |
// Nullwerte ermitteln |
// Parameter: 0 -> after switch on (ignore ACC-Z fault) |
// Parameter: 1 -> before Start |
// Parameter: 2 -> calibrate and store ACC |
// Parameter: 3 -> use stored Gyro calibration Data from EEPROM (Boat-Mode) |
unsigned char SetNeutral(unsigned char AdjustmentMode) // retuns: "sucess" |
//############################################################################ |
{ |
unsigned char i, sucess = 1; |
unsigned int gier_neutral = 0, nick_neutral = 0, roll_neutral = 0, acc_z_neutral = 0, barotest; |
VersionInfo.HardwareError[0] = 0; |
// HEF4017Reset_ON; |
NeutralAccX = 0; |
NeutralAccY = 0; |
NeutralAccZ = 0; |
NeutralAccZfine = 0; |
AdNeutralNick = 0; |
AdNeutralRoll = 0; |
AdNeutralGier = 0; |
Parameter_AchsKopplung1 = 0; |
Parameter_AchsKopplung2 = 0; |
ExpandBaro = 0; |
if(AdjustmentMode == 3) FC_StatusFlags3 |= FC_STATUS3_BOAT; |
// else FC_StatusFlags3 &= ~FC_STATUS3_BOAT; -> do not clear that |
CalibrierMittelwert(); |
Delay_ms_Mess(100); |
CalibrierMittelwert(); |
if((EE_Parameter.GlobalConfig & CFG_HOEHENREGELUNG)) // Höhenregelung aktiviert? |
{ |
if((MessLuftdruck > 950) || (MessLuftdruck < 750) || ExpandBaro) SucheLuftruckOffset(); |
} |
barotest = MessLuftdruck; |
#define NEUTRAL_FILTER 32 |
OCR0A += OPA_OFFSET_STEP; |
OCR0B = 255 - OCR0A; |
for(i=0; i<NEUTRAL_FILTER; i++) |
{ |
Delay_ms_Mess(10); |
gier_neutral += AdWertGier; |
nick_neutral += AdWertNick; |
roll_neutral += AdWertRoll; |
acc_z_neutral += Aktuell_az; |
} |
if(MessLuftdruck < 1010 && MessLuftdruck > 20) BaroStep = barotest - MessLuftdruck; |
OCR0A -= OPA_OFFSET_STEP; |
OCR0B = 255 - OCR0A; |
AdNeutralNick = (nick_neutral+NEUTRAL_FILTER/2) / (NEUTRAL_FILTER / 8); |
AdNeutralRoll = (roll_neutral+NEUTRAL_FILTER/2) / (NEUTRAL_FILTER / 8); |
AdNeutralGier = (gier_neutral+NEUTRAL_FILTER/2) / (NEUTRAL_FILTER); |
NeutralAccZ = (acc_z_neutral+NEUTRAL_FILTER/2) / (NEUTRAL_FILTER); |
StartNeutralRoll = AdNeutralRoll; |
StartNeutralNick = AdNeutralNick; |
if(AdjustmentMode == 2) |
{ |
NeutralAccX = abs(Mittelwert_AccNick) / (2*ACC_AMPLIFY); |
NeutralAccY = abs(Mittelwert_AccRoll) / (2*ACC_AMPLIFY); |
// Save ACC neutral settings to eeprom |
StoreNeutralToEeprom(); |
} |
else |
{ |
// restore from eeprom |
NeutralAccX = (int16_t)GetParamWord(PID_ACC_NICK); |
NeutralAccY = (int16_t)GetParamWord(PID_ACC_ROLL); |
// strange settings? |
if(((unsigned int) NeutralAccX > 2048) || ((unsigned int) NeutralAccY > 2048)/* || ((unsigned int) NeutralAccZ > 1024)*/) |
{ |
printf("\n\rACC not calibrated!\r\n"); |
NeutralAccX = abs(Mittelwert_AccNick) / (2*ACC_AMPLIFY); |
NeutralAccY = abs(Mittelwert_AccRoll) / (2*ACC_AMPLIFY); |
sucess = 0; |
} |
// restore from eeprom |
BoatNeutralNick = (int16_t)GetParamWord(PID_GYRO_NICK); |
BoatNeutralRoll = (int16_t)GetParamWord(PID_GYRO_ROLL); |
BoatNeutralGier = (int16_t)GetParamWord(PID_GYRO_YAW); |
if(FC_StatusFlags3 & FC_STATUS3_BOAT) // Read Gyro Data from eeprom |
{ |
// strange settings? |
if(((unsigned int) BoatNeutralNick > (600 * 16)) || ((unsigned int) BoatNeutralNick < (400 * 16)) |
|| ((unsigned int) BoatNeutralRoll > (600 * 16)) || ((unsigned int) BoatNeutralRoll < (400 * 16)) |
|| ((unsigned int) BoatNeutralGier > (600 * 2)) || ((unsigned int) BoatNeutralGier < (400 * 2))) |
{ |
printf("\n\rGyro calibration data not valid\r\n"); |
sucess = 0; |
FC_StatusFlags3 &= ~FC_STATUS3_BOAT; |
} |
else |
{ |
AdNeutralNick = BoatNeutralNick; |
AdNeutralRoll = BoatNeutralRoll; |
AdNeutralGier = BoatNeutralGier; |
} |
} |
} |
EEAR = EE_DUMMY; // Set the EEPROM Address pointer to an unused space |
MesswertNick = 0; |
MesswertRoll = 0; |
MesswertGier = 0; |
Delay_ms_Mess(200); |
Mittelwert_AccNick = ACC_AMPLIFY * AdWertAccNick; |
Mittelwert_AccRoll = ACC_AMPLIFY * AdWertAccRoll; |
IntegralNick = EE_Parameter.GyroAccFaktor * (long)Mittelwert_AccNick; |
IntegralRoll = EE_Parameter.GyroAccFaktor * (long)Mittelwert_AccRoll; |
Mess_IntegralNick = IntegralNick; |
Mess_IntegralRoll = IntegralRoll; |
Mess_Integral_Gier = 0; |
KompassSollWert = KompassValue; |
NC_CompassSetpoint = -1; |
KompassSignalSchlecht = 100; |
Umschlag180Nick = ((long) EE_Parameter.WinkelUmschlagNick * 2500L) + 15000L; |
Umschlag180Roll = ((long) EE_Parameter.WinkelUmschlagRoll * 2500L) + 15000L; |
ErsatzKompass = KompassValue * GIER_GRAD_FAKTOR; |
GierGyroFehler = 0; |
LED_Init(); |
if(AdjustmentMode != 0) FC_StatusFlags |= FC_STATUS_CALIBRATE; |
FromNaviCtrl_Value.Kalman_K = -1; |
FromNaviCtrl_Value.Kalman_MaxDrift = 0; |
FromNaviCtrl_Value.Kalman_MaxFusion = 32; |
SenderOkay = 100; |
if(ServoActive) DDRD |=0x80; // enable J7 -> Servo signal |
else |
{ |
if((EE_Parameter.ServoCompInvert & SERVO_NICK_INV) && (EE_Parameter.ServoCompInvert & SERVO_RELATIVE)) NickServoValue = 12000;//((128 + 60) * 4 * 16); // neutral position = upper 1/4// else |
else NickServoValue = ((128 - 60) * 4 * 16); // neutral position = lower 1/4 |
CalculateServoSignals = 1; |
CalculateServo(); // nick |
CalculateServo(); // roll |
} |
#if (defined(__AVR_ATmega1284__) || defined(__AVR_ATmega1284P__)) |
signed int tilt1, tilt2; |
tilt1 = (int)(IntegralNick/GIER_GRAD_FAKTOR); // nick angle in deg |
tilt2 = (int)(IntegralRoll/GIER_GRAD_FAKTOR); // roll angle in deg |
tilt1 = (int16_t)ihypot(tilt1,tilt2); // tilt angle over all |
CosAttitude = c_cos_8192(tilt1); |
NeutralAccZ = (long)((long) (NeutralAccZ - 512) * 8192 + 4096) / CosAttitude + 512; |
if(tilt1 > 20) sucess = 0; // calibration must be within 20° Tilt angle |
if(AdjustmentMode != 0 && ACC_AltitudeControl) if((NeutralAccZ < 682 - 30) || (NeutralAccZ > 682 + 35)) { VersionInfo.HardwareError[0] |= FC_ERROR0_ACC_TOP; sucess = 0;}; |
#else |
NeutralAccZ = (int16_t)GetParamWord(PID_ACC_TOP); |
EEAR = EE_DUMMY; // Set the EEPROM Address pointer to an unused space |
#endif |
if((AdNeutralNick < 150 * 16) || (AdNeutralNick > 850 * 16)) { VersionInfo.HardwareError[0] |= FC_ERROR0_GYRO_NICK; }; |
if((AdNeutralRoll < 150 * 16) || (AdNeutralRoll > 850 * 16)) { VersionInfo.HardwareError[0] |= FC_ERROR0_GYRO_ROLL; }; |
if((AdNeutralGier < 150 * 2) || (AdNeutralGier > 850 * 2)) { VersionInfo.HardwareError[0] |= FC_ERROR0_GYRO_YAW; }; |
if((NeutralAccX < 300) || (NeutralAccX > 750)) { VersionInfo.HardwareError[0] |= FC_ERROR0_ACC_NICK; }; |
if((NeutralAccY < 300) || (NeutralAccY > 750)) { VersionInfo.HardwareError[0] |= FC_ERROR0_ACC_ROLL; }; |
if((NeutralAccZ < 512) || (NeutralAccZ > 850)) { VersionInfo.HardwareError[0] |= FC_ERROR0_ACC_TOP; }; |
if(VersionInfo.HardwareError[0]) sucess = 0; |
carefree_old = 70; |
#if (defined(__AVR_ATmega1284__) || defined(__AVR_ATmega1284P__)) |
LIBFC_HoTT_Clear(); |
ACC_AltitudeFusion(2); // initalisation |
#endif |
StartLuftdruck = Luftdruck; |
VarioMeter = 0; |
SummenHoehe = 0; Mess_Integral_Hoch = 0; |
DebugOut.Analog[28] = 0; // I2C-Counter |
CalcExpandBaroStep(); |
if(FC_StatusFlags3 & FC_STATUS3_BOAT && !EE_Parameter.Driftkomp) EE_Parameter.Driftkomp = 4; |
ShutterCounter = 0; |
/* |
//+++++++++++++++++++++++++++++++++++++++++++ |
//For testing the expandBaro at 30m |
ExpandBaro -= 1; |
OCR0A = DruckOffsetSetting - OPA_OFFSET_STEP * ExpandBaro; // increase offset to shift ADC down |
OCR0B = 255 - OCR0A; |
CalcExpandBaroStep(); |
//+++++++++++++++++++++++++++++++++++++++++++ |
*/ |
return(sucess); |
} |
//############################################################################ |
// Bearbeitet die Messwerte |
void Mittelwert(void) |
//############################################################################ |
{ |
static signed long tmpl,tmpl2,tmpl3,tmpl4; |
static signed int oldNick, oldRoll, d2Roll, d2Nick; |
signed long winkel_nick, winkel_roll; |
MesswertGier = (signed int) AdNeutralGier - AdWertGier; |
MesswertNick = (signed int) AdWertNickFilter / 8; |
MesswertRoll = (signed int) AdWertRollFilter / 8; |
RohMesswertNick = MesswertNick; |
RohMesswertRoll = MesswertRoll; |
// Beschleunigungssensor ++++++++++++++++++++++++++++++++++++++++++++++++ |
Mittelwert_AccNick = (Mittelwert_AccNick * 3 + ((ACC_AMPLIFY * AdWertAccNick))) / 4L; |
Mittelwert_AccRoll = (Mittelwert_AccRoll * 3 + ((ACC_AMPLIFY * AdWertAccRoll))) / 4L; |
NaviAccNick += AdWertAccNick; |
NaviAccRoll += AdWertAccRoll; |
NaviCntAcc++; |
//++++++++++++++++++++++++++++++++++++++++++++++++ |
HoehenWert = HoehenWert_Mess; |
#if (defined(__AVR_ATmega1284__) || defined(__AVR_ATmega1284P__)) |
HoehenWertF = HoehenWertF_Mess; |
#else |
HoehenWertF = HoehenWert; |
#endif |
//++++++++++++++++++++++++++++++++++++++++++++++++ |
// ADC einschalten |
ANALOG_ON; |
AdReady = 0; |
//++++++++++++++++++++++++++++++++++++++++++++++++ |
if(Mess_IntegralRoll > 93000L) winkel_roll = 93000L; |
else if(Mess_IntegralRoll <-93000L) winkel_roll = -93000L; |
else winkel_roll = Mess_IntegralRoll; |
if(Mess_IntegralNick > 93000L) winkel_nick = 93000L; |
else if(Mess_IntegralNick <-93000L) winkel_nick = -93000L; |
else winkel_nick = Mess_IntegralNick; |
// Gier ++++++++++++++++++++++++++++++++++++++++++++++++ |
Mess_Integral_Gier += MesswertGier; |
ErsatzKompass += MesswertGier; |
// Kopplungsanteil +++++++++++++++++++++++++++++++++++++ |
if(!Looping_Nick && !Looping_Roll)// && (Parameter_GlobalConfig & CFG_ACHSENKOPPLUNG_AKTIV)) |
{ |
tmpl3 = (MesswertRoll * winkel_nick) / 2048L; |
tmpl3 *= Parameter_AchsKopplung2; //65 |
tmpl3 /= 4096L; |
tmpl4 = (MesswertNick * winkel_roll) / 2048L; |
tmpl4 *= Parameter_AchsKopplung2; //65 |
tmpl4 /= 4096L; |
KopplungsteilNickRoll = tmpl3; |
KopplungsteilRollNick = tmpl4; |
tmpl4 -= tmpl3; |
ErsatzKompass += tmpl4; |
if(!Parameter_CouplingYawCorrection) Mess_Integral_Gier -= tmpl4/2; // Gier nachhelfen |
tmpl = ((MesswertGier + tmpl4) * winkel_nick) / 2048L; |
tmpl *= Parameter_AchsKopplung1; // 90 |
tmpl /= 4096L; |
tmpl2 = ((MesswertGier + tmpl4) * winkel_roll) / 2048L; |
tmpl2 *= Parameter_AchsKopplung1; |
tmpl2 /= 4096L; |
if(abs(MesswertGier) > 64) if(labs(tmpl) > 128 || labs(tmpl2) > 128) TrichterFlug = 1; |
//MesswertGier += (Parameter_CouplingYawCorrection * tmpl4) / 256; |
} |
else tmpl = tmpl2 = KopplungsteilNickRoll = KopplungsteilRollNick = 0; |
TrimRoll = tmpl - tmpl2 / 100L; |
TrimNick = -tmpl2 + tmpl / 100L; |
// Kompasswert begrenzen ++++++++++++++++++++++++++++++++++++++++++++++++ |
if(ErsatzKompass >= (360L * GIER_GRAD_FAKTOR)) ErsatzKompass -= 360L * GIER_GRAD_FAKTOR; // 360° Umschlag |
if(ErsatzKompass < 0) ErsatzKompass += 360L * GIER_GRAD_FAKTOR; |
// Roll ++++++++++++++++++++++++++++++++++++++++++++++++ |
Mess_IntegralRoll += MesswertRoll + TrimRoll - LageKorrekturRoll; |
if(Mess_IntegralRoll > Umschlag180Roll) |
{ |
Mess_IntegralRoll = -(Umschlag180Roll - 25000L); |
} |
if(Mess_IntegralRoll <-Umschlag180Roll) |
{ |
Mess_IntegralRoll = (Umschlag180Roll - 25000L); |
} |
// Nick ++++++++++++++++++++++++++++++++++++++++++++++++ |
Mess_IntegralNick += MesswertNick + TrimNick - LageKorrekturNick; |
if(Mess_IntegralNick > Umschlag180Nick) |
{ |
Mess_IntegralNick = -(Umschlag180Nick - 25000L); |
} |
if(Mess_IntegralNick <-Umschlag180Nick) |
{ |
Mess_IntegralNick = (Umschlag180Nick - 25000L); |
} |
Integral_Gier = Mess_Integral_Gier; |
IntegralNick = Mess_IntegralNick; |
IntegralRoll = Mess_IntegralRoll; |
#define D_LIMIT 128 |
MesswertNick = HiResNick / 8; |
MesswertRoll = HiResRoll / 8; |
if(AdWertNick < 15) MesswertNick = -1000; if(AdWertNick < 7) MesswertNick = -2000; |
// if(PlatinenVersion == 10) { if(AdWertNick > 1010) MesswertNick = +1000; if(AdWertNick > 1017) MesswertNick = +2000; } |
// else |
{ if(AdWertNick > 2000) MesswertNick = +1000; if(AdWertNick > 2015) MesswertNick = +2000; } |
if(AdWertRoll < 15) MesswertRoll = -1000; if(AdWertRoll < 7) MesswertRoll = -2000; |
// if(PlatinenVersion == 10) { if(AdWertRoll > 1010) MesswertRoll = +1000; if(AdWertRoll > 1017) MesswertRoll = +2000; } |
// else |
{ if(AdWertRoll > 2000) MesswertRoll = +1000; if(AdWertRoll > 2015) MesswertRoll = +2000; } |
if(Parameter_Gyro_D) |
{ |
d2Nick = HiResNick - oldNick; |
oldNick = (oldNick + HiResNick)/2; |
if(d2Nick > D_LIMIT) d2Nick = D_LIMIT; |
else if(d2Nick < -D_LIMIT) d2Nick = -D_LIMIT; |
d2Roll = HiResRoll - oldRoll; |
oldRoll = (oldRoll + HiResRoll)/2; |
if(d2Roll > D_LIMIT) d2Roll = D_LIMIT; |
else if(d2Roll < -D_LIMIT) d2Roll = -D_LIMIT; |
MesswertNick += (d2Nick * (signed int) Parameter_Gyro_D) / 16; |
MesswertRoll += (d2Roll * (signed int) Parameter_Gyro_D) / 16; |
HiResNick += (d2Nick * (signed int) Parameter_Gyro_D); |
HiResRoll += (d2Roll * (signed int) Parameter_Gyro_D); |
} |
if(RohMesswertRoll > 0) TrimRoll += ((long) abs(KopplungsteilNickRoll) * Parameter_CouplingYawCorrection) / 64L; |
else TrimRoll -= ((long) abs(KopplungsteilNickRoll) * Parameter_CouplingYawCorrection) / 64L; |
if(RohMesswertNick > 0) TrimNick += ((long) abs(KopplungsteilRollNick) * Parameter_CouplingYawCorrection) / 64L; |
else TrimNick -= ((long) abs(KopplungsteilRollNick) * Parameter_CouplingYawCorrection) / 64L; |
if(Parameter_GlobalConfig & CFG_DREHRATEN_BEGRENZER && !Looping_Nick && !Looping_Roll) |
{ |
if(RohMesswertNick > 256) MesswertNick += 1 * (RohMesswertNick - 256); |
else if(RohMesswertNick < -256) MesswertNick += 1 * (RohMesswertNick + 256); |
if(RohMesswertRoll > 256) MesswertRoll += 1 * (RohMesswertRoll - 256); |
else if(RohMesswertRoll < -256) MesswertRoll += 1 * (RohMesswertRoll + 256); |
} |
} |
//############################################################################ |
// Senden der Motorwerte per I2C-Bus |
void SendMotorData(void) |
//############################################################################ |
{ |
unsigned char i; |
if(!MotorenEin) |
{ |
FC_StatusFlags &= ~(FC_STATUS_MOTOR_RUN | FC_STATUS_FLY); |
FC_StatusFlags2 &= ~FC_STATUS2_WAIT_FOR_TAKEOFF; |
for(i=0;i<MAX_MOTORS;i++) |
{ |
if(!PC_MotortestActive) MotorTest[i] = 0; |
Motor[i].SetPoint = MotorTest[i]; |
Motor[i].SetPointLowerBits = 0; |
/* |
Motor[i].SetPoint = MotorTest[i] / 4; // testing the high resolution |
Motor[i].SetPointLowerBits = MotorTest[i] % 4; |
*/ |
} |
if(PC_MotortestActive) PC_MotortestActive--; |
} |
else FC_StatusFlags |= FC_STATUS_MOTOR_RUN; |
// ++++++++++++++++++++++++++++++++++++++++++ |
// ++++++++++++++++++++++++++++++++++++++++++ |
#ifdef REDUNDANT_FC_SLAVE |
I2CTimeout = 100; |
return; // don't send I2C-Data |
#endif |
#ifdef REDUNDANT_FC_MASTER |
if(Parameter_UserParam7 > 150) |
{ |
FC_StatusFlags3 |= FC_STATUS3_REDUNDANCE_TEST; |
// Make noise |
if((BeepMuster == 0xffff)) { beeptime = 25000; BeepMuster = 0x0080; } |
// Do not send I2C-Data |
if((FC_StatusFlags3 & FC_STATUS3_REDUNDANCE_AKTIVE) || !(FC_StatusFlags |= FC_STATUS_MOTOR_RUN)) |
{ |
I2CTimeout = 100; |
if(modell_fliegt != 0 && modell_fliegt < 100) modell_fliegt = 100; // ansonsten kann es vorkommen, dass die Master-FC auf Standgas bleibt |
return; // don't send I2C-Data |
} |
} |
#endif |
if(I2C_TransferActive) |
{ |
I2C_TransferActive = 0; // enable for the next time |
} |
else |
{ |
// motor_write = 0; |
I2C_Start(TWI_STATE_MOTOR_TX); //Start I2C Interrupt Mode |
} |
} |
unsigned char GetChannelValue(unsigned char ch) // gives the unsigned value of the channel |
{ |
int tmp2; |
if(ch == 0) return(0); |
tmp2 = PPM_in[ch] + 127; |
if(tmp2 > 255) tmp2 = 255; else if(tmp2 < 0) tmp2 = 0; |
return(tmp2); |
} |
//############################################################################ |
// Trägt ggf. das Poti als Parameter ein |
void ParameterZuordnung(void) |
//############################################################################ |
{ |
unsigned char tmp,i; |
for(i=0;i<8;i++) |
{ |
int tmp2; |
tmp = EE_Parameter.Kanalbelegung[K_POTI1 + i]; |
tmp2 = PPM_in[tmp] + 127; |
if(tmp2 > 255) tmp2 = 255; else if(tmp2 < 0) tmp2 = 0; |
if(tmp == 25) Poti[i] = tmp2; // 25 = WaypointEvent channel -> no filter |
else |
if(tmp2 != Poti[i]) |
{ |
Poti[i] += (tmp2 - Poti[i]) / 4; |
if(Poti[i] > tmp2) Poti[i]--; |
else Poti[i]++; |
} |
} |
CHK_POTI_MM(Parameter_Luftdruck_D,EE_Parameter.Luftdruck_D,0,100); |
CHK_POTI_MM(Parameter_Hoehe_P,EE_Parameter.Hoehe_P,0,100); |
CHK_POTI_MM(Parameter_Gyro_P,EE_Parameter.Gyro_P,10,255); |
CHK_POTI_MM(Parameter_J16Timing,EE_Parameter.J16Timing,5,255); |
CHK_POTI_MM(Parameter_J17Timing,EE_Parameter.J17Timing,5,255); |
if(EE_Parameter.Servo3 == 247) { if(PORTC & (1<<PORTC2)) Parameter_Servo3 = EE_Parameter.Servo3OnValue; else Parameter_Servo3 = EE_Parameter.Servo3OffValue;} // Out1 (J16) |
else if(EE_Parameter.Servo3 == 246) { if(PORTC & (1<<PORTC3)) Parameter_Servo3 = EE_Parameter.Servo3OnValue; else Parameter_Servo3 = EE_Parameter.Servo3OffValue;} |
else CHK_POTI_MM(Parameter_Servo3,EE_Parameter.Servo3, 24, 255); |
if(EE_Parameter.Servo4 == 247) { if(PORTC & (1<<PORTC2)) Parameter_Servo4 = EE_Parameter.Servo4OnValue; else Parameter_Servo4 = EE_Parameter.Servo4OffValue;} |
else if(EE_Parameter.Servo4 == 246) { if(PORTC & (1<<PORTC3)) Parameter_Servo4 = EE_Parameter.Servo4OnValue; else Parameter_Servo4 = EE_Parameter.Servo4OffValue;} // Out2 (J17) |
else CHK_POTI_MM(Parameter_Servo4,EE_Parameter.Servo4, 24, 255); |
CHK_POTI_MM(Parameter_Servo5,EE_Parameter.Servo5, 24, 255); |
Parameter_HoehenSchalter = GetChannelValue(EE_Parameter.HoeheChannel); |
CHK_POTI(Parameter_Hoehe_ACC_Wirkung,EE_Parameter.Hoehe_ACC_Wirkung); |
CHK_POTI(Parameter_Hoehe_TiltCompensation,EE_Parameter.Hoehe_TiltCompensation); |
CHK_POTI(Parameter_KompassWirkung,EE_Parameter.KompassWirkung); |
CHK_POTI(Parameter_Gyro_I,EE_Parameter.Gyro_I); |
CHK_POTI(Parameter_Gyro_D,EE_Parameter.Gyro_D); |
CHK_POTI(Parameter_Gyro_Gier_P,EE_Parameter.Gyro_Gier_P); |
CHK_POTI(Parameter_Gyro_Gier_I,EE_Parameter.Gyro_Gier_I); |
CHK_POTI(Parameter_I_Faktor,EE_Parameter.I_Faktor); |
CHK_POTI(Parameter_UserParam1,EE_Parameter.UserParam1); |
CHK_POTI(Parameter_UserParam2,EE_Parameter.UserParam2); |
CHK_POTI(Parameter_UserParam3,EE_Parameter.UserParam3); |
CHK_POTI(Parameter_UserParam4,EE_Parameter.UserParam4); |
CHK_POTI(Parameter_UserParam5,EE_Parameter.UserParam5); |
CHK_POTI(Parameter_UserParam6,EE_Parameter.UserParam6); |
CHK_POTI(Parameter_UserParam7,EE_Parameter.UserParam7); |
CHK_POTI(Parameter_UserParam8,EE_Parameter.UserParam8); |
CHK_POTI(Parameter_ServoNickControl,EE_Parameter.ServoNickControl); |
CHK_POTI(Parameter_ServoRollControl,EE_Parameter.ServoRollControl); |
CHK_POTI(Parameter_ServoNickComp,EE_Parameter.ServoNickComp); |
CHK_POTI(Parameter_ServoRollComp,EE_Parameter.ServoRollComp); |
CHK_POTI(Parameter_LoopGasLimit,EE_Parameter.LoopGasLimit); |
CHK_POTI(Parameter_AchsKopplung1,EE_Parameter.AchsKopplung1); |
CHK_POTI(Parameter_AchsKopplung2,EE_Parameter.AchsKopplung2); |
CHK_POTI(Parameter_CouplingYawCorrection,EE_Parameter.CouplingYawCorrection); |
CHK_POTI(Parameter_MaximumAltitude,EE_Parameter.MaxAltitude); |
// if((NC_To_FC_MaxAltitude && NC_To_FC_MaxAltitude < Parameter_MaximumAltitude) || Parameter_MaximumAltitude == 0) Parameter_MaximumAltitude = NC_To_FC_MaxAltitude; |
Parameter_GlobalConfig = EE_Parameter.GlobalConfig; |
Parameter_ExtraConfig = EE_Parameter.ExtraConfig; |
// CHK_POTI(Parameter_AchsGegenKopplung1,EE_Parameter.AchsGegenKopplung1,0,255); |
CHK_POTI(Parameter_DynamicStability,EE_Parameter.DynamicStability); |
CHK_POTI(Parameter_ExternalControl,EE_Parameter.ExternalControl); |
Ki = 10300 / (Parameter_I_Faktor + 1); |
MAX_GAS = EE_Parameter.Gas_Max; |
MIN_GAS = EE_Parameter.Gas_Min; |
if(EE_Parameter.CareFreeChannel) |
{ |
CareFree = 1; |
if(PPM_in[EE_Parameter.CareFreeChannel] < -64) CareFree = 0; |
// if(tmp >= 248 && Poti[255 - tmp] < 50) CareFree = 0; |
if(carefree_old != CareFree) |
{ |
if(carefree_old < 3) |
{ |
#if (defined(__AVR_ATmega1284__) || defined(__AVR_ATmega1284P__)) |
if(CareFree) { beeptime = 1500; if(!SpeakHoTT) SpeakHoTT = SPEAK_CF_ON; } |
else { beeptime = 200; if(!SpeakHoTT) SpeakHoTT = SPEAK_CF_OFF; } |
#else |
if(CareFree) beeptime = 1500; |
else beeptime = 200; |
#endif |
NeueKompassRichtungMerken = 5; |
carefree_old = CareFree; |
} else carefree_old--; |
} |
#ifndef REDUNDANT_FC_SLAVE |
if(FromNaviCtrl.CompassValue < 0 && CareFree) VersionInfo.HardwareError[0] |= FC_ERROR0_CAREFREE; //else VersionInfo.HardwareError[0] &= ~FC_ERROR0_CAREFREE; |
#endif |
} |
else |
{ |
CareFree = 0; |
carefree_old = 10; |
} |
if(FromNaviCtrl.CompassValue < 0 && MotorenEin && CareFree) // ungültiger Kompasswert |
{ |
if(BeepMuster == 0xffff) { beeptime = 15000; BeepMuster = 0xA400;}; |
CareFree = 0; |
} |
if(CareFree) { FC_StatusFlags2 |= FC_STATUS2_CAREFREE; } else FC_StatusFlags2 &= ~FC_STATUS2_CAREFREE; |
} |
void CalcStickGasHover(void) |
{ |
if(!EE_Parameter.Hoehe_StickNeutralPoint) |
{ |
StickGasHover = HoverGas/STICK_GAIN; // rescale back to stick value |
StickGasHover = (unsigned int)((unsigned int) StickGasHover * UBat) / BattLowVoltageWarning; |
} |
else StickGasHover = EE_Parameter.Hoehe_StickNeutralPoint; |
LIMIT_MIN_MAX(StickGasHover, 70, 175); // reserve some range for trim up and down |
} |
void ChannelAssingment(void) |
{ |
cli(); |
ChannelNick = PPM_in[EE_Parameter.Kanalbelegung[K_NICK]]; |
ChannelRoll = PPM_in[EE_Parameter.Kanalbelegung[K_ROLL]]; |
ChannelYaw = PPM_in[EE_Parameter.Kanalbelegung[K_GIER]]; |
ChannelGas = PPM_in[EE_Parameter.Kanalbelegung[K_GAS]]; |
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
//+ Analoge Steuerung per Seriell |
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
if((ExternalControl.Config & EC_VALID) && (Parameter_ExternalControl > 128)) |
{ |
ChannelNick += ExternalControl.Nick; |
ChannelRoll += ExternalControl.Roll; |
ChannelYaw += ExternalControl.Gier; |
if(ExternalControl.Config & EC_GAS_ADD) ChannelGas += ExternalControl.Gas; |
else |
{ |
if(ExternalControl.Gas < ChannelGas) ChannelGas = ExternalControl.Gas; // the RC-Stick is the MAX value here |
} |
} |
sei(); |
if(ChannelNick > 127) ChannelNick = 127; else if(ChannelNick < -127) ChannelNick = -127; |
if(ChannelRoll > 127) ChannelRoll = 127; else if(ChannelRoll < -127) ChannelRoll = -127; |
if(ChannelYaw > 127) ChannelYaw = 127; else if(ChannelYaw < -127) ChannelYaw = -127; |
if(ChannelGas > 127) ChannelGas = 127; else if(ChannelGas < -127) ChannelGas = -127; |
} |
//############################################################################ |
// |
void MotorRegler(void) |
//############################################################################ |
{ |
int pd_ergebnis_nick,pd_ergebnis_roll,tmp_int, tmp_int2; |
int GierMischanteil,GasMischanteil; |
static long sollGier = 0,tmp_long,tmp_long2; |
static unsigned int RcLostTimer, delay_Acc_neutral; |
static unsigned char delay_neutral = 0; |
static unsigned char delay_einschalten = 0,delay_ausschalten = 0; |
static signed char move_safety_switch = 0; |
int IntegralNickMalFaktor,IntegralRollMalFaktor; |
unsigned char i; |
Mittelwert(); |
// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
// Gaswert ermitteln |
// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
if(!(FC_StatusFlags & (FC_STATUS_EMERGENCY_LANDING | FC_STATUS2_RC_FAILSAVE_ACTIVE))) |
{ |
if(EE_Parameter.GlobalConfig3 & CFG3_VARIO_FAILSAFE) |
{ |
if(HoverGas && HoverGas < 150 * STICK_GAIN) |
{ |
HooverGasEmergencyPercent = (HoverGas/(STICK_GAIN) * EE_Parameter.NotGas) / 100; // i.e. 80% of Hovergas |
} |
else HooverGasEmergencyPercent = 45; // default if the Hoovergas was could not calculated yet |
} else HooverGasEmergencyPercent = EE_Parameter.NotGas; |
} |
if(GasIsZeroCnt == 30000) // in that case we have RC-Lost, but the MK is probably landed |
{ |
StickGas = 0; // Hold Gas down in that case |
// ExternalControl.Gas = 0; |
HooverGasEmergencyPercent = MIN_GAS; |
} |
GasMischanteil = StickGas; |
if(GasMischanteil < MIN_GAS + 10) GasMischanteil = MIN_GAS + 10; |
// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
// Empfang schlecht |
// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
if(SenderOkay < 100 && !(FC_StatusFlags2 & FC_STATUS2_RC_FAILSAVE_ACTIVE)) |
{ |
ServoFailsafeActive = SERVO_FS_TIME; |
if(RcLostTimer) RcLostTimer--; |
else |
{ |
MotorenEin = 0; |
modell_fliegt = 0; |
FC_StatusFlags &= ~(FC_STATUS_EMERGENCY_LANDING | FC_STATUS_FLY); |
} |
ROT_ON; |
if(modell_fliegt > 1000 && Capacity.MinOfMaxPWM > 100) // wahrscheinlich in der Luft --> langsam absenken |
{ |
GasMischanteil = HooverGasEmergencyPercent; |
FC_StatusFlags |= FC_STATUS_EMERGENCY_LANDING; |
} |
else |
{ |
MotorenEin = 0; |
} |
} |
else |
// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
// Emfang gut |
// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
if(SenderOkay > 140) |
{ |
#if (defined(__AVR_ATmega1284__) || defined(__AVR_ATmega1284P__)) |
static unsigned int trigger = 1000; |
static unsigned char old_switch = 100; |
if(EE_Parameter.StartLandChannel && EE_Parameter.LandingSpeed) |
{ |
if(PPM_in[EE_Parameter.StartLandChannel] > 50) |
{ |
if(old_switch == 50) if(FC_StatusFlags2 & FC_STATUS2_WAIT_FOR_TAKEOFF) { FC_StatusFlags2 |= FC_STATUS2_AUTO_STARTING; SpeakHoTT = SPEAK_RISING;} |
FC_StatusFlags2 &= ~FC_STATUS2_AUTO_LANDING; |
old_switch = 150; |
} |
else |
if(PPM_in[EE_Parameter.StartLandChannel] < -50) |
{ |
if(old_switch == 150) { FC_StatusFlags2 |= FC_STATUS2_AUTO_LANDING; SpeakHoTT = SPEAK_SINKING;} |
FC_StatusFlags2 &= ~FC_STATUS2_AUTO_STARTING; |
old_switch = 50; |
} |
else |
{ |
FC_StatusFlags2 &= ~(FC_STATUS2_AUTO_STARTING | FC_STATUS2_AUTO_LANDING); |
} |
} |
#endif |
FC_StatusFlags &= ~FC_STATUS_EMERGENCY_LANDING; |
RcLostTimer = EE_Parameter.NotGasZeit * 50; |
if(GasMischanteil > 40 && MotorenEin) |
{ |
if(modell_fliegt < 0xffff) modell_fliegt++; |
} |
if((modell_fliegt < 256)) |
{ |
SummeNick = 0; |
SummeRoll = 0; |
sollGier = 0; |
Mess_Integral_Gier = 0; |
FC_StatusFlags2 |= FC_STATUS2_WAIT_FOR_TAKEOFF; |
#if (defined(__AVR_ATmega1284__) || defined(__AVR_ATmega1284P__)) |
old_switch = 100; |
#endif |
} |
else |
{ |
FC_StatusFlags |= FC_STATUS_FLY; |
if(FC_StatusFlags2 & FC_STATUS2_WAIT_FOR_TAKEOFF) |
{ |
#if (defined(__AVR_ATmega1284__) || defined(__AVR_ATmega1284P__)) |
if((NC_To_FC_Flags & NC_TO_FC_AUTOSTART || FC_StatusFlags2 & FC_STATUS2_AUTO_STARTING) && (VarioCharacter == '=') && ACC_AltitudeControl) |
{ |
FromNC_AltitudeSpeed = 80; |
FromNC_AltitudeSetpoint = 500; |
SollHoehe = 500; |
trigger = 1000; |
if(NC_To_FC_Flags & NC_TO_FC_AUTOSTART) SpeakHoTT = SPEAK_NEXT_WP; |
/* if(StartTrigger != 2) |
{ |
StartTrigger = 1; |
if(HoverGas < STICK_GAIN * 35) HoverGas = STICK_GAIN * 35; |
} |
*/ |
} |
// else FC_StatusFlags2 &= ~(FC_STATUS2_AUTO_STARTING); |
#endif |
if(HoehenWertF > 150 || HoehenWert < -350 || !(Parameter_GlobalConfig & CFG_HOEHENREGELUNG)) |
{ |
#if (defined(__AVR_ATmega1284__) || defined(__AVR_ATmega1284P__)) |
trigger = 1000; |
if(FC_StatusFlags2 & FC_STATUS2_AUTO_STARTING) { FromNC_AltitudeSpeed = 0; SollHoehe = 300;/*HoehenWertF + 100;*/} |
else SpeakHoTT = SPEAK_RISING; |
#endif |
FC_StatusFlags2 &= ~(FC_STATUS2_WAIT_FOR_TAKEOFF | FC_STATUS2_AUTO_STARTING | FC_STATUS2_AUTO_LANDING); |
} |
SummeNick = 0; |
SummeRoll = 0; |
Mess_Integral_Gier = 0; |
// sollGier = 0; |
if(modell_fliegt > 1000) modell_fliegt = 1000; // for the Hooverpoint-Estimation |
} |
else // Flying mode |
{ |
#if (defined(__AVR_ATmega1284__) || defined(__AVR_ATmega1284P__)) |
if((FC_StatusFlags2 & FC_STATUS2_AUTO_LANDING) && (VarioCharacter == 'v' || VarioCharacter == '=') && ACC_AltitudeControl) |
{ |
FromNC_AltitudeSpeed = EE_Parameter.LandingSpeed; |
FromNC_AltitudeSetpoint = -20000; |
} |
if(trigger < 1000) |
{ |
trigger++; |
SummeNick = 0; |
SummeRoll = 0; |
Mess_Integral_Gier = 0; |
SollHoehe = HoehenWertF - 300; |
if(trigger == 1000 && FC_StatusFlags2 & FC_STATUS2_AUTO_LANDING && VarioCharacter != '+') |
{ |
FC_StatusFlags2 &= ~FC_STATUS2_AUTO_LANDING; |
FC_StatusFlags2 |= FC_STATUS2_WAIT_FOR_TAKEOFF; // go back into starting state |
} |
} |
else |
if(ACC_AltitudeControl && (VarioCharacter == 'v' || VarioCharacter == '-') && HoehenWert < 1000 /*&& FromNC_AltitudeSetpoint < 0*/) |
{ |
if((Aktuell_az/4 > EE_Parameter.LandingPulse) && (NeutralAccZ/4 > EE_Parameter.LandingPulse)) |
{ |
trigger = 0; |
SpeakHoTT = SPEAK_LANDING; |
}; |
} |
#endif |
} |
} // end of: modell_fliegt > 256 |
if((ChannelGas > 80) && MotorenEin == 0 && !(NC_To_FC_Flags & NC_TO_FC_SIMULATION_ACTIVE)) |
{ |
// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
// auf Nullwerte kalibrieren |
// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
if(ChannelYaw > 75) // Neutralwerte |
{ |
if(++delay_neutral > 200) // nicht sofort |
{ |
unsigned char setting = 0; |
delay_neutral = 0; |
modell_fliegt = 0; |
if(ChannelNick > 70 || abs(ChannelRoll) > 70) |
{ |
if(ChannelRoll > 70 && ChannelNick < 70 && ChannelNick > -70) setting = 1; |
if(ChannelRoll > 70 && ChannelNick > 70) setting = 2; |
if(ChannelRoll < 70 && ChannelNick > 70) setting = 3; |
if(ChannelRoll <-70 && ChannelNick > 70) setting = 4; |
if(ChannelRoll <-70 && ChannelNick < 70 && ChannelNick > -70) setting = 5; |
if(setting) SetActiveParamSet(setting); // aktiven Datensatz merken |
} |
if(abs(ChannelRoll) < 30 && ChannelNick < -70) |
{ |
WinkelOut.CalcState = 1; // Compass kalibrieren |
CalibrationDone = 0; |
beeptime = 1000; |
} |
else |
{ |
ParamSet_ReadFromEEProm(ActiveParamSet); |
LipoDetection(0); |
LIBFC_ReceiverInit(EE_Parameter.Receiver); |
if((Parameter_GlobalConfig & CFG_HOEHENREGELUNG)) // Höhenregelung aktiviert? |
{ |
if((MessLuftdruck > 950) || (MessLuftdruck < 750)) SucheLuftruckOffset(); |
} |
if(!setting && ChannelRoll < -70 && ChannelNick < 70) CalibrationDone = SetNeutral(3); // Boat-Mode |
// else |
// if(!setting && ChannelYaw < -75 && abs(ChannelNick) < 70) CalibrationDone = SetNeutral(2); // store ACC values into EEPROM |
else CalibrationDone = SetNeutral(1); |
ServoActive = 1; |
DDRD |=0x80; // enable J7 -> Servo signal |
#if (defined(__AVR_ATmega1284__) || defined(__AVR_ATmega1284P__)) |
if(VersionInfo.HardwareError[0]) SpeakHoTT = SPEAK_ERR_SENSOR; |
else |
if(!CalibrationDone) SpeakHoTT = SPEAK_ERR_CALIBARTION; |
else SpeakHoTT = SPEAK_CALIBRATE; |
ShowSettingNameTime = 10; // for HoTT & Jeti |
#endif |
Piep(ActiveParamSet,120); |
} |
} |
} |
else |
if(ChannelYaw < -75 && abs(ChannelRoll) < 16 && abs(ChannelRoll) < 16) // ACC calibrate |
{ |
if(++delay_Acc_neutral > 500 * 5) // 5 sekunden |
{ |
delay_Acc_neutral = 0; |
CalibrationDone = SetNeutral(2); // store ACC values into EEPROM |
ServoActive = 1; |
DDRD |=0x80; // enable J7 -> Servo signal |
#if (defined(__AVR_ATmega1284__) || defined(__AVR_ATmega1284P__)) |
if(VersionInfo.HardwareError[0]) SpeakHoTT = SPEAK_ERR_SENSOR; |
else |
if(!CalibrationDone) SpeakHoTT = SPEAK_ERR_CALIBARTION; |
else SpeakHoTT = SPEAK_CALIBRATE; |
ShowSettingNameTime = 10; // for HoTT & Jeti |
#endif |
Piep(ActiveParamSet,120); |
} |
} |
else { delay_neutral = 0; delay_Acc_neutral = 0;}; |
} |
// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
// Gas ist unten |
// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
if(ChannelGas < -100) |
{ |
if(PPM_diff[EE_Parameter.MotorSafetySwitch & 127] > 5) move_safety_switch = 100; |
else |
if(PPM_diff[EE_Parameter.MotorSafetySwitch & 127] < -5) move_safety_switch = -100; |
// Motoren Starten |
if(!MotorenEin) |
{ |
if(((((ChannelYaw < -100) && ((!(EE_Parameter.GlobalConfig3 & CFG3_MOTOR_SWITCH_MODE) && PPM_in[EE_Parameter.MotorSafetySwitch] < -75) || EE_Parameter.MotorSafetySwitch == 0))) |
|| (((EE_Parameter.GlobalConfig3 & CFG3_MOTOR_SWITCH_MODE) && PPM_in[EE_Parameter.MotorSafetySwitch] > -10 && move_safety_switch == 100))) |
&& !(NC_To_FC_Flags & NC_TO_FC_SIMULATION_ACTIVE)) |
{ |
// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
// Einschalten |
// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
if(CalibrationDone) FC_StatusFlags |= FC_STATUS_START; |
StartLuftdruck = Luftdruck; |
HoehenWert = 0; |
HoehenWert_Mess = 0; |
GasIsZeroCnt = 600; |
#if (defined(__AVR_ATmega1284__) || defined(__AVR_ATmega1284P__)) |
HoehenWertF_Mess = 0; |
#endif |
SummenHoehe = 0; |
if((ChannelNick > -100 || abs(ChannelRoll) < 100) && EE_Parameter.MotorSafetySwitch == 0) delay_einschalten = 0; |
if(++delay_einschalten > 253) |
{ |
if(FC_StatusFlags3 & FC_STATUS3_BOAT) { if((abs(MesswertGier) > 32*2 || abs(MesswertNick) > 20*3) || abs(MesswertRoll) > 20*3) CalibrationDone = 0; } // dann ist der Gyro defekt, schlecht kalibriert oder der MK dreht sich |
else |
if((abs(MesswertGier) > 32 || abs(MesswertNick) > 20) || abs(MesswertRoll) > 20) CalibrationDone = 0; // dann ist der Gyro defekt, schlecht kalibriert oder der MK dreht sich |
delay_einschalten = 0; |
if(!VersionInfo.HardwareError[0] && CalibrationDone && !NC_ErrorCode) |
{ |
modell_fliegt = 1; |
MotorenEin = 1; |
sollGier = 0; |
Mess_Integral_Gier = 0; |
Mess_Integral_Gier2 = 0; |
Mess_IntegralNick = EE_Parameter.GyroAccFaktor * (long)Mittelwert_AccNick; |
Mess_IntegralRoll = EE_Parameter.GyroAccFaktor * (long)Mittelwert_AccRoll; |
SummeNick = 0; |
SummeRoll = 0; |
// ControlHeading = (((int) EE_Parameter.OrientationAngle * 15 + KompassValue) % 360) / 2; |
NeueKompassRichtungMerken = 100; // 2 sekunden |
#if (defined(__AVR_ATmega1284__) || defined(__AVR_ATmega1284P__)) |
SpeakHoTT = SPEAK_STARTING; |
#endif |
} |
else |
{ |
beeptime = 1500; // indicate missing calibration |
#if (defined(__AVR_ATmega1284__) || defined(__AVR_ATmega1284P__)) |
if(!CalibrationDone) SpeakHoTT = SPEAK_ERR_CALIBARTION; |
#endif |
} |
} |
} |
else delay_einschalten = 0; |
} |
// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
// Auschalten |
// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
else // only if motors are running |
{ |
// if((PPM_in[EE_Parameter.Kanalbelegung[K_GIER]] > 75) && (PPM_in[EE_Parameter.MotorSafetySwitch] < -75 || EE_Parameter.MotorSafetySwitch == 0)) |
if((((ChannelYaw > 100) && ((!(EE_Parameter.GlobalConfig3 & CFG3_MOTOR_SWITCH_MODE) && PPM_in[EE_Parameter.MotorSafetySwitch] < -75) || EE_Parameter.MotorSafetySwitch == 0))) |
|| (((EE_Parameter.GlobalConfig3 & CFG3_MOTOR_SWITCH_MODE) && PPM_in[EE_Parameter.MotorSafetySwitch] < -50 && move_safety_switch == -100))) |
{ |
if((ChannelNick > -100 || abs(ChannelRoll) < 100) && EE_Parameter.MotorSafetySwitch == 0) |
{ |
delay_ausschalten = 0; |
} |
else |
{ |
SummeNick = 0; |
SummeRoll = 0; |
StickNick = 0; |
StickRoll = 0; |
} |
if(++delay_ausschalten > 250) // nicht sofort |
{ |
MotorenEin = 0; |
delay_ausschalten = 0; |
modell_fliegt = 0; |
FC_StatusFlags2 &= ~(FC_STATUS2_WAIT_FOR_TAKEOFF | FC_STATUS2_AUTO_STARTING | FC_STATUS2_AUTO_LANDING); |
#if (defined(__AVR_ATmega1284__) || defined(__AVR_ATmega1284P__)) |
SpeakHoTT = SPEAK_MK_OFF; |
#endif |
} |
else |
if(delay_ausschalten == 100) beeptime = 3500; |
} |
else delay_ausschalten = 0; |
} |
if(GasIsZeroCnt < 1000) |
{ |
if(VarioMeter > -150) GasIsZeroCnt++; |
else if(GasIsZeroCnt) GasIsZeroCnt--; |
} |
} |
else // gas not at minimum |
{ |
move_safety_switch = 0; |
GasIsZeroCnt = 0; |
} |
} |
else // Empfang zwischen 100 und 140 -> schlecht |
{ |
if(GasIsZeroCnt >= 750) // gas-stick was down for 1.5 seconds before RC-Lost |
{ |
if((GPSInfo.HomeDistance < 40 * 10) && (HoehenWert < 15 * 100)) // and we are at the starting point -> maybe landed? |
{ |
GasIsZeroCnt = 30000; |
if(modell_fliegt > 1001) modell_fliegt = 1001; |
} |
} |
} |
// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
// neue Werte von der Funke |
// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
if(!NewPpmData-- || (FC_StatusFlags & FC_STATUS_EMERGENCY_LANDING)) |
{ |
static int stick_nick,stick_roll; |
unsigned char stick_p; |
ParameterZuordnung(); |
ChannelAssingment(); |
stick_p = EE_Parameter.Stick_P; |
stick_nick = (stick_nick * 3 + ChannelNick * stick_p) / 4; |
stick_roll = (stick_roll * 3 + ChannelRoll * stick_p) / 4; |
cli(); |
stick_nick += PPM_diff[EE_Parameter.Kanalbelegung[K_NICK]] * EE_Parameter.Stick_D; |
stick_roll += PPM_diff[EE_Parameter.Kanalbelegung[K_ROLL]] * EE_Parameter.Stick_D; |
sei(); |
StickGas = ChannelGas + 127; |
// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
// CareFree und freie Wahl der vorderen Richtung |
// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
if(CareFree) |
{ |
signed int nick, roll; |
nick = stick_nick / 4; |
roll = stick_roll / 4; |
StickNick = ((FromNC_Rotate_C * nick) + (FromNC_Rotate_S * roll)) / (32 / 4); |
StickRoll = ((FromNC_Rotate_C * roll) - (FromNC_Rotate_S * nick)) / (32 / 4); |
} |
else |
{ |
FromNC_Rotate_C = sintab[EE_Parameter.OrientationAngle + 6]; |
FromNC_Rotate_S = sintab[EE_Parameter.OrientationAngle]; |
StickNick = ((FromNC_Rotate_C * stick_nick) + (FromNC_Rotate_S * stick_roll)) / 8; |
StickRoll = ((FromNC_Rotate_C * stick_roll) - (FromNC_Rotate_S * stick_nick)) / 8; |
} |
StickGier = -ChannelYaw; |
if(StickGier > 4) StickGier -= 4; else |
if(StickGier < -4) StickGier += 4; else StickGier = 0; |
if(GasIsZeroCnt > 512) // About to switch - off |
{ |
StickNick = StickNick/8; |
StickRoll = StickRoll/8; |
SummeNick = 0; |
SummeRoll = 0; |
} |
else |
if(GPS_Aid_StickMultiplikator) // in that case the GPS controls stronger |
{ |
StickNick = (GPS_Aid_StickMultiplikator * (StickNick / 8)) / 16; |
StickRoll = (GPS_Aid_StickMultiplikator * (StickRoll / 8)) / 16; |
} |
StickNick -= GPS_Nick; |
StickRoll -= GPS_Roll; |
GyroFaktor = (Parameter_Gyro_P + 10.0); |
IntegralFaktor = Parameter_Gyro_I; |
GyroFaktorGier = (Parameter_Gyro_Gier_P + 10.0); |
IntegralFaktorGier = Parameter_Gyro_Gier_I; |
if(Parameter_GlobalConfig & CFG_HEADING_HOLD) IntegralFaktor = 0; |
if(abs(StickNick/STICK_GAIN) > MaxStickNick) |
{ |
MaxStickNick = abs(StickNick)/STICK_GAIN; |
if(MaxStickNick > 100) MaxStickNick = 100; |
} |
else MaxStickNick--; |
if(abs(StickRoll/STICK_GAIN) > MaxStickRoll) |
{ |
MaxStickRoll = abs(StickRoll)/STICK_GAIN; |
if(MaxStickRoll > 100) MaxStickRoll = 100; |
} |
else MaxStickRoll--; |
if(FC_StatusFlags & FC_STATUS_EMERGENCY_LANDING) {MaxStickNick = 0; MaxStickRoll = 0;} |
// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
// Looping? |
// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
if((PPM_in[EE_Parameter.Kanalbelegung[K_ROLL]] > EE_Parameter.LoopThreshold) && EE_Parameter.BitConfig & CFG_LOOP_LINKS) Looping_Links = 1; |
else |
{ |
{ |
if((PPM_in[EE_Parameter.Kanalbelegung[K_ROLL]] < (EE_Parameter.LoopThreshold - EE_Parameter.LoopHysterese))) Looping_Links = 0; |
} |
} |
if((PPM_in[EE_Parameter.Kanalbelegung[K_ROLL]] < -EE_Parameter.LoopThreshold) && EE_Parameter.BitConfig & CFG_LOOP_RECHTS) Looping_Rechts = 1; |
else |
{ |
if(Looping_Rechts) // Hysterese |
{ |
if(PPM_in[EE_Parameter.Kanalbelegung[K_ROLL]] > -(EE_Parameter.LoopThreshold - EE_Parameter.LoopHysterese)) Looping_Rechts = 0; |
} |
} |
if((PPM_in[EE_Parameter.Kanalbelegung[K_NICK]] > EE_Parameter.LoopThreshold) && EE_Parameter.BitConfig & CFG_LOOP_OBEN) Looping_Oben = 1; |
else |
{ |
if(Looping_Oben) // Hysterese |
{ |
if((PPM_in[EE_Parameter.Kanalbelegung[K_NICK]] < (EE_Parameter.LoopThreshold - EE_Parameter.LoopHysterese))) Looping_Oben = 0; |
} |
} |
if((PPM_in[EE_Parameter.Kanalbelegung[K_NICK]] < -EE_Parameter.LoopThreshold) && EE_Parameter.BitConfig & CFG_LOOP_UNTEN) Looping_Unten = 1; |
else |
{ |
if(Looping_Unten) // Hysterese |
{ |
if(PPM_in[EE_Parameter.Kanalbelegung[K_NICK]] > -(EE_Parameter.LoopThreshold - EE_Parameter.LoopHysterese)) Looping_Unten = 0; |
} |
} |
if(Looping_Links || Looping_Rechts) Looping_Roll = 1; else Looping_Roll = 0; |
if(Looping_Oben || Looping_Unten) { Looping_Nick = 1; Looping_Roll = 0; Looping_Links = 0; Looping_Rechts = 0;} else Looping_Nick = 0; |
} // Ende neue Funken-Werte |
if(Looping_Roll || Looping_Nick) |
{ |
if(GasMischanteil > EE_Parameter.LoopGasLimit) GasMischanteil = EE_Parameter.LoopGasLimit; |
TrichterFlug = 1; |
} |
// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
// Bei Empfangsausfall im Flug |
// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
if(FC_StatusFlags2 & FC_STATUS2_RC_FAILSAVE_ACTIVE) |
{ |
StickNick = -GPS_Nick; |
StickRoll = -GPS_Roll; |
StickGas = StickGasHover; |
StickGier = 0; |
Parameter_GlobalConfig &= ~(CFG_HEADING_HOLD | CFG_DREHRATEN_BEGRENZER); |
Parameter_GlobalConfig |= CFG_HOEHENREGELUNG | CFG_ACHSENKOPPLUNG_AKTIV | CFG_KOMPASS_AKTIV | CFG_GPS_AKTIV | CFG_HOEHEN_SCHALTER | CFG_GPS_AKTIV; |
Parameter_ExtraConfig &= ~(CFG2_HEIGHT_LIMIT | CFG_LEARNABLE_CAREFREE | CFG2_VARIO_BEEP); |
Parameter_HoehenSchalter = 200; // switch on |
} |
else |
if(FC_StatusFlags & FC_STATUS_EMERGENCY_LANDING) |
{ |
StickGier = 0; |
StickNick = 0; |
StickRoll = 0; |
GyroFaktor = 90; |
IntegralFaktor = 120; |
GyroFaktorGier = 90; |
IntegralFaktorGier = 120; |
Looping_Roll = 0; |
Looping_Nick = 0; |
} |
// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
// Integrale auf ACC-Signal abgleichen |
// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
#define ABGLEICH_ANZAHL 256L |
MittelIntegralNick += IntegralNick; // Für die Mittelwertbildung aufsummieren |
MittelIntegralRoll += IntegralRoll; |
if(Looping_Nick || Looping_Roll) |
{ |
MittelIntegralNick = 0; |
MittelIntegralRoll = 0; |
ZaehlMessungen = 0; |
LageKorrekturNick = 0; |
LageKorrekturRoll = 0; |
} |
// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
if(!Looping_Nick && !Looping_Roll && (Aktuell_az > 512 || MotorenEin)) |
{ |
long tmp_long, tmp_long2; |
if(FromNaviCtrl_Value.Kalman_K > 0 /*&& !TrichterFlug*/) |
{ |
tmp_long = (long)(IntegralNick / EE_Parameter.GyroAccFaktor - (long)(Mittelwert_AccNick - FromNaviCtrl.AccErrorN)); |
tmp_long2 = (long)(IntegralRoll / EE_Parameter.GyroAccFaktor - (long)(Mittelwert_AccRoll - FromNaviCtrl.AccErrorR)); |
tmp_long = (tmp_long * FromNaviCtrl_Value.Kalman_K) / (32 * 16); |
tmp_long2 = (tmp_long2 * FromNaviCtrl_Value.Kalman_K) / (32 * 16); |
if((MaxStickNick > 64) || (MaxStickRoll > 64)) |
{ |
tmp_long /= 2; |
tmp_long2 /= 2; |
} |
if(tmp_long > (long) FromNaviCtrl_Value.Kalman_MaxFusion) tmp_long = (long) FromNaviCtrl_Value.Kalman_MaxFusion; |
if(tmp_long < (long)-FromNaviCtrl_Value.Kalman_MaxFusion) tmp_long = (long)-FromNaviCtrl_Value.Kalman_MaxFusion; |
if(tmp_long2 > (long) FromNaviCtrl_Value.Kalman_MaxFusion) tmp_long2 = (long) FromNaviCtrl_Value.Kalman_MaxFusion; |
if(tmp_long2 < (long)-FromNaviCtrl_Value.Kalman_MaxFusion) tmp_long2 = (long)-FromNaviCtrl_Value.Kalman_MaxFusion; |
} |
else |
{ |
tmp_long = (long)(IntegralNick / EE_Parameter.GyroAccFaktor - (long)Mittelwert_AccNick); |
tmp_long2 = (long)(IntegralRoll / EE_Parameter.GyroAccFaktor - (long)Mittelwert_AccRoll); |
tmp_long /= 16; |
tmp_long2 /= 16; |
if((MaxStickNick > 64) || (MaxStickRoll > 64)) |
{ |
tmp_long /= 3; |
tmp_long2 /= 3; |
} |
if(abs(ChannelYaw) > 25) |
{ |
tmp_long /= 3; |
tmp_long2 /= 3; |
} |
KompassFusion = 25; |
#define AUSGLEICH 32 |
if(tmp_long > AUSGLEICH) tmp_long = AUSGLEICH; |
if(tmp_long < -AUSGLEICH) tmp_long =-AUSGLEICH; |
if(tmp_long2 > AUSGLEICH) tmp_long2 = AUSGLEICH; |
if(tmp_long2 <-AUSGLEICH) tmp_long2 =-AUSGLEICH; |
} |
Mess_IntegralNick -= tmp_long; |
Mess_IntegralRoll -= tmp_long2; |
DriftNick += tmp_long; |
DriftRoll += tmp_long2; |
} |
// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
if(ZaehlMessungen >= ABGLEICH_ANZAHL) //alle 512ms |
{ |
// static int cnt = 0; |
// static char last_n_p,last_n_n,last_r_p,last_r_n; |
static long MittelIntegralNick_Alt,MittelIntegralRoll_Alt; |
// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
// Gyro-Drift ermitteln |
// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
if(EE_Parameter.Driftkomp && abs(Mittelwert_AccNick) < 200*4 && abs(Mittelwert_AccRoll) < 200*4 && !TrichterFlug && abs(MesswertGier) < 32/* && (FC_StatusFlags & FC_STATUS_FLY)*/) |
{ |
DriftNick -= DriftNick / (64 * (unsigned int) EE_Parameter.Driftkomp); |
DriftRoll -= DriftRoll / (64 * (unsigned int) EE_Parameter.Driftkomp); |
GierGyroFehler -= GierGyroFehler / (64 * (unsigned int) EE_Parameter.Driftkomp); |
if((MaxStickNick > 64) || (MaxStickRoll > 64) || (abs(ChannelYaw) > 25)) |
{ |
DriftNick /= 2; |
DriftRoll /= 2; |
GierGyroFehler = 0; |
} |
if(DriftNick > 3000) { DriftNick = 0; AdNeutralNick++;} |
if(DriftNick <-3000) { DriftNick = 0; AdNeutralNick--;} |
if(DriftRoll > 3000) { DriftRoll = 0; AdNeutralRoll++;} |
if(DriftRoll <-3000) { DriftRoll = 0; AdNeutralRoll--;} |
if(GierGyroFehler > 3500) { GierGyroFehler = 0; AdNeutralGier++; } |
if(GierGyroFehler <-3500) { GierGyroFehler = 0; AdNeutralGier--; } |
} |
else |
{ |
DriftNick = 0; |
DriftRoll = 0; |
GierGyroFehler = 0; |
} |
TrichterFlug = 0; |
if(!IntegralFaktor) { LageKorrekturRoll = 0; LageKorrekturNick = 0;} // z.B. bei HH |
// +++++++++++++++++++++++++++++++++++++++++++++++++++++ |
MittelIntegralNick_Alt = MittelIntegralNick; |
MittelIntegralRoll_Alt = MittelIntegralRoll; |
// +++++++++++++++++++++++++++++++++++++++++++++++++++++ |
MittelIntegralNick = 0; |
MittelIntegralRoll = 0; |
ZaehlMessungen = 0; |
} // ZaehlMessungen >= ABGLEICH_ANZAHL |
// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
// Gieren |
// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
if(abs(StickGier) > 3) // war 15 |
{ |
// KompassSignalSchlecht = 1000; |
if(!(Parameter_GlobalConfig & CFG_KOMPASS_FIX)) |
{ |
NeueKompassRichtungMerken = 50; // eine Sekunde zum Einloggen |
}; |
} |
tmp_int = (long) EE_Parameter.StickGier_P * ((long)StickGier * abs(StickGier)) / 512L; // expo y = ax + bx² |
tmp_int += (EE_Parameter.StickGier_P * StickGier) / 4; |
if(GasIsZeroCnt > 512) tmp_int = 0; // disable Yawing when Gas-Stick is to Zero |
tmp_int += CompassGierSetpoint; |
sollGier = tmp_int; |
Mess_Integral_Gier -= tmp_int; |
if(Mess_Integral_Gier > 50000) Mess_Integral_Gier = 50000; // begrenzen |
if(Mess_Integral_Gier <-50000) Mess_Integral_Gier =-50000; |
// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
// Kompass |
// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
if(KompassValue >= 0 && (Parameter_GlobalConfig & CFG_KOMPASS_AKTIV)) |
{ |
if(CalculateCompassTimer-- == 1) |
{ |
int w,v,r,fehler,korrektur; // wird von der SPI-Routine auf 1 gesetzt |
CalculateCompassTimer = 13; // falls keine Navi-Daten |
// max. Korrekturwert schätzen |
w = abs(IntegralNick /512); // mit zunehmender Neigung den Einfluss drosseln |
v = abs(IntegralRoll /512); |
if(v > w) w = v; // grösste Neigung ermitteln |
// korrektur = w / 4 + 1; |
korrektur = w / 8 + 2; |
ErsatzKompassInGrad = ErsatzKompass/GIER_GRAD_FAKTOR; |
// Kompassfehlerwert bestimmen |
fehler = ((540 + KompassValue - ErsatzKompassInGrad) % 360) - 180; |
// GIER_GRAD_FAKTOR ist ca. 1200 |
// Kompasswert einloggen |
if(NeueKompassRichtungMerken) KompassSollWert = ErsatzKompassInGrad; |
if(KompassSignalSchlecht) KompassSignalSchlecht--; |
else |
if(w < 25) |
{ |
GierGyroFehler += fehler; |
if(NeueKompassRichtungMerken) NeueKompassRichtungMerken--; |
} |
// Kompass fusionieren |
if(!KompassSignalSchlecht) ErsatzKompass += (fehler * KompassFusion) / korrektur; |
// MK Gieren |
if(!NeueKompassRichtungMerken) |
{ |
r = ((540 + (KompassSollWert - ErsatzKompassInGrad)) % 360) - 180; |
v = r * (Parameter_KompassWirkung/2); // nach Kompass ausrichten |
CompassGierSetpoint = v / 16; |
} |
else CompassGierSetpoint = 0; |
} // CalculateCompassTimer |
} |
else CompassGierSetpoint = 0; |
//DebugOut.Analog[16] = KompassFusion; |
// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
// Drehgeschwindigkeit und -winkel zu einem Istwert zusammenfassen |
// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
if(TrichterFlug) { SummeRoll = 0; SummeNick = 0;}; |
if(!Looping_Nick) IntegralNickMalFaktor = (IntegralNick * IntegralFaktor) / (44000 / STICK_GAIN); else IntegralNickMalFaktor = 0; |
if(!Looping_Roll) IntegralRollMalFaktor = (IntegralRoll * IntegralFaktor) / (44000 / STICK_GAIN); else IntegralRollMalFaktor = 0; |
#define TRIM_MAX 200 |
if(TrimNick > TRIM_MAX) TrimNick = TRIM_MAX; else if(TrimNick <-TRIM_MAX) TrimNick =-TRIM_MAX; |
if(TrimRoll > TRIM_MAX) TrimRoll = TRIM_MAX; else if(TrimRoll <-TRIM_MAX) TrimRoll =-TRIM_MAX; |
MesswertNick = IntegralNickMalFaktor + (long)((long)MesswertNick * GyroFaktor + (long)TrimNick * 128L) / (256L / STICK_GAIN); |
MesswertRoll = IntegralRollMalFaktor + (long)((long)MesswertRoll * GyroFaktor + (long)TrimRoll * 128L) / (256L / STICK_GAIN); |
MesswertGier = (long)(MesswertGier * 2 * (long)GyroFaktorGier) / (256L / STICK_GAIN) + (long)(Integral_Gier * IntegralFaktorGier) / (2 * (44000 / STICK_GAIN)); |
// Maximalwerte abfangen |
#define MAX_SENSOR (4096) |
if(MesswertNick > MAX_SENSOR) MesswertNick = MAX_SENSOR; |
if(MesswertNick < -MAX_SENSOR) MesswertNick = -MAX_SENSOR; |
if(MesswertRoll > MAX_SENSOR) MesswertRoll = MAX_SENSOR; |
if(MesswertRoll < -MAX_SENSOR) MesswertRoll = -MAX_SENSOR; |
if(MesswertGier > MAX_SENSOR) MesswertGier = MAX_SENSOR; |
if(MesswertGier < -MAX_SENSOR) MesswertGier = -MAX_SENSOR; |
// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
// Undervoltage |
// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
if(!(FC_StatusFlags & FC_STATUS_LOWBAT)) |
{ |
GasMischanteil = ((unsigned int)GasMischanteil * BattLowVoltageWarning) / UBat; // Gas auf das aktuelle Spannungvieveau beziehen |
} |
// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
// Auto-Landing |
// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
static unsigned char slower; |
if(!slower--) |
{ |
static unsigned int u_filter = 0; |
if(!u_filter) u_filter = UBat; |
if(UBat > u_filter) u_filter++; else |
if(UBat < u_filter) u_filter--; |
slower = 100; // 5Hz |
if(u_filter < BattAutoLandingVoltage) |
{ |
LowVoltageLandingActive = 10; // 2 sek |
ServoFailsafeActive = SERVO_FS_TIME; |
} |
else if(u_filter > BattAutoLandingVoltage + LipoCells && LowVoltageLandingActive) LowVoltageLandingActive--; |
if(u_filter < BattComingHomeVoltage) |
{ |
LowVoltageHomeActive = 25; // min. 5 sek |
} |
else if(u_filter > BattComingHomeVoltage + LipoCells && LowVoltageHomeActive) LowVoltageHomeActive--; |
} |
if(LowVoltageLandingActive && FromNC_AltitudeSetpoint >= 0) |
{ |
FromNC_AltitudeSpeed = EE_Parameter.LandingSpeed; |
if(HoehenWert > 15*100) FromNC_AltitudeSpeed *= 2; // faster above 15m |
FromNC_AltitudeSetpoint = -20000; |
} |
// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
// send SPI pending bytes |
if(BytegapSPI == 0) SPI_TransmitByte(); |
// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
// Höhenregelung |
// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
GasMischanteil *= STICK_GAIN; |
// if height control is activated |
if((Parameter_GlobalConfig & CFG_HOEHENREGELUNG) && !(Looping_Roll || Looping_Nick) && !(VersionInfo.HardwareError[0] & 0x7F)) // Höhenregelung |
{ |
#define HOVER_GAS_AVERAGE 16384L // 16384 * 2ms = 32s averaging |
#define HC_GAS_AVERAGE 4 // 4 * 2ms= 8ms averaging |
int HCGas, GasReduction = 0; |
static int HeightTrimming = 0; // rate for change of height setpoint |
static int HeightDeviation = 0, FilterHCGas = 0; |
static unsigned long HoverGasFilter = 0; |
static unsigned char delay = 100, BaroAtUpperLimit = 0, BaroAtLowerLimit = 0; |
// Expand the measurement |
// measurement of air pressure close to upper limit and no overflow in correction of the new OCR0A value occurs |
if(!BaroExpandActive) |
{ |
if(MessLuftdruck > 920) |
{ // increase offset |
if(OCR0A < (255 - OPA_OFFSET_STEP)) |
{ |
ExpandBaro -= 1; |
OCR0A = DruckOffsetSetting - OPA_OFFSET_STEP * ExpandBaro; // increase offset to shift ADC down |
OCR0B = 255 - OCR0A; |
beeptime = 300; |
#if (defined(__AVR_ATmega1284__) || defined(__AVR_ATmega1284P__)) |
if(ACC_AltitudeControl) BaroExpandActive = 50; |
else |
#endif |
BaroExpandActive = 350; |
CalcExpandBaroStep(); |
} |
else |
{ |
BaroAtLowerLimit = 1; |
} |
} |
// measurement of air pressure close to lower limit and |
else |
if(MessLuftdruck < 100) |
{ // decrease offset |
if(OCR0A > OPA_OFFSET_STEP) |
{ |
ExpandBaro += 1; |
OCR0A = DruckOffsetSetting - OPA_OFFSET_STEP * ExpandBaro; // decrease offset to shift ADC up |
OCR0B = 255 - OCR0A; |
beeptime = 300; |
#if (defined(__AVR_ATmega1284__) || defined(__AVR_ATmega1284P__)) |
if(ACC_AltitudeControl) BaroExpandActive = 50; |
else |
#endif |
BaroExpandActive = 350; |
CalcExpandBaroStep(); |
} |
else |
{ |
BaroAtUpperLimit = 1; |
} |
} |
else |
{ |
BaroAtUpperLimit = 0; |
BaroAtLowerLimit = 0; |
} |
} |
else // delay, because of expanding the Baro-Range |
{ |
// now clear the D-values |
VarioMeter = 0; |
cli(); |
#if (defined(__AVR_ATmega1284__) || defined(__AVR_ATmega1284P__)) |
if(ACC_AltitudeControl) ACC_AltitudeFusion(1); // init |
else SummenHoehe = HoehenWert * SM_FILTER; |
#else |
SummenHoehe = HoehenWert * SM_FILTER; |
#endif |
sei(); |
BaroExpandActive--; |
} |
// if height control is activated by an rc channel |
if(Parameter_GlobalConfig & CFG_HOEHEN_SCHALTER) // Regler wird über Schalter gesteuert |
{ // check if parameter is less than activation threshold |
if(Parameter_HoehenSchalter < 50) // for 3 or 2-state switch height control is disabled in lowest position |
{ //height control not active |
if(!delay--) |
{ |
#if (defined(__AVR_ATmega1284__) || defined(__AVR_ATmega1284P__)) |
if(!SpeakHoTT && HoehenReglerAktiv) SpeakHoTT = SPEAK_ALTITUDE_OFF; |
#endif |
HoehenReglerAktiv = 0; // disable height control |
SollHoehe = HoehenWert; // update SetPoint with current reading |
delay = 1; |
} |
} |
else |
if(Parameter_HoehenSchalter > 70) |
{ //height control is activated |
#if (defined(__AVR_ATmega1284__) || defined(__AVR_ATmega1284P__)) |
if(!SpeakHoTT && !HoehenReglerAktiv) SpeakHoTT = SPEAK_ALTITUDE_ON; |
#endif |
delay = 200; |
HoehenReglerAktiv = 1; // enable height control |
} |
} |
else // no switchable height control |
{ |
SollHoehe = (/*(int16_t) ExternHoehenValue + */(int16_t) Parameter_HoehenSchalter) * (int)EE_Parameter.Hoehe_Verstaerkung; |
HoehenReglerAktiv = 1; |
} |
// calculate cos of nick and roll angle used for projection of the vertical hoover gas |
tmp_int = (int)(IntegralNick/GIER_GRAD_FAKTOR); // nick angle in deg |
tmp_int2 = (int)(IntegralRoll/GIER_GRAD_FAKTOR); // roll angle in deg |
tmp_int = (int16_t)ihypot(tmp_int, tmp_int2); // phytagoras gives effective attitude angle in deg |
tmp_int = (tmp_int * Parameter_Hoehe_TiltCompensation) / 100; |
LIMIT_MAX(tmp_int, 60); // limit effective attitude angle |
CosAttitude = c_cos_8192(tmp_int); // cos of actual attitude |
VarioCharacter = ' '; |
AltitudeSetpointTrimming = 0; |
if(HoehenReglerAktiv && !(FC_StatusFlags & FC_STATUS_EMERGENCY_LANDING)) |
{ |
// Holger original version |
// start of height control algorithm |
// the height control is only an attenuation of the actual gas stick. |
// I.e. it will work only if the gas stick is higher than the hover gas |
// and the hover height will be allways larger than height setpoint. |
FC_StatusFlags2 |= FC_STATUS2_ALTITUDE_CONTROL; |
if((Parameter_ExtraConfig & CFG2_HEIGHT_LIMIT) || !(Parameter_GlobalConfig & CFG_HOEHEN_SCHALTER)) // Regler wird über Schalter gesteuert) |
{ // old version |
HCGas = GasMischanteil; // take current stick gas as neutral point for the height control |
HeightTrimming = 0; |
AltitudeSetpointTrimming = 0; |
// set both flags to indicate no vario mode |
FC_StatusFlags |= (FC_STATUS_VARIO_TRIM_UP|FC_STATUS_VARIO_TRIM_DOWN); |
} |
else |
{ |
// alternative height control |
// PD-Control with respect to hoover point |
// the thrust loss out of horizontal attitude is compensated |
// the setpoint will be fine adjusted with the gas stick position |
if(/*1 || */FC_StatusFlags & FC_STATUS_FLY) // trim setpoint only when flying |
{ // gas stick is above hoover point |
if(StickGas > (StickGasHover + HEIGHT_CONTROL_STICKTHRESHOLD) && !BaroAtUpperLimit) |
{ |
if(FC_StatusFlags & FC_STATUS_VARIO_TRIM_DOWN) |
{ |
FC_StatusFlags &= ~FC_STATUS_VARIO_TRIM_DOWN; |
SollHoehe = HoehenWertF; // update setpoint to current heigth |
} |
// Limit the maximum Altitude |
if(Parameter_MaximumAltitude && (SollHoehe/100 > Parameter_MaximumAltitude)) |
{ |
AltitudeSetpointTrimming = 0; |
#if (defined(__AVR_ATmega1284__) || defined(__AVR_ATmega1284P__)) |
if(!SpeakHoTT && HoehenWert/95 > Parameter_MaximumAltitude) SpeakHoTT = SPEAK_MAX_ALTITUD; |
#endif |
VarioCharacter = '='; |
} |
else |
{ |
if(HeightDeviation > 20) SollHoehe = HoehenWertF; // update setpoint to current heigth |
FC_StatusFlags |= FC_STATUS_VARIO_TRIM_UP; |
AltitudeSetpointTrimming = abs(StickGas - (StickGasHover + HEIGHT_CONTROL_STICKTHRESHOLD)); |
if(LowVoltageLandingActive) AltitudeSetpointTrimming /= 3; // only 33% rising |
VarioCharacter = '+'; |
} |
WaypointTrimming = 0; |
} // gas stick is below hoover point |
else if(StickGas < (StickGasHover - HEIGHT_CONTROL_STICKTHRESHOLD) && !BaroAtLowerLimit ) // Minus |
{ |
if(FC_StatusFlags & FC_STATUS_VARIO_TRIM_UP || (HeightDeviation < -300)) |
{ |
FC_StatusFlags &= ~FC_STATUS_VARIO_TRIM_UP; |
SollHoehe = HoehenWertF; // update setpoint to current heigth |
} |
FC_StatusFlags |= FC_STATUS_VARIO_TRIM_DOWN; |
AltitudeSetpointTrimming = -abs(StickGas - (StickGasHover - HEIGHT_CONTROL_STICKTHRESHOLD)); |
VarioCharacter = '-'; |
WaypointTrimming = 0; |
} |
else // Gas Stick in Hover Range |
{ |
VarioCharacter = '='; |
if(FromNC_AltitudeSpeed && FromNC_AltitudeSetpoint > SollHoehe) // von NC gesteuert -> Steigen |
{ |
FC_StatusFlags |= FC_STATUS_VARIO_TRIM_UP; |
AltitudeSetpointTrimming = FromNC_AltitudeSpeed; |
//HeightTrimming += FromNC_AltitudeSpeed; |
WaypointTrimming = 10; |
VarioCharacter = '^'; |
if(FC_StatusFlags & FC_STATUS_VARIO_TRIM_DOWN) // changed from sinking to rising |
{ |
FC_StatusFlags &= ~FC_STATUS_VARIO_TRIM_DOWN; |
SollHoehe = HoehenWertF; // update setpoint to current heigth |
} |
} |
else |
if(FromNC_AltitudeSpeed && FromNC_AltitudeSetpoint < SollHoehe) // von NC gesteuert -> sinken |
{ |
FC_StatusFlags |= FC_STATUS_VARIO_TRIM_DOWN; |
AltitudeSetpointTrimming = -FromNC_AltitudeSpeed; |
//HeightTrimming -= FromNC_AltitudeSpeed; |
WaypointTrimming = -10; |
VarioCharacter = 'v'; |
if(FC_StatusFlags & FC_STATUS_VARIO_TRIM_UP) // changed from rising to sinking |
{ |
FC_StatusFlags &= ~FC_STATUS_VARIO_TRIM_UP; |
SollHoehe = HoehenWertF; // update setpoint to current heigth |
} |
} |
else |
if(FC_StatusFlags & (FC_STATUS_VARIO_TRIM_UP|FC_STATUS_VARIO_TRIM_DOWN)) |
{ |
if(!WaypointTrimming) LIMIT_MIN_MAX(SollHoehe, (HoehenWertF-200), (HoehenWertF+200)) // max. 2m Unterschied |
else WaypointTrimming = 0; |
FC_StatusFlags &= ~(FC_STATUS_VARIO_TRIM_UP|FC_STATUS_VARIO_TRIM_DOWN); |
HeightTrimming = 0; |
if(Parameter_ExtraConfig & CFG2_VARIO_BEEP) beeptime = 500; |
if(!StartTrigger && HoehenWert > 50) |
{ |
StartTrigger = 1; |
} |
} |
} |
// Trim height set point |
HeightTrimming += AltitudeSetpointTrimming; |
if(abs(HeightTrimming) > 500) // bei Waypoint-Flug ist das ca. die 500Hz |
{ |
if(WaypointTrimming) |
{ |
if(abs(FromNC_AltitudeSetpoint - SollHoehe) < 10) SollHoehe = FromNC_AltitudeSetpoint; |
else SollHoehe += WaypointTrimming; |
} |
else |
{ |
if(HeightTrimming > 0) SollHoehe += EE_Parameter.Hoehe_Verstaerkung / 3; |
else SollHoehe -= EE_Parameter.Hoehe_Verstaerkung / 3; |
} |
HeightTrimming = 0; |
LIMIT_MIN_MAX(HoehenWertF, (HoehenWert-1024), (HoehenWert+1024)); // max. 10m Unterschied |
LIMIT_MIN_MAX(SollHoehe, (HoehenWertF-1024), (HoehenWertF+1500)); // max. 15m Unterschied |
if(Parameter_ExtraConfig & CFG2_VARIO_BEEP) beeptime = 100; |
//update hoover gas stick value when setpoint is shifted |
if(FromNC_AltitudeSpeed == 0) CalcStickGasHover(); |
/* |
if(!EE_Parameter.Hoehe_StickNeutralPoint && FromNC_AltitudeSpeed == 0) |
{ |
StickGasHover = HoverGas/STICK_GAIN; //rescale back to stick value |
StickGasHover = (unsigned int)((unsigned int) StickGasHover * UBat) / BattLowVoltageWarning; |
if(StickGasHover < 70) StickGasHover = 70; |
else if(StickGasHover > 175) StickGasHover = 175; |
} |
*/ |
} |
if(BaroExpandActive) SollHoehe = HoehenWertF; // update setpoint to current altitude if Expanding is active |
} //if FCFlags & MKFCFLAG_FLY |
else |
{ |
#if (defined(__AVR_ATmega1284__) || defined(__AVR_ATmega1284P__)) |
ACC_AltitudeFusion(1); // init the ACC and Altitude fusion |
#endif |
SollHoehe = HoehenWertF - 2000; |
if(EE_Parameter.Hoehe_StickNeutralPoint) StickGasHover = EE_Parameter.Hoehe_StickNeutralPoint; |
else StickGasHover = 127; |
HoverGas = GasMischanteil; |
VarioCharacter = '.'; |
} |
HCGas = HoverGas; // take hover gas (neutral point) |
} |
if(HoehenWertF > SollHoehe || !(Parameter_ExtraConfig & CFG2_HEIGHT_LIMIT)) |
{ |
if(!ACC_AltitudeControl) |
{ |
// from this point the Heigth Control Algorithm is identical for both versions |
if(BaroExpandActive) // baro range expanding active |
{ |
HCGas = HoverGas; // hover while expanding baro adc range |
HeightDeviation = 0; |
} // EOF // baro range expanding active |
else // valid data from air pressure sensor |
{ |
// ------------------------- P-Part ---------------------------- |
tmp_long = (HoehenWertF - SollHoehe); // positive when too high |
LIMIT_MIN_MAX(tmp_long, -32767L, 32767L); // avoid overflov when casting to int16_t |
HeightDeviation = (int)(tmp_long); // positive when too high |
tmp_long = (tmp_long * (long)Parameter_Hoehe_P) / 32L; // p-part |
LIMIT_MIN_MAX(tmp_long, -127 * STICK_GAIN, 256 * STICK_GAIN); // more than the full range makes no sense |
GasReduction = tmp_long; |
// ------------------------- D-Part 1: Vario Meter ---------------------------- |
tmp_int = VarioMeter / 8; |
LIMIT_MIN_MAX(tmp_int, -127, 128); |
tmp_int = (tmp_int * (long)Parameter_Luftdruck_D) / 4L; // scale to d-gain parameter |
LIMIT_MIN_MAX(tmp_int,-64 * STICK_GAIN, 64 * STICK_GAIN); |
if(FC_StatusFlags & (FC_STATUS_VARIO_TRIM_UP|FC_STATUS_VARIO_TRIM_DOWN)) tmp_int /= 4; // reduce d-part while trimming setpoint |
else |
if(Parameter_ExtraConfig & CFG2_HEIGHT_LIMIT) tmp_int /= 8; // reduce d-part in "Deckel" mode |
GasReduction += tmp_int; |
} // EOF no baro range expanding |
// ------------------------ D-Part 2: ACC-Z Integral ------------------------ |
if(Parameter_Hoehe_ACC_Wirkung) |
{ |
tmp_long = ((Mess_Integral_Hoch / 128L) * (int32_t) Parameter_Hoehe_ACC_Wirkung) / (128L / STICK_GAIN); |
LIMIT_MIN_MAX(tmp_long, -32 * STICK_GAIN, 64 * STICK_GAIN); |
GasReduction += tmp_long; |
} |
/* // ------------------------ D-Part 3: GpsZ ---------------------------------- |
tmp_int = (Parameter_Hoehe_GPS_Z * (int)FromNaviCtrl_Value.GpsZ)/128L; |
LIMIT_MIN_MAX(tmp_int, -32 * STICK_GAIN, 64 * STICK_GAIN); |
GasReduction += tmp_int; |
*/ |
GasReduction = (long)((long)GasReduction * HoverGas) / 512; // scale to the gas value |
// ------------------------ ---------------------------------- |
HCGas -= GasReduction; |
// limit deviation from hoover point within the target region |
if(!AltitudeSetpointTrimming && HoverGas > 0) // height setpoint is not changed and hoover gas not zero |
{ |
unsigned int tmp; |
tmp = abs(HeightDeviation); |
if(tmp <= 60) |
{ |
LIMIT_MIN_MAX(HCGas, HoverGasMin, HoverGasMax); // limit gas around the hoover point |
} |
else |
{ |
tmp = (tmp - 60) / 32; |
if(tmp > 15) tmp = 15; |
if(HeightDeviation > 0) |
{ |
tmp = (HoverGasMin * (16 - tmp)) / 16; |
LIMIT_MIN_MAX(HCGas, tmp, HoverGasMax); // limit gas around the hoover point |
} |
else |
{ |
tmp = (HoverGasMax * (tmp + 16)) / 16; |
LIMIT_MIN_MAX(HCGas, HoverGasMin, tmp); // limit gas around the hoover point |
} |
} |
} |
// strech control output by inverse attitude projection 1/cos |
// + 1/cos(angle) ++++++++++++++++++++++++++ |
tmp_long2 = (int32_t)HCGas; |
tmp_long2 *= 8192L; |
tmp_long2 /= CosAttitude; |
HCGas = (int16_t)tmp_long2; |
// update height control gas averaging |
FilterHCGas = (FilterHCGas * (HC_GAS_AVERAGE - 1) + HCGas) / HC_GAS_AVERAGE; |
// limit height control gas pd-control output |
LIMIT_MIN_MAX(FilterHCGas, EE_Parameter.Hoehe_MinGas * STICK_GAIN, (MAX_GAS - 20) * STICK_GAIN); |
// set GasMischanteil to HeightControlGasFilter |
if(Parameter_ExtraConfig & CFG2_HEIGHT_LIMIT) |
{ // old version |
LIMIT_MAX(FilterHCGas, GasMischanteil); // nicht mehr als Gas |
GasMischanteil = FilterHCGas; |
} |
else GasMischanteil = FilterHCGas + (GasMischanteil - HoverGas) / 4; // only in Vario-Mode |
} |
#if (defined(__AVR_ATmega1284__) || defined(__AVR_ATmega1284P__)) |
else // ACC-Altitude control |
{ |
// from this point the Heigth Control Algorithm is identical for both versions |
if(BaroExpandActive) // baro range expanding active |
{ |
HCGas = HoverGas; // hover while expanding baro adc range |
HeightDeviation = 0; |
} // EOF // baro range expanding active |
else // valid data from air pressure sensor |
{ |
// ------------------------- P-Part ---------------------------- |
tmp_long = (HoehenWertF - SollHoehe); // positive when too high |
LIMIT_MIN_MAX(tmp_long, -32767L, 32767L); // avoid overflov when casting to int16_t |
HeightDeviation = (int)(tmp_long); // positive when too high |
tmp_long = (tmp_long * (long)Parameter_Hoehe_P) / 32L; // p-part |
LIMIT_MIN_MAX(tmp_long, -511 * STICK_GAIN, 512 * STICK_GAIN); // more than full range makes sense |
GasReduction = tmp_long; |
// ------------------------ D-Part: ACC-Z Integral ------------------------ |
tmp_long = VarioMeter + (AdWertAccHoch * Parameter_Hoehe_ACC_Wirkung)/256; |
// ------------------------- D-Part: Vario Meter ---------------------------- |
if(WaypointTrimming) { |
Variance = AltitudeSetpointTrimming * 8; |
} else { |
Variance = AltitudeSetpointTrimming * EE_Parameter.Hoehe_Verstaerkung*9/32; |
} |
tmp_long -= (long)Variance; |
tmp_long = (tmp_long * (long)Parameter_Luftdruck_D) / 32; // scale to d-gain parameter |
LIMIT_MIN_MAX(tmp_long,-511 * STICK_GAIN, 512 * STICK_GAIN); |
GasReduction += tmp_long; |
} // EOF no baro range expanding |
HCGas -= GasReduction; |
LIMIT_MIN_MAX(HCGas, HoverGasMin, HoverGasMax); // limits gas around hover point |
// strech control output by inverse attitude projection 1/cos |
// + 1/cos(angle) ++++++++++++++++++++++++++ |
tmp_long2 = (int32_t)HCGas; |
tmp_long2 *= 8192L; |
tmp_long2 /= CosAttitude; |
HCGas = (int16_t)tmp_long2; |
// update height control gas averaging |
FilterHCGas = (FilterHCGas * (HC_GAS_AVERAGE - 1) + HCGas) / HC_GAS_AVERAGE; |
// limit height control gas pd-control output |
int min; |
if(GasIsZeroCnt > 400 || (FC_StatusFlags2 & FC_STATUS2_WAIT_FOR_TAKEOFF)) min = EE_Parameter.Gas_Min; else min = EE_Parameter.Hoehe_MinGas; |
LIMIT_MIN_MAX(FilterHCGas, min * STICK_GAIN, (MAX_GAS - 20) * STICK_GAIN) |
// set GasMischanteil to HeightControlGasFilter |
if(Parameter_ExtraConfig & CFG2_HEIGHT_LIMIT) |
{ // old version |
LIMIT_MAX(FilterHCGas, GasMischanteil); // nicht mehr als Gas |
GasMischanteil = FilterHCGas; |
} |
else GasMischanteil = FilterHCGas; |
} // end of ACC-Altitude control |
#endif |
} |
}// EOF height control active |
else // HC not active |
{ |
//update hoover gas stick value when HC is not active |
CalcStickGasHover(); |
/* if(!EE_Parameter.Hoehe_StickNeutralPoint) |
{ |
StickGasHover = HoverGas/STICK_GAIN; // rescale back to stick value |
StickGasHover = (unsigned int)((unsigned int) StickGasHover * UBat) / BattLowVoltageWarning; |
} |
else StickGasHover = EE_Parameter.Hoehe_StickNeutralPoint; |
LIMIT_MIN_MAX(StickGasHover, 70, 175); // reserve some range for trim up and down |
*/ |
FilterHCGas = GasMischanteil; |
// set both flags to indicate no vario mode |
FC_StatusFlags |= (FC_STATUS_VARIO_TRIM_UP|FC_STATUS_VARIO_TRIM_DOWN); |
FC_StatusFlags2 &= ~FC_STATUS2_ALTITUDE_CONTROL; |
} |
// Hover gas estimation by averaging gas control output on small z-velocities |
// this is done only if height contol option is selected in global config and aircraft is flying |
if((FC_StatusFlags & FC_STATUS_FLY))// && !(FC_SatusFlags & FC_STATUS_EMERGENCY_LANDING)) |
{ |
//if(HoverGasFilter == 0 || StartTrigger == 1) HoverGasFilter = HOVER_GAS_AVERAGE * (unsigned long)(GasMischanteil); // init estimation |
if(HoverGasFilter == 0 || StartTrigger == 1) HoverGasFilter = HOVER_GAS_AVERAGE * (unsigned long)(HoverGas); // 0.90f: geändert |
if(StartTrigger == 1) StartTrigger = 2; |
tmp_long2 = (int32_t)GasMischanteil; // take current thrust |
tmp_long2 *= CosAttitude; // apply attitude projection |
tmp_long2 /= 8192; |
// average vertical projected thrust |
if(modell_fliegt < 4000) // the first 8 seconds |
{ // reduce the time constant of averaging by factor of 4 to get much faster a stable value |
HoverGasFilter -= HoverGasFilter/(HOVER_GAS_AVERAGE/16L); |
HoverGasFilter += 16L * tmp_long2; |
} |
if(modell_fliegt < 8000) // the first 16 seconds |
{ // reduce the time constant of averaging by factor of 2 to get much faster a stable value |
HoverGasFilter -= HoverGasFilter/(HOVER_GAS_AVERAGE/4L); |
HoverGasFilter += 4L * tmp_long2; |
} |
else //later |
if(abs(VarioMeter) < 100 && abs(HoehenWertF - SollHoehe) < 256) // only on small vertical speed & difference is small (only descending) |
{ |
HoverGasFilter -= HoverGasFilter/HOVER_GAS_AVERAGE; |
HoverGasFilter += tmp_long2; |
} |
HoverGas = (int16_t)(HoverGasFilter/HOVER_GAS_AVERAGE); |
if(EE_Parameter.Hoehe_HoverBand) |
{ |
int16_t band; |
band = HoverGas / EE_Parameter.Hoehe_HoverBand; // the higher the parameter the smaller the range |
HoverGasMin = HoverGas - band; |
HoverGasMax = HoverGas + band; |
} |
else |
{ // no limit |
HoverGasMin = 0; |
HoverGasMax = 1023; |
} |
} |
else |
{ |
StartTrigger = 0; |
HoverGasFilter = 0; |
HoverGas = 0; |
} |
}// EOF Parameter_GlobalConfig & CFG_HEIGHT_CONTROL |
else |
{ |
// set undefined state to indicate vario off |
FC_StatusFlags |= (FC_STATUS_VARIO_TRIM_UP|FC_STATUS_VARIO_TRIM_DOWN); |
} // EOF no height control |
// Limits the maximum gas in case of "Out of Range emergency landing" |
if(NC_To_FC_Flags & NC_TO_FC_EMERGENCY_LANDING) |
{ |
if(GasMischanteil/STICK_GAIN > HooverGasEmergencyPercent && HoverGas) GasMischanteil = HooverGasEmergencyPercent * STICK_GAIN; |
SollHoehe = HoehenWertF; // update setpoint to current heigth |
beeptime = 15000; |
BeepMuster = 0x0E00; |
} |
// limit gas to parameter setting |
LIMIT_MIN(GasMischanteil, (MIN_GAS + 10) * STICK_GAIN); |
if(GasMischanteil > (MAX_GAS - 20) * STICK_GAIN) GasMischanteil = (MAX_GAS - 20) * STICK_GAIN; |
// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
// all BL-Ctrl connected? |
// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
#ifndef REDUNDANT_FC_SLAVE |
if(MissingMotor || Capacity.MinOfMaxPWM < 254 || NC_ErrorCode) // wait until all BL-Ctrls started and no Errors |
if(modell_fliegt > 1 && modell_fliegt < 50 && GasMischanteil > 0) // only during start-phase |
{ |
modell_fliegt = 1; |
GasMischanteil = (MIN_GAS + 10) * STICK_GAIN; |
#if (defined(__AVR_ATmega1284__) || defined(__AVR_ATmega1284P__)) |
if(Capacity.MinOfMaxPWM < 40) SpeakHoTT = SPEAK_ERR_MOTOR; |
#endif |
} |
#endif |
// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
// send SPI pending bytes |
if(BytegapSPI == 0) SPI_TransmitByte(); |
// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
// + Mischer und PI-Regler |
// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
DebugOut.Analog[7] = GasMischanteil; // achtung: Muss auf [7] bleiben wegen SPI.C |
// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
// Gier-Anteil |
// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
GierMischanteil = MesswertGier - sollGier * STICK_GAIN; // Regler für Gier |
#define MIN_GIERGAS (40*STICK_GAIN) // unter diesem Gaswert trotzdem Gieren |
if(GasMischanteil > MIN_GIERGAS) |
{ |
if(GierMischanteil > (GasMischanteil / 2)) GierMischanteil = GasMischanteil / 2; |
if(GierMischanteil < -(GasMischanteil / 2)) GierMischanteil = -(GasMischanteil / 2); |
} |
else |
{ |
if(GierMischanteil > (MIN_GIERGAS / 2)) GierMischanteil = MIN_GIERGAS / 2; |
if(GierMischanteil < -(MIN_GIERGAS / 2)) GierMischanteil = -(MIN_GIERGAS / 2); |
} |
tmp_int = MAX_GAS*STICK_GAIN; |
if(GierMischanteil > ((tmp_int - GasMischanteil))) GierMischanteil = ((tmp_int - GasMischanteil)); |
if(GierMischanteil < -((tmp_int - GasMischanteil))) GierMischanteil = -((tmp_int - GasMischanteil)); |
// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
// Nick-Achse |
// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
DiffNick = MesswertNick - StickNick; // Differenz bestimmen |
if(IntegralFaktor) SummeNick += IntegralNickMalFaktor - StickNick; // I-Anteil bei Winkelregelung |
else SummeNick += DiffNick; // I-Anteil bei HH |
if(SummeNick > (STICK_GAIN * 16000L)) SummeNick = (STICK_GAIN * 16000L); |
if(SummeNick < -(16000L * STICK_GAIN)) SummeNick = -(16000L * STICK_GAIN); |
if(EE_Parameter.Gyro_Stability <= 8) pd_ergebnis_nick = (EE_Parameter.Gyro_Stability * DiffNick) / 8; // PI-Regler für Nick |
else pd_ergebnis_nick = ((EE_Parameter.Gyro_Stability / 2) * DiffNick) / 4; // Überlauf verhindern |
pd_ergebnis_nick += SummeNick / Ki; |
tmp_int = (long)((long)Parameter_DynamicStability * (long)(GasMischanteil + abs(GierMischanteil)/2)) / 64; |
if(pd_ergebnis_nick > tmp_int) pd_ergebnis_nick = tmp_int; |
if(pd_ergebnis_nick < -tmp_int) pd_ergebnis_nick = -tmp_int; |
// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
// Roll-Achse |
// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
DiffRoll = MesswertRoll - StickRoll; // Differenz bestimmen |
if(IntegralFaktor) SummeRoll += IntegralRollMalFaktor - StickRoll;// I-Anteil bei Winkelregelung |
else SummeRoll += DiffRoll; // I-Anteil bei HH |
if(SummeRoll > (STICK_GAIN * 16000L)) SummeRoll = (STICK_GAIN * 16000L); |
if(SummeRoll < -(16000L * STICK_GAIN)) SummeRoll = -(16000L * STICK_GAIN); |
if(EE_Parameter.Gyro_Stability <= 8) pd_ergebnis_roll = (EE_Parameter.Gyro_Stability * DiffRoll) / 8; // PI-Regler für Roll |
else pd_ergebnis_roll = ((EE_Parameter.Gyro_Stability / 2) * DiffRoll) / 4; // Überlauf verhindern |
pd_ergebnis_roll += SummeRoll / Ki; |
tmp_int = (long)((long)Parameter_DynamicStability * (long)(GasMischanteil + abs(GierMischanteil)/2)) / 64; |
if(pd_ergebnis_roll > tmp_int) pd_ergebnis_roll = tmp_int; |
if(pd_ergebnis_roll < -tmp_int) pd_ergebnis_roll = -tmp_int; |
// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
// send SPI pending bytes |
if(BytegapSPI == 0) SPI_TransmitByte(); |
// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
// Universal Mixer |
// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
for(i=0; i<MAX_MOTORS; i++) |
{ |
signed int tmp_int; |
if(Mixer.Motor[i][0] > 0) |
{ |
// Gas |
if(Mixer.Motor[i][0] == 64) tmp_int = GasMischanteil; else tmp_int = ((long)GasMischanteil * Mixer.Motor[i][0]) / 64L; |
// Nick |
if(Mixer.Motor[i][1] == 64) tmp_int += pd_ergebnis_nick; |
else if(Mixer.Motor[i][1] == -64) tmp_int -= pd_ergebnis_nick; |
else tmp_int += ((long)pd_ergebnis_nick * Mixer.Motor[i][1]) / 64L; |
// Roll |
if(Mixer.Motor[i][2] == 64) tmp_int += pd_ergebnis_roll; |
else if(Mixer.Motor[i][2] == -64) tmp_int -= pd_ergebnis_roll; |
else tmp_int += ((long)pd_ergebnis_roll * Mixer.Motor[i][2]) / 64L; |
// Gier |
if(Mixer.Motor[i][3] == 64) tmp_int += GierMischanteil; |
else if(Mixer.Motor[i][3] == -64) tmp_int -= GierMischanteil; |
else tmp_int += ((long)GierMischanteil * Mixer.Motor[i][3]) / 64L; |
#ifdef REDUNDANT_FC_SLAVE |
tmp_int = (tmp_motorwert[i] + tmp_int) / 2; |
#else |
if(Motor[i].Version & MOTOR_STATE_FAST_MODE || tmp_int > tmp_motorwert[i]) tmp_int = (tmp_motorwert[i] + tmp_int) / 2; // Beschleunigen |
else |
{ // BL-Ctrl 1.0 or 2.0 |
if(EE_Parameter.MotorSmooth == 0) |
{ |
tmp_int = 2 * tmp_int - tmp_motorwert[i]; // original MotorSmoothing |
} |
else // 1 means tmp_int = tmp_int; |
if(EE_Parameter.MotorSmooth > 1) |
{ |
// If >= 2 then allow >= 50% of the intended step down to rapidly reach the intended value. |
tmp_int = tmp_int + ((tmp_motorwert[i] - tmp_int) / EE_Parameter.MotorSmooth); |
} |
} |
#endif |
LIMIT_MIN_MAX(tmp_int,(int) MIN_GAS * 4,(int) MAX_GAS * 4); |
Motor[i].SetPoint = tmp_int / 4; |
Motor[i].SetPointLowerBits = (tmp_int % 4)<<1; // (3 bits total) |
tmp_motorwert[i] = tmp_int; |
} |
else |
{ |
Motor[i].SetPoint = 0; |
Motor[i].SetPointLowerBits = 0; |
} |
} |
#if (defined(REDUNDANT_FC_MASTER) || defined(REDUNDANT_FC_SLAVE)) |
if(Parameter_UserParam6 > 230) // Motor1-Test |
{ |
Motor[0].SetPoint = 0; |
FC_StatusFlags3 |= FC_STATUS3_REDUNDANCE_TEST; |
} |
else |
if(Parameter_UserParam7 <= 150) // I2C-Test |
{ |
FC_StatusFlags3 &= ~FC_STATUS3_REDUNDANCE_TEST; |
} |
#endif |
} |
//DebugOut.Analog[16] |
/tags/V2.12a/fc.h |
---|
0,0 → 1,168 |
/*####################################################################################### |
Flight Control |
#######################################################################################*/ |
#ifndef _FC_H |
#define _FC_H |
//#define GIER_GRAD_FAKTOR 1291L // Abhängigkeit zwischen GyroIntegral und Winkel |
//#define GIER_GRAD_FAKTOR 1160L |
extern long GIER_GRAD_FAKTOR; // Abhängigkeit zwischen GyroIntegral und Winkel |
#define STICK_GAIN 4 |
#define ACC_AMPLIFY 6 |
#define HEIGHT_CONTROL_STICKTHRESHOLD 15 |
#define SERVO_FS_TIME 10 // in Seconds |
// FC_StatusFlags |
#define FC_STATUS_MOTOR_RUN 0x01 |
#define FC_STATUS_FLY 0x02 |
#define FC_STATUS_CALIBRATE 0x04 |
#define FC_STATUS_START 0x08 |
#define FC_STATUS_EMERGENCY_LANDING 0x10 |
#define FC_STATUS_LOWBAT 0x20 |
#define FC_STATUS_VARIO_TRIM_UP 0x40 |
#define FC_STATUS_VARIO_TRIM_DOWN 0x80 |
// FC_StatusFlags2 |
#define FC_STATUS2_CAREFREE 0x01 |
#define FC_STATUS2_ALTITUDE_CONTROL 0x02 |
#define FC_STATUS2_RC_FAILSAVE_ACTIVE 0x04 |
#define FC_STATUS2_OUT1_ACTIVE 0x08 |
#define FC_STATUS2_OUT2_ACTIVE 0x10 |
#define FC_STATUS2_WAIT_FOR_TAKEOFF 0x20 // Motor Running, but still on the ground |
#define FC_STATUS2_AUTO_STARTING 0x40 |
#define FC_STATUS2_AUTO_LANDING 0x80 |
// FC_StatusFlags3 |
#define FC_STATUS3_REDUNDANCE_AKTIVE 0x01 |
#define FC_STATUS3_BOAT 0x02 |
#define FC_STATUS3_REDUNDANCE_ERROR 0x04 |
#define FC_STATUS3_REDUNDANCE_TEST 0x08 |
//NC_To_FC_Flags |
#define NC_TO_FC_FLYING_RANGE 0x01 |
#define NC_TO_FC_EMERGENCY_LANDING 0x02 // Forces a landing |
#define NC_TO_FC_AUTOSTART 0x04 |
#define NC_TO_FC_FAILSAFE_LANDING 0x08 // moves Servos into FS-Position |
#define NC_TO_FC_SIMULATION_ACTIVE 0x10 // don't start motors |
extern volatile unsigned char FC_StatusFlags, FC_StatusFlags2; |
extern unsigned char FC_StatusFlags3; |
extern void ParameterZuordnung(void); |
extern unsigned char GetChannelValue(unsigned char ch); // gives the unsigned value of the channel |
extern void ChannelAssingment(void); |
extern void StoreNeutralToEeprom(void); |
#define Poti1 Poti[0] |
#define Poti2 Poti[1] |
#define Poti3 Poti[2] |
#define Poti4 Poti[3] |
#define Poti5 Poti[4] |
#define Poti6 Poti[5] |
#define Poti7 Poti[6] |
#define Poti8 Poti[7] |
#define LIMIT_MIN(value, min) {if(value <= min) value = min;} |
#define LIMIT_MAX(value, max) {if(value >= max) value = max;} |
#define LIMIT_MIN_MAX(value, min, max) {if(value <= min) value = min; else if(value >= max) value = max;} |
#define CHK_POTI(b,a) {if(a < 248) b = a; else b = Poti[255 - a];} |
#define CHK_POTI_OFF(b,a,off) {if(a < 248) b = a; else b = Poti[255 - a] - off;} |
#define CHK_POTI_MM(b,a,min,max) {CHK_POTI(b,a); LIMIT_MIN_MAX(b, min, max);} |
#define CHK_POTI_MM_OFF(b,a,min,max,off) {CHK_POTI_OFF(b,a,off); LIMIT_MIN_MAX(b, min, max);} |
extern unsigned char Sekunde,Minute; |
extern unsigned int BaroExpandActive; |
extern long IntegralNick;//,IntegralNick2; |
extern long IntegralRoll;//,IntegralRoll2; |
//extern int IntegralNick,IntegralNick2; |
//extern int IntegralRoll,IntegralRoll2; |
extern unsigned char Poti[9]; |
extern long Mess_IntegralNick;//,Mess_IntegralNick2; |
extern long Mess_IntegralRoll;//,Mess_IntegralRoll2; |
extern long IntegralAccNick,IntegralAccRoll; |
extern long SummeNick,SummeRoll; |
extern volatile long Mess_Integral_Hoch; |
extern long Integral_Gier,Mess_Integral_Gier,Mess_Integral_Gier2; |
extern int KompassValue; |
extern int KompassSollWert,NC_CompassSetpoint; |
extern int KompassRichtung; |
extern char CalculateCompassTimer; |
extern unsigned char KompassFusion; |
extern unsigned char ControlHeading; |
extern int TrimNick, TrimRoll; |
extern long ErsatzKompass; |
extern int ErsatzKompassInGrad,CompassCorrected; // Kompasswert in Grad |
extern long HoehenWert; |
extern long SollHoehe; |
extern long FromNC_AltitudeSetpoint; |
extern unsigned char FromNC_AltitudeSpeed; |
extern unsigned char Parameter_HoehenSchalter; // Wert : 0-250 |
extern unsigned char CareFree; |
extern int MesswertNick,MesswertRoll,MesswertGier; |
extern int AdNeutralNick,AdNeutralRoll,AdNeutralGier, Mittelwert_AccNick, Mittelwert_AccRoll; |
extern int BoatNeutralNick,BoatNeutralRoll,BoatNeutralGier; |
extern unsigned int NeutralAccX, NeutralAccY; |
extern unsigned char HoehenReglerAktiv; |
extern int NeutralAccZ; |
extern signed char NeutralAccZfine; |
extern long Umschlag180Nick, Umschlag180Roll; |
extern unsigned char Parameter_UserParam1,Parameter_UserParam2,Parameter_UserParam3,Parameter_UserParam4,Parameter_UserParam5,Parameter_UserParam6,Parameter_UserParam7,Parameter_UserParam8; |
extern int NaviAccNick,NaviAccRoll,NaviCntAcc; |
extern unsigned int modell_fliegt; |
extern void MotorRegler(void); |
extern void SendMotorData(void); |
//void CalibrierMittelwert(void); |
//void Mittelwert(void); |
extern unsigned char SetNeutral(unsigned char AccAdjustment); // retuns: "sucess" |
extern void Piep(unsigned char Anzahl, unsigned int dauer); |
extern void CopyDebugValues(void); |
extern unsigned char ACC_AltitudeControl; |
extern signed int CosAttitude; // for projection of hoover gas |
extern unsigned char h,m,s; |
extern int StickNick,StickRoll,StickGier,StickGas; |
extern volatile unsigned char Timeout ; |
extern unsigned char CosinusNickWinkel, CosinusRollWinkel; |
extern int DiffNick,DiffRoll; |
//extern int Poti1, Poti2, Poti3, Poti4; |
extern volatile unsigned char SenderOkay; |
extern int StickNick,StickRoll,StickGier; |
extern char MotorenEin; |
extern unsigned char CalibrationDone; |
extern unsigned char Parameter_Servo3,Parameter_Servo4,Parameter_Servo5; |
extern char VarioCharacter; |
extern signed int AltitudeSetpointTrimming; |
extern signed char WaypointTrimming; |
extern int HoverGas; |
extern unsigned char Parameter_Luftdruck_D; |
//extern unsigned char Parameter_MaxHoehe; |
extern unsigned char Parameter_Hoehe_P; |
extern unsigned char Parameter_Hoehe_ACC_Wirkung; |
extern unsigned char Parameter_KompassWirkung; |
extern unsigned char Parameter_Gyro_P; |
extern unsigned char Parameter_Gyro_I; |
extern unsigned char Parameter_Gier_P; |
extern unsigned char Parameter_ServoNickControl; |
extern unsigned char Parameter_ServoRollControl; |
extern unsigned char Parameter_ServoNickComp; |
extern unsigned char Parameter_ServoRollComp; |
extern unsigned char Parameter_AchsKopplung1; |
extern unsigned char Parameter_AchsKopplung2; |
//extern unsigned char Parameter_AchsGegenKopplung1; |
extern unsigned char Parameter_J16Bitmask; // for the J16 Output |
extern unsigned char Parameter_J16Timing; // for the J16 Output |
extern unsigned char Parameter_J17Bitmask; // for the J17 Output |
extern unsigned char Parameter_J17Timing; // for the J17 Output |
extern unsigned char Parameter_GlobalConfig; |
extern unsigned char Parameter_ExtraConfig; |
extern signed char MixerTable[MAX_MOTORS][4]; |
extern const signed char sintab[31]; |
extern unsigned char LowVoltageLandingActive; |
extern unsigned char LowVoltageHomeActive; |
extern unsigned char Parameter_MaximumAltitude; |
extern char NeueKompassRichtungMerken; |
extern unsigned char ServoFailsafeActive; |
#endif //_FC_H |
/tags/V2.12a/flight.pnproj |
---|
0,0 → 1,0 |
<Project name="Flight-Ctrl"><File path="uart.h"></File><File path="jeti.h"></File><File path="main.c"></File><File path="main.h"></File><File path="makefile"></File><File path="uart.c"></File><File path="printf_P.h"></File><File path="timer0.c"></File><File path="timer0.h"></File><File path="old_macros.h"></File><File path="twimaster.c"></File><File path="version.txt"></File><File path="twimaster.h"></File><File path="rc.c"></File><File path="rc.h"></File><File path="fc.h"></File><File path="menu.h"></File><File path="menu.c"></File><File path="_Settings.h"></File><File path="analog.c"></File><File path="analog.h"></File><File path="GPS.c"></File><File path="gps.h"></File><File path="License.txt"></File><File path="spi.h"></File><File path="spi.c"></File><File path="led.h"></File><File path="led.c"></File><File path="fc.c"></File><File path="mymath.c"></File><File path="mymath.h"></File><File path="isqrt.S"></File><File path="Spektrum.c"></File><File path="Spektrum.h"></File><File path="eeprom.h"></File><File path="eeprom.c"></File><File path="libfc.h"></File><File path="debug.c"></File><File path="debug.h"></File><File path="hottmenu.c"></File><File path="hottmenu.h"></File></Project> |
/tags/V2.12a/flight.pnps |
---|
0,0 → 1,0 |
<pd><ViewState><e p="Flight-Ctrl" x="true"></e></ViewState></pd> |
/tags/V2.12a/gps.h |
---|
0,0 → 1,3 |
extern signed int GPS_Nick; |
extern signed int GPS_Roll; |
extern unsigned char GPS_Aid_StickMultiplikator; |
/tags/V2.12a/hottmenu.c |
---|
0,0 → 1,1635 |
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
// + www.MikroKopter.com |
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
// + Software Nutzungsbedingungen (english version: see below) |
// + der Fa. HiSystems GmbH, Flachsmeerstrasse 2, 26802 Moormerland - nachfolgend Lizenzgeber genannt - |
// + Der Lizenzgeber räumt dem Kunden ein nicht-ausschließliches, zeitlich und räumlich* unbeschränktes Recht ein, die im den |
// + Mikrocontroller verwendete Firmware für die Hardware Flight-Ctrl, Navi-Ctrl, BL-Ctrl, MK3Mag & PC-Programm MikroKopter-Tool |
// + - nachfolgend Software genannt - nur für private Zwecke zu nutzen. |
// + Der Einsatz dieser Software ist nur auf oder mit Produkten des Lizenzgebers zulässig. |
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
// + Die vom Lizenzgeber gelieferte Software ist urheberrechtlich geschützt. Alle Rechte an der Software sowie an sonstigen im |
// + Rahmen der Vertragsanbahnung und Vertragsdurchführung überlassenen Unterlagen stehen im Verhältnis der Vertragspartner ausschließlich dem Lizenzgeber zu. |
// + Die in der Software enthaltenen Copyright-Vermerke, Markenzeichen, andere Rechtsvorbehalte, Seriennummern sowie |
// + sonstige der Programmidentifikation dienenden Merkmale dürfen vom Kunden nicht verändert oder unkenntlich gemacht werden. |
// + Der Kunde trifft angemessene Vorkehrungen für den sicheren Einsatz der Software. Er wird die Software gründlich auf deren |
// + Verwendbarkeit zu dem von ihm beabsichtigten Zweck testen, bevor er diese operativ einsetzt. |
// + Die Haftung des Lizenzgebers wird - soweit gesetzlich zulässig - begrenzt in Höhe des typischen und vorhersehbaren |
// + Schadens. Die gesetzliche Haftung bei Personenschäden und nach dem Produkthaftungsgesetz bleibt unberührt. Dem Lizenzgeber steht jedoch der Einwand |
// + des Mitverschuldens offen. |
// + Der Kunde trifft angemessene Vorkehrungen für den Fall, dass die Software ganz oder teilweise nicht ordnungsgemäß arbeitet. |
// + Er wird die Software gründlich auf deren Verwendbarkeit zu dem von ihm beabsichtigten Zweck testen, bevor er diese operativ einsetzt. |
// + Der Kunde wird er seine Daten vor Einsatz der Software nach dem Stand der Technik sichern. |
// + Der Kunde ist darüber unterrichtet, dass der Lizenzgeber seine Daten im zur Vertragsdurchführung erforderlichen Umfang |
// + und auf Grundlage der Datenschutzvorschriften erhebt, speichert, verarbeitet und, sofern notwendig, an Dritte übermittelt. |
// + *) Die räumliche Nutzung bezieht sich nur auf den Einsatzort, nicht auf die Reichweite der programmierten Software. |
// + #### ENDE DER NUTZUNGSBEDINGUNGEN ####' |
// + Hinweis: Informationen über erweiterte Nutzungsrechte (wie z.B. Nutzung für nicht-private Zwecke) sind auf Anfrage per Email an info(@)hisystems.de verfügbar. |
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
// + Software LICENSING TERMS |
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
// + of HiSystems GmbH, Flachsmeerstrasse 2, 26802 Moormerland, Germany - the Licensor - |
// + The Licensor grants the customer a non-exclusive license to use the microcontroller firmware of the Flight-Ctrl, Navi-Ctrl, BL-Ctrl, and MK3Mag hardware |
// + (the Software) exclusively for private purposes. The License is unrestricted with respect to time and territory*. |
// + The Software may only be used with the Licensor's products. |
// + The Software provided by the Licensor is protected by copyright. With respect to the relationship between the parties to this |
// + agreement, all rights pertaining to the Software and other documents provided during the preparation and execution of this |
// + agreement shall be the property of the Licensor. |
// + The information contained in the Software copyright notices, trademarks, other legal reservations, serial numbers and other |
// + features that can be used to identify the program may not be altered or defaced by the customer. |
// + The customer shall be responsible for taking reasonable precautions |
// + for the safe use of the Software. The customer shall test the Software thoroughly regarding its suitability for the |
// + intended purpose before implementing it for actual operation. The Licensor's liability shall be limited to the extent of typical and |
// + foreseeable damage to the extent permitted by law, notwithstanding statutory liability for bodily injury and product |
// + liability. However, the Licensor shall be entitled to the defense of contributory negligence. |
// + The customer will take adequate precautions in the case, that the software is not working properly. The customer will test |
// + the software for his purpose before any operational usage. The customer will backup his data before using the software. |
// + The customer understands that the Licensor collects, stores and processes, and, where required, forwards, customer data |
// + to third parties to the extent necessary for executing the agreement, subject to applicable data protection and privacy regulations. |
// + *) The territory aspect only refers to the place where the Software is used, not its programmed range. |
// + #### END OF LICENSING TERMS #### |
// + Note: For information on license extensions (e.g. commercial use), please contact us at info(@)hisystems.de. |
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
#include "libfc.h" |
#include "printf_P.h" |
#include "main.h" |
#include "spi.h" |
#include "capacity.h" |
unsigned char NaviData_WaypointIndex = 0; |
unsigned char NaviData_WaypointNumber = 0, NaviData_TargetHoldTime = 0, ToNC_Load_WP_List = 0, NaviData_MaxWpListIndex = 0; |
unsigned char ToNC_Load_SingePoint = 0, ToNC_Store_SingePoint = 0, Show_Load_Time = 0, Show_Load_Value = 0, Show_Store_Time = 0, Show_Store_Value = 0; |
char WPL_Name[10];// = {" \0"}; |
#if (defined(__AVR_ATmega1284__) || defined(__AVR_ATmega1284P__)) |
#define HoTT_printf(format, args...) { _printf_P(&LIBFC_HoTT_Putchar, PSTR(format) , ## args);} |
#define HoTT_printfxy(x,y,format, args...) { LIBFC_HoTT_SetPos((y) * 21 + (x)); _printf_P(&LIBFC_HoTT_Putchar, PSTR(format) , ## args);} |
#define HoTT_printfxy_INV(x,y,format, args...) { LIBFC_HoTT_SetPos((y) * 21 + (x)); _printf_P(&LIBFC_HoTT_Putchar_INV, PSTR(format) , ## args);} |
#define HoTT_printfxy_BLINK(x,y,format, args...) { LIBFC_HoTT_SetPos((y) * 21 + (x)); _printf_P(&LIBFC_HoTT_Putchar_BLINK, PSTR(format) , ## args);} |
#define HoTT_printf_BLINK(format, args...) { _printf_P(&LIBFC_HoTT_Putchar_BLINK, PSTR(format) , ## args);} |
#define HoTT_printf_INV(format, args...) { _printf_P(&LIBFC_HoTT_Putchar_INV, PSTR(format) , ## args);} |
#define VOICE_MINIMALE_EINGANSSPANNUNG 16 |
#define VOICE_BEEP 5 |
#define HoTT_GRAD 96 |
#define HoTT_LINKS 123 |
#define HoTT_RECHTS 124 |
#define HoTT_OBEN 125 |
#define HoTT_UNTEN 126 |
#define HOTT_KEY_RIGHT 1 |
#define HOTT_KEY_DOWN 2 |
#define HOTT_KEY_UP 4 |
#define HOTT_KEY_SET 6 |
#define HOTT_KEY_LEFT 8 |
#define VARIO_ZERO 30000 |
unsigned int NaviData_TargetDistance = 0; |
unsigned char MaxBlTemperture = 0; |
unsigned char MinBlTemperture = 0; |
unsigned char HottestBl = 0; |
GPSPacket_t GPSPacket; |
VarioPacket_t VarioPacket; |
ASCIIPacket_t ASCIIPacket; |
ElectricAirPacket_t ElectricAirPacket; |
HoTTGeneral_t HoTTGeneral; |
unsigned char SpeakHoTT = SPEAK_MIKROKOPTER; |
unsigned char ToNC_SpeakHoTT = 0, ShowSettingNameTime = 0; |
int HoTTVarioMeter = 0; |
const char PROGMEM MIKROKOPTER[] = {" MikroKopter "}; |
const char PROGMEM UNDERVOLTAGE[] = {" !! LiPo voltage !! "}; |
const char PROGMEM LANDING[] = {" !! LANDING !! "}; |
const char PROGMEM SIMULATION[] = {" SIMULATION active "}; |
const char PROGMEM BOAT_MODE[] = {" MikroKopter (Boat) "}; |
const char PROGMEM STORE[] = {" Store Position SP1 "}; |
const char PROGMEM LOAD[] = {" Load Position SP1 "}; |
const char PROGMEM SETTING[] = {"Set :"}; |
const char PROGMEM NC_ERROR_TEXT[MAX_ERR_NUMBER][17] = |
{ |
//0123456789123456 |
"No Error \0", // 0 |
"Not compatible \0", // 1 |
"MK3Mag not compa\0", // 2 |
"No FC communicat\0", // 3 |
"Compass communic\0", // 4 |
"GPS communicatio\0", // 5 |
"compass value \0", // 6 |
"RC Signal lost \0", // 7 |
"FC spi rx error \0", // 8 |
"No NC communicat\0", // 9 |
"FC Nick Gyro \0", // 10 |
"FC Roll Gyro \0", // 11 |
"FC Yaw Gyro \0", // 12 |
"FC Nick ACC \0", // 13 |
"FC Roll ACC \0", // 14 |
"FC Z-ACC \0", // 15 |
"Pressure sensor \0", // 16 |
"I2C FC->BL-Ctrl \0", // 17 |
"Bl Missing \0", // 18 |
"Mixer Error \0", // 19 |
"Carefree Error \0", // 20 |
"GPS Fix lost \0", // 21 |
"Magnet Error \0", // 22 |
"Motor restart \0", // 23 |
"BL Limitation \0", // 24 |
"GPS Range \0", // 25 |
"No SD-Card \0", // 26 |
"SD-Logging error\0", // 27 |
"Flying range! \0", // 28 |
"Max Altitude! \0", // 29 |
"No GPS fix \0", // 30 |
"compass not cal.\0", // 31 |
"BL-Selftest \0", // 32 |
"no ext. compass \0", // 33 |
"compass sensor \0", // 34 |
"Failsafe postion\0", // 35 |
"No Redundancy! \0", // 36 |
"Redundancy test \0", // 37 |
"GPS Update Rate \0" // 38 |
}; |
const char PROGMEM HOTT_ERROR[MAX_ERR_NUMBER][2] = |
{ // 1 -> only in flight 0 -> also on ground |
//0123456789123456 |
{0,0},// "No Error \0", // 0 |
{SPEAK_ERROR,0}, // "Not compatible \0", // 1 |
{SPEAK_ERROR,0}, // "MK3Mag not compa\0", // 2 |
{SPEAK_ERR_NAVI,1}, // "No FC communicat\0", // 3 |
{SPEAK_ERR_COMPASS,1}, // "MK3Mag communica\0", // 4 |
{SPEAK_ERR_GPS,0}, // "GPS communicatio\0", // 5 |
{SPEAK_ERR_COMPASS,1}, // "compass value \0", // 6 |
{SPEAK_ERR_RECEICER,0},// "RC Signal lost \0", // 7 |
{SPEAK_ERR_NAVI,0}, // "FC spi rx error \0", // 8 |
{SPEAK_ERR_NAVI,0}, // "No NC communicat\0", // 9 |
{SPEAK_ERR_SENSOR,0}, // "FC Nick Gyro \0", // 10 |
{SPEAK_ERR_SENSOR,0}, // "FC Roll Gyro \0", // 11 |
{SPEAK_ERR_SENSOR,0}, // "FC Yaw Gyro \0", // 12 |
{SPEAK_ERR_SENSOR,0}, // "FC Nick ACC \0", // 13 |
{SPEAK_ERR_SENSOR,0}, // "FC Roll ACC \0", // 14 |
{SPEAK_ERR_SENSOR,0}, // "FC Z-ACC \0", // 15 |
{SPEAK_ERR_SENSOR,0}, // "Pressure sensor \0", // 16 |
{SPEAK_ERR_DATABUS,1}, // "I2C FC->BL-Ctrl \0", // 17 |
{SPEAK_ERR_DATABUS,1}, // "Bl Missing \0", // 18 |
{SPEAK_ERROR,0}, // "Mixer Error \0", // 19 |
{SPEAK_CF_OFF,1}, // "Carefree Error \0", // 20 |
{SPEAK_GPS_FIX,1}, // "GPS Fix lost \0", // 21 |
{SPEAK_ERR_COMPASS,0}, // "Magnet Error \0", // 22 |
{SPEAK_ERR_MOTOR,1}, // "Motor restart \0", // 23 |
{SPEAK_MAX_TEMPERAT,1},// "BL Limitation \0", // 24 |
{SPEAK_MAX_RANGE,1}, // "GPS Range \0", // 25 |
{SPEAK_ERROR,1}, // "No SD-Card \0", // 26 |
{SPEAK_ERROR,1}, // "SD-Logging error\0", // 27 |
{SPEAK_MAX_RANGE,1}, // "Flying range! \0", // 28 |
{SPEAK_MAX_ALTITUD,1}, // "Max Altitude! \0" // 29 |
{SPEAK_GPS_FIX,1}, // "No GPS fix \0" // 30 |
{SPEAK_ERR_CALIBARTION,0},// "compass not cal." // 31 |
{SPEAK_ERR_MOTOR,0}, // "BL-Selftest \0" // 32 |
{SPEAK_ERR_COMPASS,0}, // "no ext. compass" // 33 |
{SPEAK_ERR_COMPASS,0}, // "compass sensor" // 34 |
{SPEAK_ERROR,1}, // "Failsafe postion0", // 35 |
{SPEAK_ERROR,0}, // "No Redundancy!", // 36 |
{0,0}, // "Redundancy test", // 37 |
{SPEAK_ERR_GPS,0}, // "GPS Update Rate", // 38 |
}; |
/* |
//------------------------------------------------------------------------------------------ |
// HoTT-Plus |
//------------------------------------------------------------------------------------------ |
char dummy=0; |
const Parameter_List_t Parameter_List[] = |
{ //offset,min,max,name,variable |
{127, 0, 247,"SP1", (unsigned char *) &PPM_in[13] }, |
{127, 0, 247,"SP2", (unsigned char *) &PPM_in[14] }, |
{127, 0, 247,"SP3", (unsigned char *) &PPM_in[15] }, |
{127, 0, 247,"SP4", (unsigned char *) &PPM_in[16] }, |
{ 0, 0, 247,"HD ", (unsigned char *) &EE_Parameter.Luftdruck_D }, |
{ 0, 0, 247,"HP ", (unsigned char *) &EE_Parameter.Hoehe_P }, |
{ 0, 0, 247,"HA ", (unsigned char *) &EE_Parameter.Hoehe_ACC_Wirkung }, |
{ 0, 0, 247,"HM ", (unsigned char *) &EE_Parameter.Hoehe_MinGas }, |
{ 0, 0, 247,"HV ", (unsigned char *) &EE_Parameter.Hoehe_HoverBand }, |
{ 0, 0, 247,"HG ", (unsigned char *) &EE_Parameter.Hoehe_Verstaerkung }, |
{ 0, 0, 247,"NG ", (unsigned char *) &EE_Parameter.NotGas }, |
{ 0, 0, 247,"StP", (unsigned char *) &EE_Parameter.Stick_P }, |
{ 0, 0, 247,"StD", (unsigned char *) &EE_Parameter.Stick_D }, |
{ 0, 0, 247,"SGP", (unsigned char *) &EE_Parameter.StickGier_P }, |
{ 0, 0, 247,"DrC", (unsigned char *) &EE_Parameter.Driftkomp }, |
{ 0, 0, 247,"GYP", (unsigned char *) &EE_Parameter.Gyro_P }, |
{ 0, 0, 247,"GYD", (unsigned char *) &EE_Parameter.Gyro_D }, |
{ 0, 0, 247,"GYI", (unsigned char *) &EE_Parameter.Gyro_I }, |
{ 0, 0, 247,"MaI", (unsigned char *) &EE_Parameter.I_Faktor }, |
{ 0, 0, 247,"GGP", (unsigned char *) &EE_Parameter.Gyro_Gier_P }, |
{ 0, 0, 247,"GGI", (unsigned char *) &EE_Parameter.Gyro_Gier_I }, |
{ 0, 0, 15,"GSt", (unsigned char *) &EE_Parameter.Gyro_Stability }, |
{ 0, 0, 247,"DSt", (unsigned char *) &EE_Parameter.DynamicStability }, |
{ 0, 0, 247,"NGG", (unsigned char *) &EE_Parameter.NaviGpsGain }, |
{ 0, 0, 247,"NWC", (unsigned char *) &EE_Parameter.NaviWindCorrection }, |
{ 0, 0, 247,"NSC", (unsigned char *) &EE_Parameter.NaviAccCompensation }, |
{ 0, 0, 247,"NAL", (unsigned char *) &EE_Parameter.NaviAngleLimitation }, |
{ 0, 0, 247,"NP ", (unsigned char *) &EE_Parameter.NaviGpsP }, |
{ 0, 0, 247,"ND ", (unsigned char *) &EE_Parameter.NaviGpsI }, |
{ 0, 0, 247,"NI ", (unsigned char *) &EE_Parameter.NaviGpsD }, |
{ 0, 0, 247,"LGL", (unsigned char *) &EE_Parameter.LoopGasLimit }, |
{ 0, 0, 247,"LHy", (unsigned char *) &EE_Parameter.LoopHysterese }, |
{ 0, 0, 247,"LTh", (unsigned char *) &EE_Parameter.LoopThreshold }, |
{ 0, 0, 0," ", (unsigned char *) &dummy }, |
{ 0, 0, 247,"FGP", (unsigned char *) &EE_Parameter.AchsKopplung1}, |
{ 0, 0, 247,"FNR", (unsigned char *) &EE_Parameter.AchsKopplung2}, |
{ 0, 0, 247,"CYC", (unsigned char *) &EE_Parameter.CouplingYawCorrection}, |
{ 0, 0, 247,"MSH", (unsigned char *) &EE_Parameter.MotorSmooth}, |
{ 0, 0, 247,"NCT", (unsigned char *) &EE_Parameter.ServoNickControl }, |
{ 0, 0, 247,"NCP", (unsigned char *) &EE_Parameter.ServoNickComp }, |
{ 0, 0, 247,"RCT", (unsigned char *) &EE_Parameter.ServoRollControl }, |
{ 0, 0, 247,"RCP", (unsigned char *) &EE_Parameter.ServoRollComp } |
}; |
unsigned char settingdest = 0; |
//------------------------------------------------------------------------------------------ |
// HoTT-Plus |
//------------------------------------------------------------------------------------------ |
*/ |
void GetHottestBl(void) |
{ |
static unsigned char search = 0,tmp_max,tmp_min,who; |
if(Motor[search].Temperature > tmp_max) { tmp_max = Motor[search].Temperature; who = search;} |
else |
if(Motor[search].Temperature) if(Motor[search].Temperature < tmp_min) tmp_min = Motor[search].Temperature; |
if(++search >= MAX_MOTORS) |
{ |
search = 0; |
if(tmp_min != 255) MinBlTemperture = tmp_min; else MinBlTemperture = 0; |
MaxBlTemperture = tmp_max; |
HottestBl = who; |
tmp_min = 255; |
tmp_max = 0; |
who = 0; |
} |
} |
//--------------------------------------------------------------- |
void Hott_ClearLine(unsigned char line) |
{ |
HoTT_printfxy(0,line," "); |
} |
//--------------------------------------------------------------- |
unsigned char HoTT_Waring(void) |
{ |
unsigned char status = 0; |
static char old_status = 0; |
static int repeat; |
//if(Parameter_UserParam1) SpeakHoTT = Parameter_UserParam1; |
ToNC_SpeakHoTT = SpeakHoTT; |
if(FC_StatusFlags & FC_STATUS_LOWBAT) |
{ |
if(LowVoltageLandingActive && (EE_Parameter.Receiver == RECEIVER_HOTT)) status = SPEAK_LANDING; |
else status = VOICE_MINIMALE_EINGANSSPANNUNG; // Jeti hat kein wort: "LANDEN" |
if(SpeakHoTT && old_status == VOICE_MINIMALE_EINGANSSPANNUNG) status = SpeakHoTT; // das soll auch noch durch kommen |
} |
else |
if(NC_ErrorCode && NC_ErrorCode < MAX_ERR_NUMBER) // Fehlercodes |
{ |
if(MotorenEin || !pgm_read_byte(&HOTT_ERROR[NC_ErrorCode][1])) status = pgm_read_byte(&HOTT_ERROR[NC_ErrorCode][0]); |
} |
if(!status) // Sprachansagen |
{ |
// if(!(GetParamByte(PID_SPEAK_HOTT_CFG) & 0x01)) SpeakHoTT = 0; // is the voice wanted? |
if(!(EE_Parameter.GlobalConfig3 & CFG3_SPEAK_ALL)) SpeakHoTT = 0; // is the voice wanted? |
else status = SpeakHoTT; |
} |
else ToNC_SpeakHoTT = status; |
if(old_status == status) // Gleichen Fehler nur alle 4 sek bringen |
{ |
if(!CheckDelay(repeat)) return(0); |
repeat = SetDelay(4000); |
} |
else repeat = SetDelay(2000); |
if(status) |
{ |
if(status == SpeakHoTT) SpeakHoTT = 0; |
} |
old_status = status; |
// DebugOut.Analog[16] = status; |
return(status); |
} |
//--------------------------------------------------------------- |
void NC_Fills_HoTT_Telemety(void) |
{ |
unsigned char *ptr = NULL; |
unsigned char max = 0,i,z; |
switch(FromNaviCtrl.Param.Byte[11]) |
{ |
case HOTT_VARIO_PACKET_ID: |
ptr = (unsigned char *) &VarioPacket; |
max = sizeof(VarioPacket); |
break; |
case HOTT_GPS_PACKET_ID: |
ptr = (unsigned char *) &GPSPacket; |
max = sizeof(GPSPacket); |
break; |
case HOTT_ELECTRIC_AIR_PACKET_ID: |
ptr = (unsigned char *) &ElectricAirPacket; |
max = sizeof(ElectricAirPacket); |
break; |
case HOTT_GENERAL_PACKET_ID: |
ptr = (unsigned char *) &HoTTGeneral; |
max = sizeof(HoTTGeneral); |
break; |
case JETI_GPS_PACKET_ID1: |
ptr = (unsigned char *) &JetiExData[14].Value; |
max = sizeof(JetiExData[14].Value); |
break; |
case JETI_GPS_PACKET_ID2: |
ptr = (unsigned char *) &JetiExData[15].Value; |
max = sizeof(JetiExData[15].Value); |
break; |
case HOTT_WPL_NAME: |
ptr = (unsigned char *) WPL_Name; |
max = sizeof(WPL_Name)-1; |
break; |
} |
z = FromNaviCtrl.Param.Byte[0]; // Data allocation |
for(i=0; i < FromNaviCtrl.Param.Byte[1]; i++) |
{ |
if(z >= max) break; |
ptr[z] = FromNaviCtrl.Param.Byte[2+i]; |
z++; |
} |
} |
unsigned int BuildHoTT_Vario(void) |
{ |
unsigned int tmp = VARIO_ZERO; |
if(VarioCharacter == '+' || VarioCharacter == '-') |
{ |
tmp = VARIO_ZERO + (AltitudeSetpointTrimming * EE_Parameter.Hoehe_Verstaerkung) / 3; |
if(tmp < VARIO_ZERO && tmp > VARIO_ZERO - 50) tmp = VARIO_ZERO - 50; // weil es sonst erst bei < 0,5m/sek piept |
} |
else |
if((VarioCharacter == ' ') && (FC_StatusFlags & FC_STATUS_FLY)) |
{ |
tmp = VARIO_ZERO + HoTTVarioMeter; |
if(tmp > VARIO_ZERO) |
{ |
if(tmp < VARIO_ZERO + 100) tmp = VARIO_ZERO; |
else tmp -= 100; |
} |
if(tmp < VARIO_ZERO) |
{ |
if(tmp > VARIO_ZERO - 100) tmp = VARIO_ZERO; |
else tmp += 100; |
} |
} |
else |
if(VarioCharacter == '^') tmp = VARIO_ZERO + FromNC_AltitudeSpeed * 10; |
else |
if(VarioCharacter == 'v') tmp = VARIO_ZERO - FromNC_AltitudeSpeed * 10; |
return(tmp); |
} |
//--------------------------------------------------------------- |
unsigned char HoTT_Telemety(unsigned char packet_request) |
{ |
unsigned char i = 0; |
static unsigned char SpeechMessage = 0; |
//Debug("rqst: %02X",packet_request); |
switch(packet_request) |
{ |
case HOTT_VARIO_PACKET_ID: |
if(GPSPacket.WarnBeep == SpeechMessage) SpeechMessage = HoTT_Waring(); // Achtung: das ist richtig hier, damit der Varioton schon vorher abgestellt wird |
VarioPacket.Altitude = HoehenWert/100 + 500; |
if(!SpeechMessage) VarioPacket.m_sec = BuildHoTT_Vario(); else VarioPacket.m_sec = VARIO_ZERO; |
VarioPacket.m_3sec = VarioPacket.m_sec; |
VarioPacket.m_10sec = VarioPacket.m_sec; |
if (VarioPacket.Altitude < VarioPacket.MinAltitude) VarioPacket.MinAltitude = VarioPacket.Altitude; |
if (VarioPacket.Altitude > VarioPacket.MaxAltitude) VarioPacket.MaxAltitude = VarioPacket.Altitude; |
VarioPacket.WarnBeep = 0;//HoTT_Waring(); |
HoTT_DataPointer = (unsigned char *) &VarioPacket; |
VarioPacket.FreeCharacters[0] = VarioCharacter; |
if(FC_StatusFlags2 & FC_STATUS2_CAREFREE) VarioPacket.FreeCharacters[1] = 'C'; else VarioPacket.FreeCharacters[1] = ' '; |
// VarioPacket.FreeCharacters[2] = ' '; |
if(NC_ErrorCode) |
{ |
VarioPacket.Text[0] = NC_ErrorCode/10 + '0'; |
VarioPacket.Text[1] = NC_ErrorCode%10 + '0'; |
VarioPacket.Text[2] = ':'; |
for(i=0; i<16;i++) VarioPacket.Text[i+3] = pgm_read_byte(&NC_ERROR_TEXT[NC_ErrorCode][i]); |
VarioPacket.Text[19] = ' '; |
VarioPacket.Text[20] = ' '; |
} |
else |
if(LowVoltageLandingActive) for(i=0; i<21;i++) VarioPacket.Text[i] = pgm_read_byte(&LANDING[i]); // no Error |
else |
if(FC_StatusFlags & FC_STATUS_LOWBAT) for(i=0; i<21;i++) VarioPacket.Text[i] = pgm_read_byte(&UNDERVOLTAGE[i]); // no Error |
else |
if(ShowSettingNameTime) // no Error |
{ |
for(i=0; i<sizeof(SETTING);i++) VarioPacket.Text[i] = pgm_read_byte(&SETTING[i]); |
VarioPacket.Text[4] = '0' + ActiveParamSet; |
for(i=0; i<sizeof(EE_Parameter.Name);i++) VarioPacket.Text[i+7] = EE_Parameter.Name[i]; // no Error |
if(FC_StatusFlags3 & FC_STATUS3_BOAT) |
{ |
VarioPacket.Text[17] = 'B'; |
VarioPacket.Text[18] = 'O'; |
VarioPacket.Text[19] = 'A'; |
VarioPacket.Text[20] = 'T'; |
} |
else |
{ |
VarioPacket.Text[18] = ' '; |
VarioPacket.Text[19] = ' '; |
VarioPacket.Text[20] = ' '; |
} |
} |
else |
if(Show_Store_Time) |
{ |
for(i=0; i<21;i++) VarioPacket.Text[i] = pgm_read_byte(&STORE[i]); // no Error and not calibrated |
if(Show_Store_Value < 10) VarioPacket.Text[18] = Show_Store_Value + '0'; |
else |
{ |
VarioPacket.Text[18] = Show_Store_Value/10 + '0'; |
VarioPacket.Text[19] = Show_Store_Value%10 + '0'; |
} |
} |
else |
if(Show_Load_Time) |
{ |
for(i=0; i<21;i++) VarioPacket.Text[i] = pgm_read_byte(&LOAD[i]); // no Error and not calibrated |
if(Show_Load_Value < 10) VarioPacket.Text[17] = Show_Load_Value + '0'; |
else |
{ |
VarioPacket.Text[17] = Show_Load_Value/10 + '0'; |
VarioPacket.Text[18] = Show_Load_Value%10 + '0'; |
} |
} |
else |
if(NaviData_WaypointNumber) |
{ |
unsigned int tmp_int; |
unsigned char tmp; |
VarioPacket.Text[0] = 'W'; VarioPacket.Text[1] = 'P'; |
VarioPacket.Text[2] = ' '; |
VarioPacket.Text[3] = '0'+(NaviData_WaypointIndex) / 10; |
VarioPacket.Text[4] = '0'+(NaviData_WaypointIndex) % 10; |
VarioPacket.Text[5] = '/'; |
VarioPacket.Text[6] = '0'+(NaviData_WaypointNumber) / 10; |
VarioPacket.Text[7] = '0'+(NaviData_WaypointNumber) % 10; |
VarioPacket.Text[8] = ' '; |
tmp_int = NaviData_TargetDistance; |
if(tmp_int > 1000) { VarioPacket.Text[9] = '0'+(tmp_int) / 1000; tmp_int %= 1000;} |
else VarioPacket.Text[9] = ' '; |
if(tmp_int > 100) { VarioPacket.Text[10] = '0'+(tmp_int) / 100; tmp_int %= 100;} |
else VarioPacket.Text[10] = ' '; |
VarioPacket.Text[11] = '0'+(tmp_int) / 10; |
VarioPacket.Text[12] = '0'+(tmp_int) % 10; |
VarioPacket.Text[13] = 'm'; |
VarioPacket.Text[14] = ' '; |
tmp = NaviData_TargetHoldTime; |
if(tmp > 100) { VarioPacket.Text[15] = '0'+(tmp) / 100; tmp %= 100;} else VarioPacket.Text[15] = ' '; |
VarioPacket.Text[16] = '0'+(tmp) / 10; |
VarioPacket.Text[17] = '0'+(tmp) % 10; |
VarioPacket.Text[18] = 's'; |
VarioPacket.Text[19] = ' '; |
VarioPacket.Text[20] = ' '; |
} |
else |
if(NC_To_FC_Flags & NC_TO_FC_SIMULATION_ACTIVE) |
{ |
for(i=0; i<21;i++) VarioPacket.Text[i] = pgm_read_byte(&SIMULATION[i]); |
} |
else |
if(!CalibrationDone) |
{ |
for(i=0; i<17;i++) VarioPacket.Text[i] = pgm_read_byte(&MIKROKOPTER[i+2]); // no Error and not calibrated |
VarioPacket.Text[16] = '0'+VERSION_MAJOR; |
VarioPacket.Text[17] = '.'; |
VarioPacket.Text[18] = '0'+VERSION_MINOR/10; |
VarioPacket.Text[19] = '0'+VERSION_MINOR%10; |
VarioPacket.Text[20] = 'a'+VERSION_PATCH; |
} |
else |
{ |
if(FC_StatusFlags3 & FC_STATUS3_BOAT) for(i=0; i<21;i++) VarioPacket.Text[i] = pgm_read_byte(&BOAT_MODE[i]); // no Error |
else for(i=0; i<21;i++) VarioPacket.Text[i] = pgm_read_byte(&MIKROKOPTER[i]); // no Error |
if(FC_StatusFlags3 & FC_STATUS3_REDUNDANCE_AKTIVE) VarioPacket.Text[0] = 'R'; |
} |
return(sizeof(VarioPacket)); |
break; |
case HOTT_GPS_PACKET_ID: |
GPSPacket.Altitude = HoehenWert/100 + 500; |
// GPSPacket.Distance = GPSInfo.HomeDistance/10; // macht die NC |
// GPSPacket.Heading = GPSInfo.HomeBearing/2; // macht die NC |
// GPSPacket.Speed = (GPSInfo.Speed * 36) / 10; // macht die NC |
GPSPacket.WarnBeep = SpeechMessage; |
if(!GPSPacket.WarnBeep) GPSPacket.m_sec = BuildHoTT_Vario(); else GPSPacket.m_sec = VARIO_ZERO; |
GPSPacket.m_3sec = 120; |
GPSPacket.NumOfSats = GPSInfo.NumOfSats; |
if(GPSInfo.Flags & FLAG_DIFFSOLN) GPSPacket.SatFix = 'D'; |
else |
if(GPSInfo.SatFix == SATFIX_3D) GPSPacket.SatFix = ' '; |
else GPSPacket.SatFix = '!'; |
HoTT_DataPointer = (unsigned char *) &GPSPacket; |
GPSPacket.FreeCharacters[0] = NC_GPS_ModeCharacter; |
GPSPacket.FreeCharacters[2] = GPSPacket.SatFix; |
GPSPacket.HomeDirection = GPSInfo.HomeBearing / 2;//230; |
return(sizeof(GPSPacket)); |
break; |
case HOTT_ELECTRIC_AIR_PACKET_ID: |
GetHottestBl(); |
ElectricAirPacket.Altitude = HoehenWert/100 + 500; |
ElectricAirPacket.Battery1 = UBat; |
ElectricAirPacket.Battery2 = UBat; |
ElectricAirPacket.VoltageCell1 = CompassCorrected / 2; |
ElectricAirPacket.VoltageCell8 = ElectricAirPacket.VoltageCell1; |
ElectricAirPacket.VoltageCell6 = GPSInfo.HomeBearing / 2; |
ElectricAirPacket.VoltageCell7 = GPSInfo.HomeDistance/20; |
ElectricAirPacket.VoltageCell13 = ElectricAirPacket.VoltageCell6; |
ElectricAirPacket.VoltageCell14 = ElectricAirPacket.VoltageCell7; |
if(!SpeechMessage) ElectricAirPacket.m_sec = BuildHoTT_Vario(); else ElectricAirPacket.m_sec = VARIO_ZERO; |
ElectricAirPacket.m_3sec = 120; |
ElectricAirPacket.InputVoltage = UBat; |
ElectricAirPacket.Temperature1 = MinBlTemperture + 20; |
ElectricAirPacket.Temperature2 = MaxBlTemperture + 20; |
ElectricAirPacket.Capacity = Capacity.UsedCapacity/10; |
ElectricAirPacket.WarnBeep = 0;//HoTT_Waring(); |
//ElectricAirPacket.WarnBeep = SpeechMessage; |
ElectricAirPacket.Current = Capacity.ActualCurrent; |
HoTT_DataPointer = (unsigned char *) &ElectricAirPacket; |
ElectricAirPacket.FlightTimeMinutes = FlugSekunden / 60; |
ElectricAirPacket.FlightTimeSeconds = FlugSekunden % 60; |
return(sizeof(ElectricAirPacket)); |
break; |
case HOTT_GENERAL_PACKET_ID: |
GetHottestBl(); |
HoTTGeneral.Rpm = GPSInfo.HomeDistance/100; |
HoTTGeneral.VoltageCell1 = CompassCorrected / 2; |
HoTTGeneral.VoltageCell2 = KompassValue / 2; |
//HoTTGeneral.VoltageCell3 = Magnetstaerke -> macht NC |
//HoTTGeneral.VoltageCell4 = Inclinition -> macht NC |
HoTTGeneral.VoltageCell5 = DebugOut.Analog[28]; // I2C ErrorCounter |
HoTTGeneral.VoltageCell6 = GPSInfo.HomeBearing / 2; |
if(UBat > BattLowVoltageWarning + 2) HoTTGeneral.FuelPercent = (UBat - (BattLowVoltageWarning + 2)) * 3; |
else HoTTGeneral.FuelPercent = 0; |
if(HoTTGeneral.FuelPercent > 100) HoTTGeneral.FuelPercent = 100; |
HoTTGeneral.FuelCapacity = NC_ErrorCode;//HoehenWert/100; // Oelpegel |
// if(HoTTGeneral.FuelCapacity < 0) HoTTGeneral.FuelCapacity = 0; |
HoTTGeneral.Altitude = HoehenWert/100 + 500; |
HoTTGeneral.Battery1 = UBat; |
HoTTGeneral.Battery2 = UBat; |
if(!SpeechMessage) HoTTGeneral.m_sec = BuildHoTT_Vario(); else HoTTGeneral.m_sec = VARIO_ZERO; |
HoTTGeneral.m_3sec = 120 + SpeechMessage; |
HoTTGeneral.InputVoltage = UBat; |
HoTTGeneral.Temperature1 = MinBlTemperture + 20; |
HoTTGeneral.Temperature2 = MaxBlTemperture + 20; |
HoTTGeneral.Capacity = Capacity.UsedCapacity/10; |
HoTTGeneral.WarnBeep = 0; |
HoTTGeneral.Current = Capacity.ActualCurrent; |
//HoTTGeneral.ErrorNumber = HoTTErrorCode(); |
HoTT_DataPointer = (unsigned char *) &HoTTGeneral; |
return(sizeof(HoTTGeneral)); |
break; |
default: return(0); |
} |
} |
//--------------------------------------------------------------- |
void HoTT_Menu(void) |
{ |
static unsigned char line, page = 0,show_current = 0,show_mag = 0, show_poti = 0,hyterese = 1; |
unsigned char tmp; |
HoTTVarioMeter = (HoTTVarioMeter * 7 + VarioMeter) / 8; |
static int delay; |
// if(HottKeyboard) {beeptime = 1000;}; |
switch(page) |
{ |
case 0: |
switch(line++) |
{ |
case 0: |
if(FC_StatusFlags & FC_STATUS_LOWBAT) |
HoTT_printfxy_BLINK(0,0," %2i.%1iV ",UBat/10, UBat%10) |
else |
HoTT_printfxy(0,0," %2i.%1iV ",UBat/10, UBat%10) |
if(Parameter_GlobalConfig & CFG_HOEHENREGELUNG) |
{ |
if(HoehenReglerAktiv) HoTT_printfxy_INV(10,0,"ALT:%4im %c", (int16_t)(HoehenWert/100),VarioCharacter) |
else HoTT_printfxy(10,0,"ALT:%4im ", (int16_t)(HoehenWert/100)) |
} |
else HoTT_printfxy(10,0,"ALT:---- "); |
break; |
case 1: |
if(FC_StatusFlags & FC_STATUS_LOWBAT) |
HoTT_printfxy_BLINK(0,1," %2i:%02i ",FlugSekunden/60,FlugSekunden%60) |
else HoTT_printfxy(0,1," %2i:%02i ",FlugSekunden/60,FlugSekunden%60); |
HoTT_printfxy(10,1,"DIR: %3d%c",CompassCorrected, HoTT_GRAD); |
if(FC_StatusFlags2 & FC_STATUS2_CAREFREE) HoTT_printfxy_INV(20,1,"C") else HoTT_printfxy(20,1," "); |
break; |
case 2: |
if(FC_StatusFlags & FC_STATUS_LOWBAT) |
HoTT_printfxy_BLINK(0,2," %5i ",Capacity.UsedCapacity) |
else HoTT_printfxy(0,2," %5i ",Capacity.UsedCapacity); |
HoTT_printfxy(12,2,"I:%2i.%1iA ",Capacity.ActualCurrent/10, Capacity.ActualCurrent%10); |
break; |
case 3: |
HoTT_printfxy(9,0,":"); |
HoTT_printfxy(9,1,":"); |
HoTT_printfxy(9,2,":"); |
HoTT_printfxy(0,3,"---------+-----------"); |
// HoTT_printfxy(0,3,"---------------------"); |
HoTT_printfxy(0,6,"---------------------"); |
break; |
case 4: |
if(NaviDataOkay) |
{ |
HoTT_printfxy(9,4,":"); |
HoTT_printfxy(0,4,"SAT:%2d ",GPSInfo.NumOfSats); |
HoTT_printfxy(10,4,"DIST:%3dm",GPSInfo.HomeDistance/10); |
switch (GPSInfo.SatFix) |
{ |
case SATFIX_3D: |
if(GPSInfo.Flags & FLAG_DIFFSOLN) HoTT_printfxy(7,4,"D ") |
else HoTT_printfxy(7,4,"3D"); |
break; |
default: |
HoTT_printfxy_BLINK(7,4,"!!"); |
break; |
} |
} |
else |
{ |
Hott_ClearLine(4); |
} |
break; |
case 5: |
if(NaviDataOkay) |
{ |
if(show_mag) |
{ |
HoTT_printfxy(0,5,"MAG:%3u%% ",EarthMagneticField); |
HoTT_printfxy(12,5,"HM:%3d%c %c", GPSInfo.HomeBearing, HoTT_GRAD, NC_GPS_ModeCharacter); |
HoTT_printfxy(9,5,"incl:%2d%c(%2i)",EarthMagneticInclination, HoTT_GRAD,EarthMagneticInclinationTheoretic); |
} |
else |
{ |
HoTT_printfxy(0,5," %2um/s: HM:%3d%c %c",GPSInfo.Speed, GPSInfo.HomeBearing, HoTT_GRAD, NC_GPS_ModeCharacter); |
} |
} |
else Hott_ClearLine(5); |
break; |
case 6: |
break; |
case 7: if(NC_ErrorCode) |
{ |
if(HoTTBlink && NC_ErrorCode < MAX_ERR_NUMBER) |
{ |
Hott_ClearLine(7); |
HoTT_printfxy_INV(0,7,"ERR: %2d !",NC_ErrorCode); |
} |
else |
{ |
HoTT_printfxy(0,7,"ERR: "); _printf_P(&LIBFC_HoTT_Putchar, NC_ERROR_TEXT[NC_ErrorCode] , 0);}; |
} |
else |
if(FC_StatusFlags & FC_STATUS_LOWBAT) HoTT_printfxy(1,7,"!! LiPo voltage !!") |
else HoTT_printfxy(0,7," www.MikroKopter.de "); |
break; |
case 8: //ASCIIPacket.WarnBeep = HoTT_Waring(); |
// ASCIIPacket.WarnBeep = Parameter_UserParam1; |
case 9: |
case 10: |
case 11: |
case 12: |
case 13: |
case 14: |
case 15: |
case 16: |
if(HottKeyboard == HOTT_KEY_DOWN) { LIBFC_HoTT_Clear(); page = 5; line = 0;} |
else |
if(HottKeyboard == HOTT_KEY_SET) { if(show_mag) show_mag = 0; else show_mag = 1;} |
else |
if(HottKeyboard == HOTT_KEY_LEFT) { LIBFC_HoTT_Clear(); page = 1; line = 0;}; |
HottKeyboard = 0; |
break; |
default: line = 0; |
break; |
} |
break; |
case 1: |
switch(line++) |
{ |
case 0: |
if(FC_StatusFlags & FC_STATUS_LOWBAT) |
HoTT_printfxy_BLINK(0,0," %2i:%02i %2i.%1iV %4imAh",FlugSekunden/60,FlugSekunden%60,UBat/10, UBat%10,Capacity.UsedCapacity) |
else HoTT_printfxy(0,0," %2i:%02i %2i.%1iV %4imAh",FlugSekunden/60,FlugSekunden%60,UBat/10, UBat%10,Capacity.UsedCapacity); |
break; |
case 1: |
HoTT_printfxy(0,1,"DIR:%3d%c",CompassCorrected, HoTT_GRAD); |
if(Parameter_GlobalConfig & CFG_HOEHENREGELUNG) |
{ |
if(HoehenReglerAktiv) HoTT_printfxy_INV(10,1,"ALT:%4im", (int16_t)(HoehenWert/100)) |
else HoTT_printfxy(10,1,"ALT:%4im", (int16_t)(HoehenWert/100)) |
} |
else HoTT_printfxy(10,1,"ALT:---- "); |
HoTT_printfxy(20,1,"%c",VarioCharacter); |
break; |
case 2: |
if(NaviDataOkay) |
{ |
HoTT_printfxy(1,2,"HM:%3d%c DIST:%3dm %c", GPSInfo.HomeBearing, HoTT_GRAD, GPSInfo.HomeDistance/10, NC_GPS_ModeCharacter); |
} |
else |
{ |
Hott_ClearLine(2); |
} |
break; |
case 3: |
HoTT_printfxy(0,3,"PWR:%2i.%1iA (%iW) ",Capacity.ActualCurrent/10, Capacity.ActualCurrent%10,Capacity.ActualPower); |
if(FC_StatusFlags2 & FC_STATUS2_CAREFREE) HoTT_printfxy_INV(19,3,"CF") else HoTT_printfxy(19,3," "); |
break; |
case 4: |
if(NaviDataOkay) |
{ |
HoTT_printfxy(0,4,"GPS:%2um/s SAT:%d ",GPSInfo.Speed,GPSInfo.NumOfSats); |
switch (GPSInfo.SatFix) |
{ |
case SATFIX_3D: |
HoTT_printfxy(16,4," 3D "); |
break; |
//case SATFIX_2D: |
//case SATFIX_NONE: |
default: |
HoTT_printfxy_BLINK(16,4,"NOFIX"); |
break; |
} |
if(GPSInfo.Flags & FLAG_DIFFSOLN) |
{ |
HoTT_printfxy(16,4,"DGPS "); |
} |
} |
else |
{ //012345678901234567890 |
HoTT_printfxy(0,4," No NaviCtrl "); |
} |
break; |
case 5: |
if(show_current) |
{ |
// HoTT_printfxy(0,5,"%2i.%i %2i.%i %2i.%i %2i.%iA", Motor[0].Current/10,Motor[0].Current%10,Motor[1].Current/10,Motor[1].Current%10,Motor[2].Current/10,Motor[2].Current%10,Motor[3].Current/10,Motor[3].Current%10); |
HoTT_printfxy(0,5,"%2i.%i %2i.%i %2i.%i %2i.%iA", BL3_Current(0)/10,BL3_Current(0)%10,BL3_Current(1)/10,BL3_Current(1)%10,BL3_Current(2)/10,BL3_Current(2)%10,BL3_Current(3)/10,BL3_Current(3)%10); |
} |
else |
{ |
HoTT_printfxy(0,5,"%3i %3i %3i %3i%cC", Motor[0].Temperature, Motor[1].Temperature, Motor[2].Temperature, Motor[3].Temperature,HoTT_GRAD); |
} |
break; |
case 6: |
if(show_current) |
{ |
if(RequiredMotors == 4) Hott_ClearLine(6); |
else |
// if(RequiredMotors == 6) HoTT_printfxy(0,6,"%2i.%i %2i.%iA", Motor[4].Current/10,Motor[4].Current%10,Motor[5].Current/10,Motor[5].Current%10) |
if(RequiredMotors == 6) HoTT_printfxy(0,6,"%2i.%i %2i.%iA", BL3_Current(4)/10,BL3_Current(4)%10, BL3_Current(5)/10,BL3_Current(5)%10) |
else |
// if(RequiredMotors > 6) HoTT_printfxy(0,6,"%2i.%i %2i.%i %2i.%i %2i.%iA", Motor[4].Current/10,Motor[4].Current%10,Motor[5].Current/10,Motor[5].Current%10,Motor[6].Current/10,Motor[6].Current%10,Motor[7].Current/10,Motor[7].Current%10); |
if(RequiredMotors > 6) HoTT_printfxy(0,6,"%2i.%i %2i.%i %2i.%i %2i.%iA", BL3_Current(4)/10,BL3_Current(4)%10,BL3_Current(5)/10,BL3_Current(5)%10,BL3_Current(6)/10,BL3_Current(6)%10,BL3_Current(7)/10,BL3_Current(7)%10,BL3_Current(8)/10,BL3_Current(8)%10); |
} |
else |
{ |
if(RequiredMotors == 4) Hott_ClearLine(6); |
else |
if(RequiredMotors == 6) HoTT_printfxy(0,6,"%3i %3i%cC ", Motor[4].Temperature, Motor[5].Temperature,HoTT_GRAD) |
else |
if(RequiredMotors > 6) HoTT_printfxy(0,6,"%3i %3i %3i %3i%cC", Motor[4].Temperature, Motor[5].Temperature, Motor[6].Temperature, Motor[7].Temperature,HoTT_GRAD); |
} |
break; |
case 7: if(NC_ErrorCode) |
{ |
if(HoTTBlink && NC_ErrorCode < MAX_ERR_NUMBER) |
{ |
Hott_ClearLine(7); |
HoTT_printfxy_INV(0,7,"ERR: %2d !",NC_ErrorCode); |
} |
else |
{ |
HoTT_printfxy(0,7,"ERR: "); _printf_P(&LIBFC_HoTT_Putchar, NC_ERROR_TEXT[NC_ErrorCode] , 0);}; |
} |
else |
if(FC_StatusFlags & FC_STATUS_LOWBAT) HoTT_printfxy(1,7,"!! LiPo voltage !!") |
else HoTT_printfxy(0,7," www.MikroKopter.de "); |
break; |
case 8: // ASCIIPacket.WarnBeep = HoTT_Waring(); |
// ASCIIPacket.WarnBeep = Parameter_UserParam1; |
case 9: |
case 10: |
case 11: |
case 12: |
case 13: |
case 14: |
case 15: |
case 16: |
if(HottKeyboard == HOTT_KEY_SET) { if(show_current) show_current = 0; else show_current = 1; Hott_ClearLine(5); Hott_ClearLine(6);} |
else |
if(HottKeyboard == HOTT_KEY_LEFT) { LIBFC_HoTT_Clear(); page++; line = 0;} |
else |
if(HottKeyboard == HOTT_KEY_RIGHT) { LIBFC_HoTT_Clear(); page--; line = 0;} |
//if(HottKeyboard) HoTT_printfxy(15,6,"%KEY:%02x ",HottKeyboard); |
HottKeyboard = 0; |
break; |
default: line = 0; |
break; |
} |
break; |
case 2: |
switch(line++) |
{ |
case 0: |
HoTT_printfxy_INV(0,0,"Setting:%u %s ",ActiveParamSet,EE_Parameter.Name); |
break; |
case 1: HoTT_printfxy(0,1,"Min:%2i.%1iV %s ",BattLowVoltageWarning/10, BattLowVoltageWarning%10, Mixer.Name); |
break; |
case 2: HoTT_printfxy(0,2,"ALT:"); |
if(Parameter_GlobalConfig & CFG_HOEHENREGELUNG) |
{ |
if(!(EE_Parameter.GlobalConfig & CFG_HOEHEN_SCHALTER)) HoTT_printf("POTI:%3u ", Parameter_HoehenSchalter) |
else |
{ |
if(Parameter_HoehenSchalter > 50) HoTT_printf("(ON) ") else HoTT_printf("(OFF) "); |
if((Parameter_ExtraConfig & CFG2_HEIGHT_LIMIT)) HoTT_printf("LIMIT", Parameter_HoehenSchalter) |
else HoTT_printf("VARIO", Parameter_HoehenSchalter); |
} |
} |
else |
HoTT_printf("DISABLED"); |
break; |
case 3: HoTT_printfxy(0,3,"CF:"); |
if(!EE_Parameter.CareFreeChannel) HoTT_printf("DISABLED") |
else |
{ |
if(CareFree) HoTT_printf(" (ON) ") else HoTT_printf(" (OFF)"); |
if(EE_Parameter.ExtraConfig & CFG_LEARNABLE_CAREFREE) HoTT_printf(" TEACH"); |
} |
break; |
case 4: HoTT_printfxy(0,4,"GPS:"); |
if(!(Parameter_GlobalConfig & CFG_GPS_AKTIV)) HoTT_printf("DISABLED") |
else |
{ |
tmp = GetChannelValue(EE_Parameter.NaviGpsModeChannel); |
if(tmp < 50) HoTT_printf("(FREE)") |
else |
if(tmp >= 180) HoTT_printf("(HOME)") |
else |
if(EE_Parameter.ExtraConfig & CFG_GPS_AID) HoTT_printf("(AID) ") |
else HoTT_printf("(HOLD)") |
} |
if(EE_Parameter.FailSafeTime) HoTT_printfxy(10,4," FS:%usek ",EE_Parameter.FailSafeTime) |
break; |
case 5: HoTT_printfxy(0,5,"HOME ALT:"); |
if(EE_Parameter.ComingHomeAltitude) HoTT_printf("%um",EE_Parameter.ComingHomeAltitude) else HoTT_printf("HOLD "); |
break; |
case 6: |
if(!show_poti) |
{ |
HoTT_printfxy(0,6,"Ni:%4i Ro:%4i C:%3i",ChannelNick,ChannelRoll, Parameter_ServoNickControl); |
HoTT_printfxy(0,7,"Gs:%4i Ya:%4i ",ChannelGas+127,ChannelYaw); |
} |
else |
{ |
HoTT_printfxy(0,6,"P1:%4i P2:%4i 3:%3i",Poti1,Poti2, Poti3); |
HoTT_printfxy(0,7,"P4:%4i P5:%4i 6:%3i",Poti4,Poti5, Poti6); |
} |
break; |
case 7: //HoTT_printfxy(0,6,"WARNINGS:"); |
if(HoTTBlink) |
{ |
LIBFC_HoTT_SetPos(6 * 21); |
// if(!(Parameter_GlobalConfig & CFG_ACHSENKOPPLUNG_AKTIV)) HoTT_printf_BLINK("COUPLING OFF! "); |
if(EE_Parameter.BitConfig & (CFG_LOOP_LINKS | CFG_LOOP_RECHTS | CFG_LOOP_UNTEN | CFG_LOOP_OBEN)) HoTT_printf_BLINK("LOOPING! "); |
if(Parameter_GlobalConfig & CFG_HEADING_HOLD) HoTT_printf_BLINK("HH! "); |
if(!(Parameter_GlobalConfig & CFG_KOMPASS_AKTIV)) HoTT_printf_BLINK("COMPASS OFF! "); |
} |
break; |
case 8: //ASCIIPacket.WarnBeep = HoTT_Waring(); |
break; |
case 9: |
case 10: |
case 11: |
case 12: |
case 13: |
case 14: |
case 15: |
case 16: |
if(HottKeyboard == HOTT_KEY_SET) { if(show_poti) show_poti = 0; else show_poti = 1; Hott_ClearLine(6); Hott_ClearLine(7);} |
else |
if(HottKeyboard == HOTT_KEY_LEFT) { LIBFC_HoTT_Clear(); page++; line = 0;} |
else |
if(HottKeyboard == HOTT_KEY_RIGHT) { LIBFC_HoTT_Clear(); page--; line = 0;}; |
HottKeyboard = 0; |
break; |
default: line = 0; |
break; |
} |
break; |
case 3: |
switch(line++) |
{ |
static unsigned char load_waypoint_tmp2 = 1, changed2; |
case 0: |
HoTT_printfxy(0,0,"Load Waypoints"); |
HoTT_printfxy(0,1,"(Relative Positions)"); |
// HoTT_printfxy(0,1,"(Absolute)"); |
break; |
case 1: |
if(NaviData_WaypointNumber) HoTT_printfxy(0,6,"Active WP:%2d/%d ",NaviData_WaypointIndex,NaviData_WaypointNumber) |
else HoTT_printfxy(0,6,"No WPs active ") |
break; |
case 2: |
HoTT_printfxy(0,7,"%2i.%1iV ",UBat/10, UBat%10) |
HoTT_printfxy(11,7,"%s",WPL_Name) |
case 3: |
case 4: |
case 5: |
if(load_waypoint_tmp2) |
{ |
if(changed2 && HoTTBlink) HoTT_printfxy(10,3," ") |
else HoTT_printfxy(10,3,"%2i ",load_waypoint_tmp2); |
HoTT_printfxy(0,3,"Load list:") |
} |
else |
{ |
HoTT_printfxy(0,3,"Load list: -- "); |
} |
if(NaviData_MaxWpListIndex == 0) HoTT_printfxy(0,4,"No SD-Card ") |
else |
{ |
if(GPSInfo.SatFix == SATFIX_3D) |
{ |
if(changed2 && load_waypoint_tmp2) HoTT_printfxy(0,4,"(Set -> Load)") |
else HoTT_printfxy(0,4," "); |
if(HottKeyboard == HOTT_KEY_SET) { if(load_waypoint_tmp2) ToNC_Load_WP_List = load_waypoint_tmp2 | 128; changed2 = 0;} |
} else HoTT_printfxy(0,4,"!No GPS-Fix! "); |
} |
if(HottKeyboard == HOTT_KEY_UP && load_waypoint_tmp2 < NaviData_MaxWpListIndex) { changed2 = 1; load_waypoint_tmp2++;HoTTBlink = 0;} |
if(HottKeyboard == HOTT_KEY_DOWN && load_waypoint_tmp2 > 1) { changed2 = 1; load_waypoint_tmp2--;HoTTBlink = 0;}; |
if(HottKeyboard == HOTT_KEY_LEFT) { LIBFC_HoTT_Clear(); page++; line = 0;} |
if(HottKeyboard == HOTT_KEY_RIGHT) { LIBFC_HoTT_Clear(); page--; line = 0;}; |
HottKeyboard = 0; |
break; |
default: line = 0; |
break; |
} |
break; |
case 4: |
switch(line++) |
{ |
static unsigned char load_waypoint_tmp = 1, changed; |
case 0: |
HoTT_printfxy(0,0,"Load Waypoints"); |
HoTT_printfxy(0,1,"(Fixed Positions)"); |
break; |
case 1: |
if(NaviData_WaypointNumber) HoTT_printfxy(0,6,"Active WP:%2d/%d ",NaviData_WaypointIndex,NaviData_WaypointNumber) |
else HoTT_printfxy(0,6,"No WPs active ") |
break; |
case 2: |
HoTT_printfxy(0,7,"%2i.%1iV ",UBat/10, UBat%10) |
HoTT_printfxy(11,7,"%s",WPL_Name) |
case 3: |
case 4: |
case 5: |
HoTT_printfxy(0,3,"Load list:") |
if(load_waypoint_tmp) |
{ |
if(changed && HoTTBlink) HoTT_printfxy(10,3," ") |
else HoTT_printfxy(10,3,"%2d (FIX)",load_waypoint_tmp); |
} |
else |
{ |
HoTT_printfxy(10,3," --") |
} |
if(NaviData_MaxWpListIndex == 0) HoTT_printfxy(0,4,"No SD-Card ") |
else |
{ |
if(changed && load_waypoint_tmp) HoTT_printfxy(0,4,"(Set -> Load)") |
else HoTT_printfxy(0,4," "); |
} |
if(HottKeyboard == HOTT_KEY_UP && load_waypoint_tmp < NaviData_MaxWpListIndex) { changed = 1; load_waypoint_tmp++; HoTTBlink = 0;} |
if(HottKeyboard == HOTT_KEY_DOWN && load_waypoint_tmp > 1) { changed = 1; load_waypoint_tmp--; HoTTBlink = 0;}; |
if(HottKeyboard == HOTT_KEY_SET) { if(load_waypoint_tmp) ToNC_Load_WP_List = load_waypoint_tmp; changed = 0;} |
if(HottKeyboard == HOTT_KEY_LEFT) { LIBFC_HoTT_Clear(); page++; line = 0;} |
if(HottKeyboard == HOTT_KEY_RIGHT) { LIBFC_HoTT_Clear(); page--; line = 0;}; |
HottKeyboard = 0; |
break; |
default: line = 0; |
break; |
} |
break; |
case 5: |
switch(line++) |
{ |
static unsigned char wp_tmp, changed; |
case 0: |
HoTT_printfxy(0,0,"Store single Position"); |
// HoTT_printfxy(0,1,"(Fixed Positions)"); |
break; |
case 1: |
HoTT_printfxy(0,2," %2i.%1iV ",UBat/10, UBat%10) |
HoTT_printfxy(0,3," %2i:%02i ",FlugSekunden/60,FlugSekunden%60); |
// HoTT_printfxy(0,4,"Dist:%3dm",NaviData_TargetDistance) |
break; |
case 2: |
HoTT_printfxy(11,2,"ALT:%4im", (int16_t)(HoehenWert/100)) |
HoTT_printfxy(11,3,"DIR: %3d%c",CompassCorrected, HoTT_GRAD); |
HoTT_printfxy(11,4,"Cam: %3i",Parameter_ServoNickControl); |
break; |
case 3: |
case 4: |
case 5: |
HoTT_printfxy(0,6,"Store point:") |
if(wp_tmp) |
{ |
if(changed && HoTTBlink) HoTT_printfxy(13,6," ") |
else HoTT_printfxy(13,6,"%2d ",wp_tmp); |
} |
else |
{ |
HoTT_printfxy(13,6,"--") |
} |
if(GPSInfo.SatFix == SATFIX_3D) |
{ |
if(NaviData_MaxWpListIndex == 0) HoTT_printfxy(0,7,"No SD-Card ") |
else |
{ |
if(changed && wp_tmp) HoTT_printfxy(0,7,"(Set -> Store)") |
else Hott_ClearLine(7); |
} |
if(HottKeyboard == HOTT_KEY_SET) { if(wp_tmp) ToNC_Store_SingePoint = wp_tmp; changed = 0;} |
} |
else HoTT_printfxy(0,7,"!No GPS-Fix! "); |
if(HottKeyboard == HOTT_KEY_UP && wp_tmp < NaviData_MaxWpListIndex) { changed = 1; wp_tmp++; HoTTBlink = 0;} |
if(HottKeyboard == HOTT_KEY_DOWN && wp_tmp > 1) { changed = 1; wp_tmp--; HoTTBlink = 0;}; |
if(HottKeyboard == HOTT_KEY_LEFT) { LIBFC_HoTT_Clear(); page++; line = 0;} |
if(HottKeyboard == HOTT_KEY_RIGHT) { LIBFC_HoTT_Clear(); page--; line = 0;}; |
HottKeyboard = 0; |
// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
// Bedienung per Taster am Sender |
if(PPM_in[EE_Parameter.MenuKeyChannel] > 50) // |
{ |
hyterese = 2; |
if(CheckDelay(delay)) { wp_tmp = 0; hyterese = 1;} |
} |
else |
if(PPM_in[EE_Parameter.MenuKeyChannel] < -50) |
{ |
delay = SetDelay(2500); |
if(hyterese == 2 && (wp_tmp < NaviData_MaxWpListIndex)) |
{ |
wp_tmp++; |
ToNC_Store_SingePoint = wp_tmp; |
changed = 0; |
} |
hyterese = 0; |
} |
// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
break; |
default: line = 0; |
break; |
} |
break; |
case 6: |
switch(line++) |
{ |
static unsigned char wp_tmp, changed; |
case 0: |
HoTT_printfxy(0,0,"Load single Position"); |
// HoTT_printfxy(0,1,"(Fixed Positions)"); |
break; |
case 1: |
HoTT_printfxy(0,2," %2i.%1iV ",UBat/10, UBat%10) |
HoTT_printfxy(0,3," %2i:%02i ",FlugSekunden/60,FlugSekunden%60); |
// HoTT_printfxy(0,4,"Dist:%3dm",NaviData_TargetDistance) |
if(NaviData_WaypointNumber) HoTT_printfxy(0,5,"WP:%2d/%d Dist:%3dm ",NaviData_WaypointIndex,NaviData_WaypointNumber,NaviData_TargetDistance) |
else Hott_ClearLine(5); |
break; |
case 2: |
if(FromNC_AltitudeSpeed) |
HoTT_printfxy(8,2,"ALT:%4i/%im ", (int16_t)(HoehenWert/100),(int16_t)(FromNC_AltitudeSetpoint/100)) |
else |
HoTT_printfxy(8,2,"ALT:%4im ",(int16_t)(HoehenWert/100)) |
HoTT_printfxy(8,3,"DIR: %3d%c",CompassCorrected, HoTT_GRAD); |
HoTT_printfxy(8,4,"Cam: %3i",Parameter_ServoNickControl); |
break; |
// HoTT_printfxy(11,7,"%s",WPL_Name) |
case 3: |
case 4: |
case 5: |
if(HottKeyboard) DebugOut.Analog[17]++; |
HoTT_printfxy(0,6,"load point:") |
if(wp_tmp) |
{ |
if(changed && HoTTBlink) HoTT_printfxy(11,6," ") |
else HoTT_printfxy(11,6,"%2d",wp_tmp); |
} |
else |
{ |
HoTT_printfxy(11,6,"--") |
} |
if(NaviData_MaxWpListIndex == 0) HoTT_printfxy(0,7,"No SD-Card ") |
else |
{ |
if(changed && wp_tmp) HoTT_printfxy(0,7,"(Set -> Load)") |
else |
{ |
Hott_ClearLine(7); |
if(NaviData_WaypointNumber) HoTT_printfxy(0,7,"%s",WPL_Name); |
} |
} |
if(HottKeyboard == HOTT_KEY_UP && wp_tmp < NaviData_MaxWpListIndex) { changed = 1; wp_tmp++; HoTTBlink = 0;} |
if(HottKeyboard == HOTT_KEY_DOWN && wp_tmp > 1) { changed = 1; wp_tmp--; HoTTBlink = 0;}; |
if(HottKeyboard == HOTT_KEY_SET) { if(wp_tmp) ToNC_Load_SingePoint = wp_tmp; changed = 0;} |
if(HottKeyboard == HOTT_KEY_LEFT) { LIBFC_HoTT_Clear(); page++; line = 0;} |
if(HottKeyboard == HOTT_KEY_RIGHT) { LIBFC_HoTT_Clear(); page--; line = 0;}; |
HottKeyboard = 0; |
// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
// Bedienung per Taster am Sender |
if(PPM_in[EE_Parameter.MenuKeyChannel] > 50) // |
{ |
hyterese = 2; |
if(CheckDelay(delay)) { wp_tmp = 0; hyterese = 1;} |
} |
else |
if(PPM_in[EE_Parameter.MenuKeyChannel] < -50) |
{ |
delay = SetDelay(2500); |
if(hyterese == 2 && (wp_tmp < NaviData_MaxWpListIndex)) |
{ |
wp_tmp++; |
ToNC_Load_SingePoint = wp_tmp; |
changed = 0; |
} |
hyterese = 0; |
} |
// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
break; |
default: line = 0; |
break; |
} |
break; |
case 7: |
switch(line++) |
{ |
static unsigned char i=0,test=0,set=0; |
case 0: HoTT_printfxy(0,0,"Motortest / Setpoints");break; |
case 1: //HoTT_printfxy(0,1,"Motor Setpoint Strom "); |
case 2: |
case 3: |
case 4: i=((line-2)*2)+1; |
if(MotorenEin) |
{ |
HoTT_printfxy(0,line,"M%i=%2i%2i.%iA M%i=%2i%2i.%iA",i,Motor[i-1].SetPoint,Motor[i-1].Current/10,Motor[i-1].Current%10,i+1,Motor[i].SetPoint,Motor[i].Current/10,Motor[i].Current%10); |
} |
else |
{ |
HoTT_printfxy(0,line,"M%i=%2i%2i.%iA M%i=%2i%2i.%iA",i,MotorTest[i-1],Motor[i-1].Current/10,Motor[i-1].Current%10,i+1,MotorTest[i],Motor[i].Current/10,Motor[i].Current%10); |
} |
break; |
case 5: if(test) |
{ |
HoTT_printfxy(0,6,"!!!Motortest Aktiv!!!"); |
} |
case 6: if(test) |
{ |
PC_MotortestActive = 254; |
HoTT_printfxy(0,7,"Motor %i",test); |
MotorTest[test-1]=set; |
} |
case 7: |
case 8: |
case 9: |
case 10: |
case 11: |
case 12: |
case 13: |
case 14: |
case 15: |
case 16: |
if(HottKeyboard == HOTT_KEY_RIGHT) |
{ |
if(test) |
{ |
set=0; |
MotorTest[test-1]=set; |
if(test<8) test++; |
} |
else |
{ |
LIBFC_HoTT_Clear(); |
page--; |
line=0; |
} |
} |
else |
if(HottKeyboard == HOTT_KEY_LEFT) |
{ |
if(test) |
{ |
set=0; |
MotorTest[test-1]=set; |
if(test>1) test--; |
} |
else |
{ |
LIBFC_HoTT_Clear(); |
page++; |
line = 0; |
} |
} |
else |
if((HottKeyboard == HOTT_KEY_UP) && (set <98 ) && test) set+=2;//GESCHW |
else |
if((HottKeyboard == HOTT_KEY_DOWN) && (set >0 ) && test) set-=2; |
else |
if((HottKeyboard == HOTT_KEY_SET) && !MotorenEin) |
{ |
if(test) test = 0; else test = 1; |
set=0; |
Hott_ClearLine(6); Hott_ClearLine(7); |
} |
HottKeyboard = 0; |
break; |
default: line = 0; |
break; |
//HoTT_printfxy(10 ,line,"I"); |
//line++; |
} |
break; |
case 8: |
switch(line++) |
{ |
#define MD_OFF 1 |
#define MD_CAL 2 |
#define MD_SAV 3 |
static unsigned char mode=MD_OFF,cursor=MD_OFF; |
case 0: HoTT_printfxy(0,0,"ACC calibration");break; |
case 1: HoTT_printfxy(0,2,"ACC: N:%3i R:%3i ",NeutralAccX,NeutralAccY); |
case 2: HoTT_printfxy(0,3,"Stick: (%i/%i) ",ChannelNick,ChannelRoll); |
case 3: if(ChannelNick || ChannelRoll) HoTT_printfxy(7,3,"!!"); |
break; |
case 4: HoTT_printfxy(2,4,"Off");break; |
case 5: HoTT_printfxy(2,5,"Calibrate");break; |
case 6: HoTT_printfxy(2,6,"Save "); |
if(mode == MD_SAV && cursor == MD_SAV) |
{ |
HoTT_printfxy(7,6,"(SET)"); |
} |
else if((mode == MD_CAL) && !((NC_GPS_ModeCharacter == ' ') || (NC_GPS_ModeCharacter == '/') || (NC_GPS_ModeCharacter == '-'))) |
{ |
HoTT_printfxy(2,6,"Swich GPS off!"); |
} |
break; |
case 7: |
case 8: HoTT_printfxy(0,cursor+3,">");break; |
case 9: HoTT_printfxy(1,mode+3,"*");break; |
case 10: |
case 11: |
case 12: |
case 13: |
case 14: |
case 15: |
case 16: |
if(HottKeyboard == HOTT_KEY_RIGHT) |
{ |
switch(mode) |
{ |
case MD_OFF: LIBFC_HoTT_Clear(); |
page--; // leave menu |
line = 0; |
break; |
case MD_CAL: NeutralAccY++; |
break; |
case MD_SAV: break; |
default: mode=MD_OFF;break; |
} |
} |
else |
if(HottKeyboard == HOTT_KEY_LEFT) |
{ |
switch(mode) |
{ |
case MD_OFF: LIBFC_HoTT_Clear(); |
page++; // leave menu |
line = 0; |
break; |
case MD_CAL: NeutralAccY--; |
break; |
case MD_SAV: break; |
default: mode=MD_OFF; |
break; |
} |
} |
else |
if(HottKeyboard == HOTT_KEY_UP) |
{ |
switch(mode) |
{ |
case MD_CAL: NeutralAccX++; |
break; |
case MD_OFF: |
case MD_SAV: if(cursor>1) {HoTT_printfxy(0,cursor+3," ");cursor--;} |
HoTT_printfxy(2,6," "); |
break; |
default: mode=MD_OFF; |
break; |
} |
} |
else |
if(HottKeyboard == HOTT_KEY_DOWN) |
{ |
switch(mode) |
{ |
case MD_CAL: NeutralAccX--; |
break; |
case MD_SAV: |
case MD_OFF: if(cursor<MD_SAV) {HoTT_printfxy(0,cursor+3," ");cursor++;} |
break; |
default: mode=MD_OFF; |
break; |
} |
} |
else |
if(HottKeyboard == HOTT_KEY_SET) |
{ |
switch(mode) |
{ |
case MD_OFF: HoTT_printfxy(1,mode+3," "); |
mode = cursor; |
if(mode == MD_CAL && !EE_Parameter.Driftkomp) EE_Parameter.Driftkomp = 6; // enables the Gyro-Drift compensation to make sure that a litlte calibration error won't effect the attitude |
break; |
case MD_CAL: HoTT_printfxy(1,mode+3," "); |
mode = MD_OFF; |
break; |
case MD_SAV: |
Hott_ClearLine(7); |
if(cursor == MD_SAV) |
{ |
if(!MotorenEin) |
{ |
/* BoatNeutralNick = AdNeutralNick; |
BoatNeutralRoll = AdNeutralRoll; |
BoatNeutralGier = AdNeutralGier; |
SetParamWord(PID_ACC_NICK, (uint16_t)NeutralAccX); |
SetParamWord(PID_ACC_ROLL, (uint16_t)NeutralAccY); |
SetParamWord(PID_GYRO_NICK,(uint16_t)BoatNeutralNick); |
SetParamWord(PID_GYRO_ROLL,(uint16_t)BoatNeutralRoll); |
SetParamWord(PID_GYRO_YAW,(uint16_t)BoatNeutralGier); |
*/ |
StoreNeutralToEeprom(); |
HoTT_printfxy(7,6," okay "); |
HoTT_printfxy(1,mode+3," "); |
mode = MD_OFF; |
} |
else |
{ |
HoTT_printfxy(0,7,"Motors running!!!"); |
mode = MD_OFF; |
} |
} |
else |
{ |
HoTT_printfxy(1,mode+3," "); |
mode=cursor; |
} |
break; |
default: mode=MD_OFF; |
break; |
} |
} |
HottKeyboard = 0; |
break; |
default: line = 0; |
break; |
//HoTT_printfxy(10 ,line,"I"); |
//line++; |
} |
break; |
/* |
//------------------------------------------------------------------------------------------ |
// HoTT-Plus |
//------------------------------------------------------------------------------------------ |
case 9: |
switch(line++) |
{ |
case 0: HoTT_printfxy(0,0,"I2C Schwerpunkt GAS"); |
break; |
case 1: HoTT_printfxy(0,1,"I2C%3i%3i%3i%3i",Motor[0].State & MOTOR_STATE_ERROR_MASK,Motor[1].State & MOTOR_STATE_ERROR_MASK, Motor[2].State & MOTOR_STATE_ERROR_MASK, Motor[3].State & MOTOR_STATE_ERROR_MASK); |
break; |
case 2: HoTT_printfxy(0,2," %3i%3i%3i%3i",Motor[4].State & MOTOR_STATE_ERROR_MASK,Motor[5].State & MOTOR_STATE_ERROR_MASK, Motor[6].State & MOTOR_STATE_ERROR_MASK, Motor[7].State & MOTOR_STATE_ERROR_MASK); |
break; |
case 3: { //0123456789ABCDEF |
int r=0; |
int n=0; |
int g=0; |
n=SummeNick >> 9; |
r=SummeRoll >> 9; |
g=Mess_Integral_Gier >> 9; |
HoTT_printfxy(0,5,"%3iN %3iR %3iG",n ,r ,g); |
} |
break; |
case 4: { //0123456789ABCDEF |
HoTT_printfxy(0,4,"+ ^ + <"); |
} |
break; |
case 5: { //0123456789ABCDEF |
HoTT_printfxy(0,6,"- v - >"); |
} |
break; |
case 6: HoTT_printfxy(0,7,"%3i=HG/4 %3i=Gas",HoverGas/4,StickGas); |
break; |
case 7: |
case 8: |
case 9: |
case 10: |
case 11: |
case 12: |
case 13: |
case 14: |
case 15: |
case 16: |
if(HottKeyboard == HOTT_KEY_RIGHT) { LIBFC_HoTT_Clear(); page--; line = 0;} |
else |
if(HottKeyboard == HOTT_KEY_LEFT) { LIBFC_HoTT_Clear(); page++; line = 0;} |
HottKeyboard = 0; |
break; |
default: line = 0; |
break; |
} |
break; |
//--------------------------------------------------------------------------------------------------- |
case 10: |
{ |
static signed char i=0,j=0,Changepos=0; |
if(line==9) |
{ |
line=0; |
if(HottKeyboard == HOTT_KEY_SET ) { if(Changepos) Changepos = 0; else Changepos = 1;} |
else |
if(Changepos) |
{ |
unsigned char temp=0; |
temp=(Changepos+j)-1; |
if((HottKeyboard == HOTT_KEY_RIGHT) && !((unsigned char)(*Parameter_List[temp].Variable + Parameter_List[temp].offset) >= Parameter_List[temp].max )) {*Parameter_List[temp].Variable += 1;} |
else |
if((HottKeyboard == HOTT_KEY_LEFT) && !((unsigned char)(*Parameter_List[temp].Variable + Parameter_List[temp].offset) <= Parameter_List[temp].min )) {*Parameter_List[temp].Variable -= 1;} |
else |
if(HottKeyboard == HOTT_KEY_UP ) |
{ |
Changepos--; |
line = Changepos/2; |
if(Changepos< 1 ) {Changepos=16;} |
} |
else |
if(HottKeyboard == HOTT_KEY_DOWN) |
{ |
Changepos++; |
line = Changepos/2; |
if(Changepos >= 17 ) {Changepos=1;} |
} |
} |
else |
{ |
if(HottKeyboard == HOTT_KEY_RIGHT) { LIBFC_HoTT_Clear(); page--; line = 0;} |
else |
if(HottKeyboard == HOTT_KEY_LEFT) { LIBFC_HoTT_Clear(); page++; line = 0;} |
else |
if(HottKeyboard == HOTT_KEY_UP ) |
{ |
j-=16; |
line = 0; |
if(j< 0 ) {j=0;} |
} |
else |
if(HottKeyboard == HOTT_KEY_DOWN) |
{ |
LIBFC_HoTT_Clear(); |
j+=16; |
line = 0; |
if(j+14> MAXPARAM ) {j=MAXPARAM-15;} |
} |
} |
Debug("line=%i Changepos=%i j=%i Key=%i",line,Changepos,j,HottKeyboard); |
HottKeyboard = 0; |
} |
HoTT_printfxy(10 ,line,"I"); |
i=(line*2)+(j); |
if(Changepos==(line*2)+1) |
{ |
HoTT_printfxy(0 ,line,">%3i=%-5.5s%",(unsigned char)(*Parameter_List[i ].Variable + Parameter_List[i ].offset),&Parameter_List[i ].name); |
} |
else |
{ |
HoTT_printfxy(0 ,line," %3i=%-5.5s%",(unsigned char)(*Parameter_List[i ].Variable + Parameter_List[i ].offset),&Parameter_List[i ].name); |
} |
if(Changepos==(line*2)+2) |
{ |
HoTT_printfxy(11,line,">%3i=%-5.5s%",(unsigned char)(*Parameter_List[i+1].Variable + Parameter_List[i+1].offset),&Parameter_List[i+1].name); |
} |
else |
{ |
HoTT_printfxy(11,line," %3i=%-5.5s%",(unsigned char)(*Parameter_List[i+1].Variable + Parameter_List[i+1].offset),&Parameter_List[i+1].name); |
} |
line++; |
} |
break; |
case 11: |
switch(line++) |
{ |
case 0: HoTT_printfxy(0,0,"Setting speichern"); |
break; |
case 1: HoTT_printfxy(0,1,"Setting%1i= %-11.11s",GetActiveParamSet(),EE_Parameter.Name); |
break; //123456789012345678901 |
case 2: HoTT_printfxy(0,2,"Speichern nach Set %i",settingdest); |
break; |
case 3: HoTT_printfxy(0,4,"\"SET\" zum speichern"); |
break; |
case 4: HoTT_printfxy(0,5,"^ v zum auswaehlen"); |
break; |
case 5: |
case 6: |
case 7: |
case 8: |
case 9: |
case 10: |
case 11: |
case 12: |
case 13: |
case 14: |
case 15: |
case 16: |
if(HottKeyboard == HOTT_KEY_RIGHT) { LIBFC_HoTT_Clear(); page--; line = 0;} |
else |
if(HottKeyboard == HOTT_KEY_LEFT) { LIBFC_HoTT_Clear(); page++; line = 0;} |
else |
if((HottKeyboard == HOTT_KEY_UP) & (settingdest <5 )) settingdest++; |
else |
if((HottKeyboard == HOTT_KEY_DOWN) & (settingdest >1 )) settingdest--; |
else |
if((HottKeyboard == HOTT_KEY_SET) && !MotorenEin) |
{ |
ParamSet_WriteToEEProm(settingdest); |
//JetiBeep = jetibeepcode[GetActiveParamSet()-1]; |
Piep(GetActiveParamSet(),120); |
HoTT_printfxy(0,7,"Gespeichert!"); |
} |
HottKeyboard = 0; |
break; |
default: line = 0; |
break; |
} |
break; |
//------------------------------------------------------------------------------------------ |
// HoTT-Plus |
//------------------------------------------------------------------------------------------ |
*/ |
default: page = 0; |
break; |
} |
} |
#endif |
/tags/V2.12a/hottmenu.h |
---|
0,0 → 1,316 |
#ifndef _HOTTMENU_H |
#define _HOTTMENU_H |
extern unsigned char NaviData_WaypointIndex; |
extern unsigned char NaviData_WaypointNumber, NaviData_TargetHoldTime,ToNC_Load_WP_List,NaviData_MaxWpListIndex; |
extern unsigned char ToNC_Load_SingePoint, ToNC_Store_SingePoint, Show_Load_Time, Show_Store_Time, Show_Load_Value, Show_Store_Value; |
extern char WPL_Name[10]; |
#if (defined(__AVR_ATmega1284__) || defined(__AVR_ATmega1284P__)) |
#define SPEAK_ERR_CALIBARTION 1 |
#define SPEAK_ERR_RECEICER 2 |
#define SPEAK_ERR_DATABUS 3 |
#define SPEAK_ERR_NAVI 4 |
#define SPEAK_ERROR 5 |
#define SPEAK_ERR_COMPASS 6 |
#define SPEAK_ERR_SENSOR 7 |
#define SPEAK_ERR_GPS 8 |
#define SPEAK_ERR_MOTOR 9 |
#define SPEAK_MAX_TEMPERAT 10 // ->Motor Überlastung |
#define SPEAK_ALTI_REACHED 11 // ? |
#define SPEAK_WP_REACHED 12 |
#define SPEAK_NEXT_WP 13 |
#define SPEAK_LANDING 14 |
#define SPEAK_GPS_FIX 15 |
#define SPEAK_UNDERVOLTAGE 16 |
#define SPEAK_GPS_HOLD 17 |
#define SPEAK_GPS_HOME 18 |
#define SPEAK_GPS_OFF 19 |
#define SPEAK_BEEP 20 |
#define SPEAK_MIKROKOPTER 21 |
#define SPEAK_CAPACITY 22 // ? |
#define SPEAK_CF_OFF 23 |
#define SPEAK_CALIBRATE 24 |
#define SPEAK_MAX_RANGE 25 |
#define SPEAK_MAX_ALTITUD 26 |
#define SPEAK_20M 37 // ? |
#define SPEAK_MK_OFF 38 |
#define SPEAK_ALTITUDE_ON 39 |
#define SPEAK_ALTITUDE_OFF 40 |
#define SPEAK_100M 41 |
#define SPEAK_CF_ON 46 |
#define SPEAK_SINKING 47 // ? |
#define SPEAK_RISING 48 |
#define SPEAK_HOLDING 49 // ? |
#define SPEAK_GPS_ON 50 |
#define SPEAK_FOLLWING 51 // ? |
#define SPEAK_STARTING 52 |
// Achtung: wenn > 53 -> JETI_CODE[53] anpassen |
/* |
1 Fehler: Kalibration |
2 Fehler: Empfang |
3 Fehler: Datenbus |
4 Fehler: Navi |
5 Fehler |
6 Fehler: Kompass |
7 Fehler: Sensor |
8 Fehler: GPS |
9 Fehler: Motor |
10 Fehler: Überlastung |
11 Höhe erreicht |
12 Wegpunkt erreicht |
13 Nächster Wegpunkt |
14 Landen |
15 GPS Fix |
16 Unterspannung |
17 GPS Halten |
18 GPS Home |
19 GPS Aus |
20 * Beep |
21 MikroKopter |
22 Kapazität |
23 Carefree aus |
24 Kalibriere |
25 Maximale Entfernung |
26 Maximale Höhe |
27 * Warnung |
28 * Failsafe aktiv |
29 * Failsafe aus |
30 * Redundanz aktiv |
31 * Redundanz aus |
32 * Starte Wegpunkt |
33 * Fehler: Überstrom |
34 * Fehler: Übertemperatur |
35 * Fehler: Failsafe |
36 * Fehler: Redundanz |
37 Zwanzig Meter |
38 MikroKopter aus |
39 Höhe Ein |
40 Höhe Aus |
41 Einhundert meter |
42 * Verbindung hergestellt |
43 * Verbindung unterbrochen |
44 |
45 |
46 Carefree ein |
47 Sinken |
48 Steigen |
49 Halten |
50 GPS ein |
51 Folgen |
52 Starten |
//fehlt: |
//"Warnung" |
//"Failsafe" |
//"ERR:Redundanz ?" |
*/ |
#define MAX_ERR_NUMBER (38+1) |
extern const char PROGMEM NC_ERROR_TEXT[MAX_ERR_NUMBER][17]; |
extern unsigned int NaviData_TargetDistance; |
extern unsigned char MaxBlTemperture; |
extern unsigned char MinBlTemperture; |
extern unsigned char HottestBl; |
extern unsigned char HottKeyboard,HoTT_RequestedSensor; |
extern unsigned char HottUpdate(unsigned char key); |
extern unsigned char SpeakHoTT,ShowSettingNameTime; |
extern unsigned char ToNC_SpeakHoTT; |
extern volatile unsigned char *HoTT_DataPointer; |
extern void CreateHoTT_Menu(void); |
extern void LIBFC_HoTT_Putchar(char); |
extern void LIBFC_HoTT_Putchar_INV(char); // print Invers |
extern void LIBFC_HoTT_Putchar_BLINK(char); |
extern void LIBFC_HoTT_SetPos(unsigned char); |
extern void LIBFC_HoTT_Clear(void); |
extern void NC_Fills_HoTT_Telemety(void); |
extern void HoTT_Menu(void); |
extern unsigned char HoTT_Telemety(unsigned char); |
extern unsigned char HoTT_Waring(void); |
extern volatile unsigned char HoTTBlink; |
extern void GetHottestBl(void); |
typedef struct |
{ |
unsigned char StartByte; // 0x7C |
unsigned char Packet_ID; // HOTT_GENERAL_PACKET_ID |
unsigned char WarnBeep; // 3 Anzahl der Töne 0..36 |
unsigned char SensorID; // 4 0xD0 |
unsigned char InverseStatus1; // 5 |
unsigned char InverseStatus2; // 6 |
unsigned char VoltageCell1; // 7 208 = 4,16V (Voltage * 50 = Wert) |
unsigned char VoltageCell2; // 8 209 = 4,18V |
unsigned char VoltageCell3; // 9 |
unsigned char VoltageCell4; // 10 |
unsigned char VoltageCell5; // 11 |
unsigned char VoltageCell6; // 12 |
unsigned int Battery1; // 13+14 51 = 5,1V |
unsigned int Battery2; // 15+16 51 = 5,1V |
unsigned char Temperature1; // 17 44 = 24°C, 0 = -20°C |
unsigned char Temperature2; // 18 44 = 24°C, 0 = -20°C |
unsigned char FuelPercent; // 19 |
signed int FuelCapacity; // 20+21 |
unsigned int Rpm; // 22+23 |
signed int Altitude; // 24+25 |
unsigned int m_sec; // 26+27 3000 = 0 |
unsigned char m_3sec; // 28 120 = 0 |
unsigned int Current; // 29+30 1 = 0.1A |
unsigned int InputVoltage; // 31+32 66 = 6,6V |
unsigned int Capacity; // 33+34 1 = 10mAh |
unsigned int Speed; // 35+36 |
unsigned char LowestCellVoltage; // 37 |
unsigned char LowestCellNumber; // 38 |
unsigned int Rpm2; // 39+40 |
unsigned char ErrorNumber; // 41 |
unsigned char Pressure; // 42 in 0,1bar 20=2,0bar |
unsigned char Version; // 43 |
unsigned char EndByte; // 0x7D |
} HoTTGeneral_t; |
typedef struct |
{ |
unsigned char StartByte; // 0x7C |
unsigned char Packet_ID; // HOTT_ELECTRIC_AIR_PACKET_ID |
unsigned char WarnBeep; // Anzahl der Töne 0..36 |
unsigned char SensorID; // 4 0xE0 |
unsigned char InverseStatus1; // 5 |
unsigned char InverseStatus2; // 6 |
unsigned char VoltageCell1; // 7 208 = 4,16V (Voltage * 50 = Wert) |
unsigned char VoltageCell2; // 209 = 4,18V |
unsigned char VoltageCell3; // |
unsigned char VoltageCell4; // |
unsigned char VoltageCell5; // |
unsigned char VoltageCell6; // |
unsigned char VoltageCell7; // |
unsigned char VoltageCell8; // |
unsigned char VoltageCell9; // |
unsigned char VoltageCell10; // |
unsigned char VoltageCell11; // |
unsigned char VoltageCell12; // |
unsigned char VoltageCell13; // |
unsigned char VoltageCell14; // 20 |
unsigned int Battery1; // 21+22 51 = 5,1V |
unsigned int Battery2; // 23+24 51 = 5,1V |
unsigned char Temperature1; // 25 44 = 24°C, 0 = -20°C |
unsigned char Temperature2; // 26 44 = 24°C, 0 = -20°C |
signed int Altitude; // 27+28 |
unsigned int Current; // 29+30 1 = 0.1A |
unsigned int InputVoltage; // 31+32 66 = 6,6V |
unsigned int Capacity; // 33+34 1 = 10mAh |
unsigned int m_sec; // 35+36 30000 = 0 |
unsigned char m_3sec; // 37 120 = 0 |
unsigned int Rpm; // 38+39 |
unsigned char FlightTimeMinutes; // 40 |
unsigned char FlightTimeSeconds; // 41 |
unsigned char Speed; // 42 1=2km |
unsigned char Version; // 43 0x00 |
unsigned char EndByte; // 0x7D |
} ElectricAirPacket_t; |
typedef struct |
{ |
unsigned char StartByte; // 0x7C |
unsigned char Packet_ID; // 0x89 - Vario ID |
unsigned char WarnBeep; //3 // Anzahl der Töne 0..36 |
unsigned char SensorID; // 0x90 |
unsigned char InverseStatus; |
signed int Altitude; //6+7 // 500 = 0m |
signed int MaxAltitude; //8+9 // 500 = 0m |
signed int MinAltitude; //10+11 // 500 = 0m |
unsigned int m_sec; //12+13 // 3000 = 0 |
unsigned int m_3sec; //14+15 |
unsigned int m_10sec; //26+17 |
char Text[21]; //18-38 |
char FreeCharacters[3]; // 39-41 |
unsigned char NullByte; // 42 0x00 |
unsigned char Version; // 43 |
unsigned char EndByte; // 0x7D |
} VarioPacket_t; |
typedef struct |
{ |
unsigned char StartByte; //0 // 0x7C |
unsigned char Packet_ID; //1 // 0x8A - GPS ID |
unsigned char WarnBeep; //2 // Anzahl der Töne 0..36 |
unsigned char SensorID; // 4 0xA0 |
unsigned char InverseStatus1; // 5 |
unsigned char InverseStatus2; // 6 |
unsigned char Heading; //7 // 1 = 2° |
unsigned int Speed; //8+9 // in km/h |
unsigned char Lat_North; //10 |
unsigned char Lat_G; //11 |
unsigned char Lat_M; //12 |
unsigned char Lat_Sek1; //13 |
unsigned char Lat_Sek2; //14 |
unsigned char Lon_East; //15 |
unsigned char Lon_G; //16 |
unsigned char Lon_M; //17 |
unsigned char Lon_Sek1; //18 |
unsigned char Lon_Sek2; //19 |
unsigned int Distance; //20+21 // 9000 = 0m |
signed int Altitude; //22+23 // 500 = 0m |
unsigned int m_sec; //24+25 // 3000 = 0 |
unsigned char m_3sec; //26 120 = 0 |
unsigned char NumOfSats; //27 |
unsigned char SatFix; //28 |
unsigned char HomeDirection; // 29 |
unsigned char AngleX; // 30 |
unsigned char AngleY; // 31 |
unsigned char AngleZ; // 32 |
signed int GyroX; //33+34 |
signed int GyroY; //35+36 |
signed int GyroZ; //37+38 |
unsigned char Vibration; // 39 |
char FreeCharacters[3]; // 40-42 |
unsigned char Version; // 43 |
unsigned char EndByte; // 0x7D |
} GPSPacket_t; |
typedef struct |
{ |
unsigned char StartByte; // 0x7B |
unsigned char Packet_ID; // |
unsigned char WarnBeep; // Anzahl der Töne 0..36 |
char Text[8*21]; |
unsigned char EndByte; // 0x7D |
} ASCIIPacket_t; |
extern GPSPacket_t GPSPacket; |
extern VarioPacket_t VarioPacket; |
extern ASCIIPacket_t ASCIIPacket; |
extern ElectricAirPacket_t ElectricAirPacket; |
extern HoTTGeneral_t HoTTGeneral; |
#define HOTT_VARIO_PACKET_ID 0x89 |
#define HOTT_GPS_PACKET_ID 0x8A |
#define HOTT_ELECTRIC_AIR_PACKET_ID 0x8E |
#define HOTT_GENERAL_PACKET_ID 0x8D |
#define JETI_GPS_PACKET_ID1 0x01 |
#define JETI_GPS_PACKET_ID2 0x02 |
#define HOTT_WPL_NAME 0x03 |
//--------------------------------------------------------------------------------------------------- |
typedef struct{ |
char offset; |
unsigned char min; |
unsigned char max; |
char name[4]; |
unsigned char *Variable; |
} Parameter_List_t; |
#define MAXPARAM 41 //Muss eine ungerade Zahl sein |
extern const Parameter_List_t Parameter_List[]; |
//--------------------------------------------------------------------------------------------------- |
#endif |
#endif |
/tags/V2.12a/isqrt.S |
---|
0,0 → 1,203 |
;-----------------------------------------------------------------------------; |
; Fast integer squareroot routines for avr-gcc project (C)ChaN, 2008 |
; http://elm-chan.org/docs/avrlib/sqrt32.S |
;-----------------------------------------------------------------------------; |
; uint16_t isqrt32 (uint32_t n); |
; uint8_t isqrt16 (uint16_t n); |
; uint16_t ihypot (int16_t x, int16_t y); |
;-----------------------------------------------------------------------------: |
; 32bit integer squareroot |
;-----------------------------------------------------------------------------; |
; uint16_t isqrt32 ( |
; uint32_t n |
; ); |
; |
; Return Value: |
; Squareroot of n. |
; |
; Size = 53 words |
; Clock = 532..548 cycles |
; Stack = 0 byte |
.global isqrt32 |
.func isqrt32 |
isqrt32: |
clr r0 |
clr r18 |
clr r19 |
clr r20 |
ldi r21, 1 |
clr r27 |
clr r30 |
clr r31 |
ldi r26, 16 |
1: lsl r22 |
rol r23 |
rol r24 |
rol r25 |
rol r0 |
rol r18 |
rol r19 |
rol r20 |
lsl r22 |
rol r23 |
rol r24 |
rol r25 |
rol r0 |
rol r18 |
rol r19 |
rol r20 |
brpl 2f |
add r0, r21 |
adc r18, r27 |
adc r19, r30 |
adc r20, r31 |
rjmp 3f |
2: sub r0, r21 |
sbc r18, r27 |
sbc r19, r30 |
sbc r20, r31 |
3: lsl r21 |
rol r27 |
rol r30 |
andi r21, 0b11111000 |
ori r21, 0b00000101 |
sbrc r20, 7 |
subi r21, 2 |
dec r26 |
brne 1b |
lsr r30 |
ror r27 |
ror r21 |
lsr r30 |
ror r27 |
ror r21 |
mov r24, r21 |
mov r25, r27 |
ret |
.endfunc |
;-----------------------------------------------------------------------------: |
; 16bit integer squareroot |
;-----------------------------------------------------------------------------; |
; uint8_t isqrt16 ( |
; uint16_t n |
; ); |
; |
; Return Value: |
; Squareroot of n. |
; |
; Size = 33 words |
; Clock = 181..189 cycles |
; Stack = 0 byte |
.global isqrt16 |
.func isqrt16 |
isqrt16: |
clr r18 |
clr r19 |
ldi r20, 1 |
clr r21 |
ldi r22, 8 |
1: lsl r24 |
rol r25 |
rol r18 |
rol r19 |
lsl r24 |
rol r25 |
rol r18 |
rol r19 |
brpl 2f |
add r18, r20 |
adc r19, r21 |
rjmp 3f |
2: sub r18, r20 |
sbc r19, r21 |
3: lsl r20 |
rol r21 |
andi r20, 0b11111000 |
ori r20, 0b00000101 |
sbrc r19, 7 |
subi r20, 2 |
dec r22 |
brne 1b |
lsr r21 |
ror r20 |
lsr r21 |
ror r20 |
mov r24, r20 |
ret |
.endfunc |
;-----------------------------------------------------------------------------: |
; 16bit integer hypot (megaAVR is required) |
;-----------------------------------------------------------------------------; |
; uint16_t ihypot ( |
; int16_t x, |
; int16_t y |
; ); |
; |
; Return Value: |
; Squareroot of (x*x + y*y) |
; |
; Size = 42 words |
; Clock = 581..597 cycles |
; Stack = 0 byte |
.global ihypot |
.func ihypot |
ihypot: |
clr r26 |
sbrs r25, 7 |
rjmp 1f |
com r24 |
com r25 |
adc r24, r26 |
adc r25, r26 |
1: sbrs r23, 7 |
rjmp 2f |
com r22 |
com r23 |
adc r22, r26 |
adc r23, r26 |
2: mul r22, r22 |
movw r18, r0 |
mul r23, r23 |
movw r20, r0 |
mul r22, r23 |
add r19, r0 |
adc r20, r1 |
adc r21, r26 |
add r19, r0 |
adc r20, r1 |
adc r21, r26 |
mul r24, r24 |
movw r30, r0 |
mul r25, r25 |
add r18, r30 |
adc r19, r31 |
adc r20, r0 |
adc r21, r1 |
mul r24, r25 |
add r19, r0 |
adc r20, r1 |
adc r21, r26 |
add r19, r0 |
adc r20, r1 |
adc r21, r26 |
movw r24, r20 |
movw r22, r18 |
clr r1 |
rjmp isqrt32 |
.endfunc |
/tags/V2.12a/isqrt.h |
---|
0,0 → 1,11 |
#ifndef _ISQRT_H |
#define _ISQRT_H |
#include <inttypes.h> |
// coded in assembler file |
extern uint16_t isqrt32(uint32_t n); |
extern uint8_t isqrt16(uint16_t n); |
extern uint16_t ihypot(int16_t x, int16_t y); |
#endif // _ISQRT_H |
/tags/V2.12a/jeti_ex.c |
---|
0,0 → 1,145 |
#include "libfc.h" |
#include "printf_P.h" |
#include "main.h" |
#include "spi.h" |
#include "capacity.h" |
#include "jeti_ex.h" |
#include "hottmenu.h" |
#if (defined(__AVR_ATmega1284__) || defined(__AVR_ATmega1284P__)) |
const char PROGMEM JETI_CODE[53] = |
{ |
0, // 0 |
'O', // SPEAK_ERR_CALIBARTION 1 |
'P', // SPEAK_ERR_RECEICER 2 |
'Q', // SPEAK_ERR_DATABUS 3 |
'R', // SPEAK_ERR_NAVI 4 |
'S', // SPEAK_ERROR 5 |
'T', // SPEAK_ERR_COMPASS 6 |
'S', // SPEAK_ERR_SENSOR 7 |
'V', // SPEAK_ERR_GPS 8 |
'W', // SPEAK_ERR_MOTOR 9 |
'H', // SPEAK_MAX_TEMPERAT 10 |
0, // SPEAK_ALTI_REACHED 11 |
'X', // SPEAK_WP_REACHED 12 |
'Y', // SPEAK_NEXT_WP 13 |
0, // SPEAK_LANDING 14 |
'Z', // SPEAK_GPS_FIX 15 |
'U', // SPEAK_UNDERVOLTAGE 16 |
'E', // SPEAK_GPS_HOLD 17 |
'F', // SPEAK_GPS_HOME 18 |
'G', // SPEAK_GPS_OFF 19 |
'H', // SPEAK_BEEP 20 |
'A', // SPEAK_MIKROKOPTER 21 |
0, // SPEAK_CAPACITY 22 |
'I', // SPEAK_CF_OFF 23 |
'B', // SPEAK_CALIBRATE 24 |
'J', // SPEAK_MAX_RANGE 25 |
'J', // SPEAK_MAX_ALTITUD 26 |
0, // 27 |
0, // 28 |
0, // 29 |
0, // 30 |
0, // 31 |
0, // 32 |
0, // 33 |
0, // 34 |
0, // 35 |
0, // 36 |
0, // SPEAK_20M 37 |
'D', // SPEAK_MK_OFF 38 |
'L', // SPEAK_ALTITUDE_ON 39 |
'M', // SPEAK_ALTITUDE_OFF 40 |
0, // SPEAK_100M 41 |
0, // 42 |
0, // 43 |
0, // 44 |
0, // 45 |
'N', // SPEAK_CF_ON 46 |
0, // SPEAK_SINKING 47 |
0, // SPEAK_RISING 48 |
0, // SPEAK_HOLDING 49 |
'K', // SPEAK_GPS_ON 50 // ? |
0, // SPEAK_FOLLWING 51 |
'C' // SPEAK_STARTING 52 |
}; |
JetiExPacket_t JetiExData[JETI_EX_PARAMETER_COUNT + 1] = // Parameter count + DeviceName (ID0) |
{ |
// Label[10] unit[3], data type, Data , position of decimal point |
// "1234567890", "123", |
// { "-=.M_K.=-" , " ", 1, 0 , 0 }, // first one is device name // datatype 1 = -8192...8192 |
{ "MK " , " ", 1, 0 , 0 }, // first one is device name // datatype 1 = -8192...8192 |
{ "Voltage " , "V ", 1, 0 , 1 }, // ID 1 |
{ "Current " , "A ", 1, 0 , 1 }, // ID 2 |
{ "Capacity " , "Ah ", 1, 0 , 2 }, // ID 3 |
{ "Altitude " , "m ", 1, 0 , 0 }, // ID 4 |
{ "Compass " , "° ", 1, 0 , 0 }, // ID 5 |
{ "Sats " , " ", 1, 0 , 0 }, // ID 6 |
{ "Speed " , "m/s", 1, 0 , 0 }, // ID 7 |
{ "Distance " , "m ", 1, 0 , 0 }, // ID 8 |
{ "Home-Dir " , "° ", 1, 0 , 0 }, // ID 9 |
{ "max.Temp. " , "°C ", 1, 0 , 0 }, // ID 10 |
{ "Magn.field" , "% ", 1, 0 , 0 }, // ID 11 |
{ "Vario " , " ", 1, 0 , 0 }, // ID 12 |
{ "ErrorCode " , " ", 1, 0 , 0 }, // ID 13 |
{ "Latitude " , " ", 9, 0 , 0 }, // ID 14 special data type for coordinates Import: fixed position in list ID 14 - DO NOT MOVE !!! |
{ "Longitude " , " ", 9, 0 , 0 }, // ID 15 special data type for coordinates Import: fixed position in list ID 15 - DO NOT MOVE !!! |
}; |
void BuildJeti_Vario(void) |
{ |
signed int tmp = 0; |
static signed int JetiVarioMeter = 0; |
JetiVarioMeter = (JetiVarioMeter * 3 + VarioMeter) / 4; |
if(VarioCharacter == '+') |
{ |
tmp = (AltitudeSetpointTrimming * EE_Parameter.Hoehe_Verstaerkung) / 32 + 5; |
} |
else |
if(VarioCharacter == '-') |
{ |
tmp = (AltitudeSetpointTrimming * EE_Parameter.Hoehe_Verstaerkung) / 32 - 5; |
} |
else |
if((VarioCharacter == ' ') && (FC_StatusFlags & FC_STATUS_FLY)) |
{ |
tmp = (JetiVarioMeter/32); |
} |
else |
if(VarioCharacter == '^') tmp = FromNC_AltitudeSpeed; |
else |
if(VarioCharacter == 'v') tmp = tmp - FromNC_AltitudeSpeed; |
JetiExData[12].Value = tmp; |
} |
// -------------------------------------------------------------------------------------------------- |
void JetiEX_Update(void) |
{ |
GetHottestBl(); |
JetiExData[1].Value = UBat; |
JetiExData[2].Value = Capacity.ActualCurrent; |
JetiExData[3].Value = Capacity.UsedCapacity / 10; |
JetiExData[4].Value = HoehenWert / 100; |
JetiExData[5].Value = KompassValue; |
JetiExData[6].Value = GPSInfo.NumOfSats; |
JetiExData[7].Value = GPSInfo.Speed; |
JetiExData[8].Value = GPSInfo.HomeDistance / 10; |
JetiExData[9].Value = GPSInfo.HomeBearing; |
JetiExData[10].Value = MaxBlTemperture; |
JetiExData[11].Value = EarthMagneticField; |
// JetiExData[12].Value = Vario; // wird in BuildJeti_Vario() gemacht |
JetiExData[13].Value = NC_ErrorCode; |
//JetiExData[14].Value = 53 * 0x10000 + 23467; // GPS-Latitude (macht NC_Fills_HoTT_Telemety() ) |
//JetiExData[15].Value = 7 * 0x10000 + 23467; // GPS-Longitude (macht NC_Fills_HoTT_Telemety() ) |
} |
#endif |
/tags/V2.12a/jeti_ex.h |
---|
0,0 → 1,37 |
#ifndef _JETI_EX_H |
#define _JETI_EX_H |
#if (defined(__AVR_ATmega1284__) || defined(__AVR_ATmega1284P__)) |
extern void BuildJeti_Vario(void); |
// define here how many Jeti EX parameters should be transmitted (max. = 15) |
// |
#define JETI_EX_PARAMETER_COUNT 15 |
// |
// ------------------------------------------------------------------------- |
extern const char PROGMEM JETI_CODE[53]; |
typedef struct |
{ |
char Label[10]; |
char Unit[3]; |
unsigned char DataType; |
long Value; |
unsigned char DecimalPointPos; |
} JetiExPacket_t; |
extern JetiExPacket_t JetiExData[]; |
extern void JetiEX_Update(void); |
#if (JETI_EX_PARAMETER_COUNT > 15) |
#error "ERROR: Too many Jeti EX parameters (max. allowed 15)" |
#endif |
#endif |
#endif //_JETI_EX_H |
/tags/V2.12a/jetimenu.c |
---|
0,0 → 1,568 |
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
// + Software Nutzungsbedingungen (english version: see below) |
// + www.MikroKopter.com |
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
// + der Fa. HiSystems GmbH, Flachsmeerstrasse 2, 26802 Moormerland - nachfolgend Lizenzgeber genannt - |
// + Der Lizenzgeber räumt dem Kunden ein nicht-ausschließliches, zeitlich und räumlich* unbeschränktes Recht ein, die im den |
// + Mikrocontroller verwendete Firmware für die Hardware Flight-Ctrl, Navi-Ctrl, BL-Ctrl, MK3Mag & PC-Programm MikroKopter-Tool |
// + - nachfolgend Software genannt - nur für private Zwecke zu nutzen. |
// + Der Einsatz dieser Software ist nur auf oder mit Produkten des Lizenzgebers zulässig. |
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
// + Die vom Lizenzgeber gelieferte Software ist urheberrechtlich geschützt. Alle Rechte an der Software sowie an sonstigen im |
// + Rahmen der Vertragsanbahnung und Vertragsdurchführung überlassenen Unterlagen stehen im Verhältnis der Vertragspartner ausschließlich dem Lizenzgeber zu. |
// + Die in der Software enthaltenen Copyright-Vermerke, Markenzeichen, andere Rechtsvorbehalte, Seriennummern sowie |
// + sonstige der Programmidentifikation dienenden Merkmale dürfen vom Kunden nicht verändert oder unkenntlich gemacht werden. |
// + Der Kunde trifft angemessene Vorkehrungen für den sicheren Einsatz der Software. Er wird die Software gründlich auf deren |
// + Verwendbarkeit zu dem von ihm beabsichtigten Zweck testen, bevor er diese operativ einsetzt. |
// + Die Haftung des Lizenzgebers wird - soweit gesetzlich zulässig - begrenzt in Höhe des typischen und vorhersehbaren |
// + Schadens. Die gesetzliche Haftung bei Personenschäden und nach dem Produkthaftungsgesetz bleibt unberührt. Dem Lizenzgeber steht jedoch der Einwand |
// + des Mitverschuldens offen. |
// + Der Kunde trifft angemessene Vorkehrungen für den Fall, dass die Software ganz oder teilweise nicht ordnungsgemäß arbeitet. |
// + Er wird die Software gründlich auf deren Verwendbarkeit zu dem von ihm beabsichtigten Zweck testen, bevor er diese operativ einsetzt. |
// + Der Kunde wird er seine Daten vor Einsatz der Software nach dem Stand der Technik sichern. |
// + Der Kunde ist darüber unterrichtet, dass der Lizenzgeber seine Daten im zur Vertragsdurchführung erforderlichen Umfang |
// + und auf Grundlage der Datenschutzvorschriften erhebt, speichert, verarbeitet und, sofern notwendig, an Dritte übermittelt. |
// + *) Die räumliche Nutzung bezieht sich nur auf den Einsatzort, nicht auf die Reichweite der programmierten Software. |
// + #### ENDE DER NUTZUNGSBEDINGUNGEN ####' |
// + Hinweis: Informationen über erweiterte Nutzungsrechte (wie z.B. Nutzung für nicht-private Zwecke) sind auf Anfrage per Email an info(@)hisystems.de verfügbar. |
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
// + Software LICENSING TERMS |
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
// + of HiSystems GmbH, Flachsmeerstrasse 2, 26802 Moormerland, Germany - the Licensor - |
// + The Licensor grants the customer a non-exclusive license to use the microcontroller firmware of the Flight-Ctrl, Navi-Ctrl, BL-Ctrl, and MK3Mag hardware |
// + (the Software) exclusively for private purposes. The License is unrestricted with respect to time and territory*. |
// + The Software may only be used with the Licensor's products. |
// + The Software provided by the Licensor is protected by copyright. With respect to the relationship between the parties to this |
// + agreement, all rights pertaining to the Software and other documents provided during the preparation and execution of this |
// + agreement shall be the property of the Licensor. |
// + The information contained in the Software copyright notices, trademarks, other legal reservations, serial numbers and other |
// + features that can be used to identify the program may not be altered or defaced by the customer. |
// + The customer shall be responsible for taking reasonable precautions |
// + for the safe use of the Software. The customer shall test the Software thoroughly regarding its suitability for the |
// + intended purpose before implementing it for actual operation. The Licensor's liability shall be limited to the extent of typical and |
// + foreseeable damage to the extent permitted by law, notwithstanding statutory liability for bodily injury and product |
// + liability. However, the Licensor shall be entitled to the defense of contributory negligence. |
// + The customer will take adequate precautions in the case, that the software is not working properly. The customer will test |
// + the software for his purpose before any operational usage. The customer will backup his data before using the software. |
// + The customer understands that the Licensor collects, stores and processes, and, where required, forwards, customer data |
// + to third parties to the extent necessary for executing the agreement, subject to applicable data protection and privacy regulations. |
// + *) The territory aspect only refers to the place where the Software is used, not its programmed range. |
// + #### END OF LICENSING TERMS #### |
// + Note: For information on license extensions (e.g. commercial use), please contact us at info(@)hisystems.de. |
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
#include "jetimenu.h" |
#include "libfc.h" |
#include "printf_P.h" |
#include "main.h" |
#include "spi.h" |
#include "capacity.h" |
#include "hottmenu.h" |
#define JETIBOX_KEY_RIGHT 0x1F |
#define JETIBOX_KEY_UP 0x2F |
#define JETIBOX_KEY_DOWN 0x4F |
#define JETIBOX_KEY_LEFT 0x8F |
#define JETIBOX_KEY_NONE 0x0F |
#define JETIBOX_KEY_UNDEF 0x00 |
#define JetiBox_printfxy(x,y,format, args...) { LIBFC_JetiBox_SetPos(y * 16 + x); _printf_P(&LIBFC_JetiBox_Putchar, PSTR(format) , ## args);} |
#define JetiBox_printf(format, args...) { _printf_P(&LIBFC_JetiBox_Putchar, PSTR(format) , ## args);} |
unsigned char JumpToMenu = 0xff; |
// ----------------------------------------------------------- |
// the menu functions |
// ----------------------------------------------------------- |
void Menu_Status(uint8_t key) |
{ //0123456789ABCDEF |
#if !defined (RECEIVER_SPEKTRUM_DX7EXP) && !defined (RECEIVER_SPEKTRUM_DX8EXP) |
JetiBox_printfxy(0,0,"%2i.%1iV",UBat/10, UBat%10); |
if(NaviDataOkay) |
{ |
JetiBox_printfxy(6,0,"%3d%c %3dm%c",CompassCorrected, 0xDF, GPSInfo.HomeDistance/10,NC_GPS_ModeCharacter); |
} |
else |
{ |
JetiBox_printfxy(6,0,"Status "); |
} |
#if (defined(__AVR_ATmega1284__) || defined(__AVR_ATmega1284P__)) |
if(NC_ErrorCode) |
{ |
static unsigned int timer; |
static char toggle = 1; |
if(CheckDelay(timer)) { if(toggle) toggle = 0; else toggle = 1; timer = SetDelay(1500);}; |
if(toggle) |
{ |
LIBFC_JetiBox_SetPos(0); |
_printf_P(&LIBFC_JetiBox_Putchar, NC_ERROR_TEXT[NC_ErrorCode] , 0); |
} |
else |
{ |
JetiBox_printfxy(6,0,"ERROR: %2d ",NC_ErrorCode); |
// if(MotorenEin) JetiBeep = 'O'; |
} |
} |
else |
if(NC_To_FC_Flags & NC_TO_FC_SIMULATION_ACTIVE) |
{ |
JetiBox_printfxy(6,0,"SIMULATION"); |
} |
else |
if(ShowSettingNameTime) |
{ |
LIBFC_JetiBox_Clear(); |
JetiBox_printfxy(0,0,"Set%d:%s",ActiveParamSet,EE_Parameter.Name); |
if(FC_StatusFlags3 & FC_STATUS3_BOAT) JetiBox_printfxy(0,1,"(Boat-Mode)"); |
return; // nichts weiter ausgeben |
} |
#else |
if(NC_ErrorCode) { JetiBox_printfxy(6,0,"ERROR: %2d ",NC_ErrorCode); if(MotorenEin) JetiBeep = 'S';}; |
#endif |
JetiBox_printfxy(0,1,"%4i %2i:%02i",Capacity.UsedCapacity,FlugSekunden/60,FlugSekunden%60); |
if(Parameter_GlobalConfig & CFG_HOEHENREGELUNG) |
{ |
JetiBox_printfxy(10,1,"%4im%c", (int16_t)(HoehenWert/100),VarioCharacter); |
} |
if(FC_StatusFlags3 & FC_STATUS3_REDUNDANCE_AKTIVE) JetiBox_printfxy(10,1,"R"); |
#endif |
} |
void Menu_Temperature(uint8_t key) |
{ //0123456789ABCDEF |
#if !defined (RECEIVER_SPEKTRUM_DX7EXP) && !defined (RECEIVER_SPEKTRUM_DX8EXP) |
JetiBox_printfxy(0,0,"%3i %3i %3i %3i", Motor[0].Temperature, Motor[1].Temperature, Motor[2].Temperature, Motor[3].Temperature); |
JetiBox_printfxy(0,1,"%3i %3i %3i %3i", Motor[4].Temperature, Motor[5].Temperature, Motor[6].Temperature, Motor[7].Temperature); |
if(RequiredMotors <= 4) |
{ |
JetiBox_printfxy(0,1,"Temperatures "); |
} |
else |
if(RequiredMotors <= 6) |
{ |
JetiBox_printfxy(8,1,"\%cC ",0xdf); |
} |
#endif |
} |
void Menu_Battery(uint8_t key) |
{ //0123456789ABCDEF |
#if !defined (RECEIVER_SPEKTRUM_DX7EXP) && !defined (RECEIVER_SPEKTRUM_DX8EXP) |
JetiBox_printfxy(0,0,"%2i.%1iV %3i.%1iA", UBat/10, UBat%10, Capacity.ActualCurrent/10, Capacity.ActualCurrent%10); |
JetiBox_printfxy(0,1,"%4iW %6imAh",Capacity.ActualPower, Capacity.UsedCapacity); |
#endif |
} |
void Magnet_Values(uint8_t key) |
{ //0123456789ABCDEF |
#if !defined (RECEIVER_SPEKTRUM_DX7EXP) && !defined (RECEIVER_SPEKTRUM_DX8EXP) |
JetiBox_printfxy(0,0,"Magnet:%3i%% %3i%c",EarthMagneticField, KompassValue,0xDF); |
JetiBox_printfxy(0,1,"Incli.:%3i%c (%i) ",EarthMagneticInclination, 0xDF,EarthMagneticInclinationTheoretic); |
#endif |
} |
void Menu_WPL_A1(uint8_t key) |
{ //0123456789ABCDEF |
#if !defined (RECEIVER_SPEKTRUM_DX7EXP) && !defined (RECEIVER_SPEKTRUM_DX8EXP) |
JetiBox_printfxy(0,0,"Load Waypoints"); |
JetiBox_printfxy(0,1,"(Fixed) "); |
#endif |
} |
void Menu_WPL_R1(uint8_t key) |
{ //0123456789ABCDEF |
#if !defined (RECEIVER_SPEKTRUM_DX7EXP) && !defined (RECEIVER_SPEKTRUM_DX8EXP) |
JetiBox_printfxy(0,0,"Load Waypoints"); |
JetiBox_printfxy(0,1,"(Relative) "); |
#endif |
} |
#if (defined(__AVR_ATmega1284__) || defined(__AVR_ATmega1284P__)) |
void Menu_POINT_LD(uint8_t key) |
{ //0123456789ABCDEF |
JetiBox_printfxy(0,0,"Load singl.Point"); |
// JetiBox_printfxy(0,1,"(Fixed) "); |
} |
#endif |
#if (defined(__AVR_ATmega1284__) || defined(__AVR_ATmega1284P__)) |
void Menu_POINT_SV(uint8_t key) |
{ //0123456789ABCDEF |
JetiBox_printfxy(0,0,"Save singl.Point"); |
// JetiBox_printfxy(0,1,"(Relative) "); |
} |
void Menu_AccCal_Ask(uint8_t key) |
{ //0123456789ABCDEF |
JetiBox_printfxy(0,0,"ACC calibration"); |
// JetiBox_printfxy(0,1,"(Relative) "); |
} |
void Menu_AccCal(uint8_t key) |
{ |
static unsigned char changed = 0; |
//0123456789ABCDEF |
JetiBox_printfxy(0,0,"ACC calibration"); |
if((FC_StatusFlags & FC_STATUS_MOTOR_RUN) && ((NC_GPS_ModeCharacter == ' ') || (NC_GPS_ModeCharacter == '/') || (NC_GPS_ModeCharacter == '-'))) |
{ |
if(!EE_Parameter.Driftkomp) EE_Parameter.Driftkomp = 6; // enables the Gyro-Drift compensation to make sure that a litlte calibration error won't effect the attitude |
JetiBox_printfxy(0,0,"ACC N=%3i R=%3i",NeutralAccX,NeutralAccY); |
if(ChannelNick || ChannelRoll) |
JetiBox_printfxy(0,1,"Stick! (%i/%i)",ChannelNick,ChannelRoll) |
else //0123456789ABCDEF |
if(changed) JetiBox_printfxy(0,1,"land to save ") |
else JetiBox_printfxy(0,1,"use keys now ") |
if(key== JETIBOX_KEY_UP ) {NeutralAccX++;JetiBeep=130; changed = 1;} |
if(key== JETIBOX_KEY_DOWN ) {NeutralAccX--;JetiBeep=130; changed = 1;} |
if(key== JETIBOX_KEY_RIGHT ) {NeutralAccY++;JetiBeep=130; changed = 1;} |
if(key== JETIBOX_KEY_LEFT) {NeutralAccY--;JetiBeep=130; changed = 1;} |
} |
else |
{ |
if(!(FC_StatusFlags & FC_STATUS_MOTOR_RUN)) // motors are off |
{ |
if(key == JETIBOX_KEY_LEFT) { JumpToMenu = 0; changed = 0; }// Exit |
if(changed == 0) JetiBox_printfxy(0,1,"Fly with GPS off") |
else |
if(changed == 1) |
{ |
JetiBox_printfxy(0,1," save -->") |
if(key== JETIBOX_KEY_RIGHT) |
{ |
StoreNeutralToEeprom(); |
JetiBeep = 130; |
changed = 2; |
} |
} |
else |
if(changed == 2) |
{ |
JetiBox_printfxy(0,1," values stored "); |
} |
} //0123456789ABCDEF |
else JetiBox_printfxy(0,1,"switch GPS off ") |
} |
// JetiBox_printfxy(0,1,"(Relative) "); |
} |
#endif |
#if (defined(__AVR_ATmega1284__) || defined(__AVR_ATmega1284P__)) |
void Menu_POINT_SV2(uint8_t key) |
{ //0123456789ABCDEF |
static unsigned char load_waypoint_tmp = 0, changed, hyterese = 1; |
static int delay; |
// if(WPL_Name[0] == 0) JetiBox_printfxy(0,0,"Relative WPs ") |
// else JetiBox_printfxy(0,0,"Rel:%s",WPL_Name); |
JetiBox_printfxy(0,0,"Save Point:"); |
if(NaviData_MaxWpListIndex == 0) JetiBox_printfxy(0,1,"no SD-Card") |
else |
if(GPSInfo.SatFix != SATFIX_3D) JetiBox_printfxy(0,1,"no GPS-Fix") |
else |
{ |
if(load_waypoint_tmp) JetiBox_printfxy(11,0,"%2d",load_waypoint_tmp) |
else JetiBox_printfxy(11,0,"--"); |
// if(NaviData_WaypointNumber) JetiBox_printfxy(8,1,"%2d/%d ",NaviData_WaypointIndex,NaviData_WaypointNumber) |
// else JetiBox_printfxy(8,1,"--/--") |
JetiBox_printfxy(0,1,"Dir:%3d Alt:%3dm",CompassCorrected,(int16_t)(HoehenWert/100)) |
if(changed) JetiBox_printfxy(14,0,"->") |
else JetiBox_printfxy(14,0," "); |
if(key == JETIBOX_KEY_UP && load_waypoint_tmp < NaviData_MaxWpListIndex) { load_waypoint_tmp++; changed = 1;} |
if(key == JETIBOX_KEY_DOWN && load_waypoint_tmp > 1) { load_waypoint_tmp--; changed = 1; } |
if(key == JETIBOX_KEY_RIGHT && load_waypoint_tmp) |
{ |
ToNC_Store_SingePoint = load_waypoint_tmp; |
changed = 0; |
} |
// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
// Bedienung per Taster am Sender |
if(PPM_in[EE_Parameter.MenuKeyChannel] > 50) // |
{ |
hyterese = 2; |
if(CheckDelay(delay)) { load_waypoint_tmp = 0; hyterese = 1;} |
} |
else |
if(PPM_in[EE_Parameter.MenuKeyChannel] < -50) |
{ |
delay = SetDelay(2500); |
if(hyterese == 2 && (load_waypoint_tmp < NaviData_MaxWpListIndex)) |
{ |
load_waypoint_tmp++; |
ToNC_Store_SingePoint = load_waypoint_tmp; |
changed = 0; |
// JetiBeep = 'A'; // "MikroKopter" |
} |
hyterese = 0; |
} |
// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
} |
} |
#endif |
#if (defined(__AVR_ATmega1284__) || defined(__AVR_ATmega1284P__)) |
void Menu_POINT_LD2(uint8_t key) |
{ //0123456789ABCDEF |
static unsigned char load_waypoint_tmp = 0, changed, hyterese = 1; |
static int delay; |
// if(WPL_Name[0] == 0) JetiBox_printfxy(0,0,"FIX Waypoints") |
// else JetiBox_printfxy(0,0,"FIX:%s",WPL_Name); |
JetiBox_printfxy(0,0,"Load Point") |
if(NaviData_MaxWpListIndex == 0) JetiBox_printfxy(0,1,"no SD-Card") |
else |
{ |
if(load_waypoint_tmp) JetiBox_printfxy(11,0,"%2d",load_waypoint_tmp) |
else JetiBox_printfxy(11,0,"--"); |
if(NaviData_WaypointNumber) JetiBox_printfxy(0,1,"Dist:%3d Alt:%3d ",NaviData_TargetDistance,(int16_t)(FromNC_AltitudeSetpoint/100)) |
else JetiBox_printfxy(8,1," "); |
if(changed) JetiBox_printfxy(14,0,"->") |
else JetiBox_printfxy(14,0," "); |
if(key == JETIBOX_KEY_UP && load_waypoint_tmp < NaviData_MaxWpListIndex) { load_waypoint_tmp++; changed = 1;} |
if(key == JETIBOX_KEY_DOWN && load_waypoint_tmp > 1) { load_waypoint_tmp--; changed = 1; } |
if(key == JETIBOX_KEY_RIGHT && load_waypoint_tmp) |
{ |
ToNC_Load_SingePoint = load_waypoint_tmp; |
changed = 0; |
} |
// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
// Bedienung per Taster am Sender |
if(PPM_in[EE_Parameter.MenuKeyChannel] > 50) // |
{ |
hyterese = 2; |
if(CheckDelay(delay)) { load_waypoint_tmp = 0; hyterese = 1;} |
} |
else |
if(PPM_in[EE_Parameter.MenuKeyChannel] < -50) |
{ |
delay = SetDelay(2500); |
if(hyterese == 2 && (load_waypoint_tmp < NaviData_MaxWpListIndex)) |
{ |
load_waypoint_tmp++; |
ToNC_Load_SingePoint = load_waypoint_tmp; |
changed = 0; |
// JetiBeep = 'A'; // "MikroKopter" |
} |
hyterese = 0; |
} |
// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
} |
} |
#endif |
void Menu_WPL_A2(uint8_t key) |
{ //0123456789ABCDEF |
#if !defined (RECEIVER_SPEKTRUM_DX7EXP) && !defined (RECEIVER_SPEKTRUM_DX8EXP) |
static unsigned char load_waypoint_tmp = 1, changed; |
if(WPL_Name[0] == 0) JetiBox_printfxy(0,0,"FIX Waypoints") |
else JetiBox_printfxy(0,0,"FIX:%s",WPL_Name); |
if(NaviData_MaxWpListIndex == 0) JetiBox_printfxy(0,1,"no SD-Card") |
else |
{ |
JetiBox_printfxy(0,1,"#%2d WP:",load_waypoint_tmp); |
if(NaviData_WaypointNumber) JetiBox_printfxy(8,1,"%2d/%d ",NaviData_WaypointIndex,NaviData_WaypointNumber) |
else JetiBox_printfxy(8,1,"--/--") |
if(changed) JetiBox_printfxy(14,1,"->") |
else JetiBox_printfxy(14,1," "); |
if(key == JETIBOX_KEY_UP && load_waypoint_tmp < NaviData_MaxWpListIndex) { load_waypoint_tmp++; changed = 1;} |
if(key == JETIBOX_KEY_DOWN && load_waypoint_tmp > 1) { load_waypoint_tmp--; changed = 1; } |
if(key == JETIBOX_KEY_RIGHT && load_waypoint_tmp) |
{ |
ToNC_Load_WP_List = load_waypoint_tmp; |
changed = 0; |
} |
} |
#endif |
} |
void Menu_WPL_R2(uint8_t key) |
{ //0123456789ABCDEF |
#if !defined (RECEIVER_SPEKTRUM_DX7EXP) && !defined (RECEIVER_SPEKTRUM_DX8EXP) |
static unsigned char load_waypoint_tmp = 1, changed; |
if(WPL_Name[0] == 0) JetiBox_printfxy(0,0,"Relative WPs ") |
else JetiBox_printfxy(0,0,"Rel:%s",WPL_Name); |
if(NaviData_MaxWpListIndex == 0) JetiBox_printfxy(0,1,"no SD-Card") |
else |
if(GPSInfo.SatFix != SATFIX_3D) JetiBox_printfxy(0,1,"no GPS-Fix") |
else |
{ |
JetiBox_printfxy(0,1,"#%2d WPs:",load_waypoint_tmp); |
if(NaviData_WaypointNumber) JetiBox_printfxy(8,1,"%2d/%d ",NaviData_WaypointIndex,NaviData_WaypointNumber) |
else JetiBox_printfxy(8,1,"--/--") |
if(changed) JetiBox_printfxy(14,1,"->") |
else JetiBox_printfxy(14,1," "); |
if(key == JETIBOX_KEY_UP && load_waypoint_tmp < NaviData_MaxWpListIndex) { load_waypoint_tmp++; changed = 1;} |
if(key == JETIBOX_KEY_DOWN && load_waypoint_tmp > 1) { load_waypoint_tmp--; changed = 1; } |
if(key == JETIBOX_KEY_RIGHT && load_waypoint_tmp) |
{ |
ToNC_Load_WP_List = load_waypoint_tmp | 0x80; |
changed = 0; |
} |
} |
#endif |
} |
void Menu_PosInfo(uint8_t key) |
{ |
#if !defined (RECEIVER_SPEKTRUM_DX7EXP) && !defined (RECEIVER_SPEKTRUM_DX8EXP) |
if(NaviDataOkay) |
{ |
JetiBox_printfxy(0,0,"%2um/s Sat:%d ",GPSInfo.Speed,GPSInfo.NumOfSats); |
switch (GPSInfo.SatFix) |
{ |
case SATFIX_3D: |
JetiBox_printfxy(12,0," 3D"); |
break; |
// case SATFIX_2D: |
// case SATFIX_NONE: |
default: |
JetiBox_printfxy(12,0,"NoFx"); |
break; |
} |
if(GPSInfo.Flags & FLAG_DIFFSOLN) |
{ |
JetiBox_printfxy(12,0,"DGPS"); |
} |
JetiBox_printfxy(0,1,"Home:%3dm %3d%c %c", GPSInfo.HomeDistance/10, GPSInfo.HomeBearing, 0xDF,NC_GPS_ModeCharacter); |
} |
else |
{ //0123456789ABCDEF |
JetiBox_printfxy(2,0,"No NaviCtrl!"); |
} |
#endif |
} |
// ----------------------------------------------------------- |
// the menu topology |
// ----------------------------------------------------------- |
typedef void (*pFctMenu) (uint8_t); // the menu item handler function pointer |
typedef struct{ |
int8_t left; |
int8_t right; |
int8_t up; |
int8_t down; |
pFctMenu pHandler; |
} MENU_ENTRY; |
// the menu navigation structure |
/* | |
3 - 0 - 1 - 2 - 3 - 0 |
*/ |
const MENU_ENTRY JetiBox_Menu[] PROGMEM= |
{ // l r u d pHandler |
#if !defined (RECEIVER_SPEKTRUM_DX7EXP) && !defined (RECEIVER_SPEKTRUM_DX8EXP) |
#if (defined(__AVR_ATmega1284__) || defined(__AVR_ATmega1284P__)) |
#define ACC_CAL 13 |
{8, 1, 0, 0, &Menu_Status }, // 0 |
{0, 2, 1, 1, &Menu_Temperature }, // 1 |
{1, 3, 2, 2, &Menu_Battery }, // 2 |
{2, 4, 3, 3, &Menu_PosInfo }, // 3 |
{3, 5, 4,10, &Menu_WPL_A1 }, // 4 |
{4, 6, 5,11, &Menu_WPL_R1 }, // 5 |
{5, 7, 6,12, &Menu_POINT_LD}, // 6 |
{6, 8, 7,13, &Menu_POINT_SV}, // 7 |
{7, 9, 8, 8, &Magnet_Values }, // 8 |
{8, 0, 9,14, &Menu_AccCal_Ask},// 9 |
{4,10,10,10, &Menu_WPL_A2 }, // 10 |
{5,11,11,11, &Menu_WPL_R2 }, // 11 |
{6,12,12,12, &Menu_POINT_LD2}, // 12 |
{7,13,13,13, &Menu_POINT_SV2}, // 13 |
{14,14,14,14, &Menu_AccCal}, // 14 |
#else |
{6, 1, 0, 0, &Menu_Status }, // 0 |
{0, 2, 1, 1, &Menu_Temperature }, // 1 |
{1, 3, 2, 2, &Menu_Battery }, // 2 |
{2, 4, 3, 3, &Menu_PosInfo }, // 3 |
{3, 5, 7, 7, &Menu_WPL_A1 }, // 4 |
{4, 6, 8, 8, &Menu_WPL_R1 }, // 5 |
{5, 0, 6, 6, &Magnet_Values }, // 6 |
{4, 7, 7, 7, &Menu_WPL_A2 }, // 7 |
{5, 8, 8, 8, &Menu_WPL_R2 }, // 8 |
#endif |
#endif |
}; |
// ----------------------------------------------------------- |
// Update display buffer |
// ----------------------------------------------------------- |
unsigned char JetiBox_Update(unsigned char key) |
{ |
#if !defined (RECEIVER_SPEKTRUM_DX7EXP) && !defined (RECEIVER_SPEKTRUM_DX8EXP) |
static uint8_t item = 0, last_item = 0; // the menu item |
static uint8_t updateDelay = 1 , last_key; |
// navigate within the menu by key action |
last_item = item; |
switch(key) |
{ |
case JETIBOX_KEY_LEFT: |
//if (item == 0) return (1); // switch back to jeti expander menu |
// else |
item = pgm_read_byte(&JetiBox_Menu[item].left); //trigger to left menu item |
break; |
case JETIBOX_KEY_RIGHT: |
item = pgm_read_byte(&JetiBox_Menu[item].right); //trigger to right menu item |
break; |
case JETIBOX_KEY_UP: |
item = pgm_read_byte(&JetiBox_Menu[item].up); //trigger to up menu item |
break; |
case JETIBOX_KEY_DOWN: |
item = pgm_read_byte(&JetiBox_Menu[item].down); //trigger to down menu item |
break; |
default: |
break; |
} |
if(JumpToMenu != 0xff) { item = JumpToMenu; JumpToMenu = 0xff;}; |
// if the menu item has been changed, do not pass the key to the item handler |
// to avoid jumping over to items |
if(item != last_item) key = JETIBOX_KEY_UNDEF; |
// if((updateDelay++ & 0x01) || (key != last_key)) |
if((updateDelay++ & 0x01) || (key != JETIBOX_KEY_NONE)) |
{ |
last_key = key; |
LIBFC_JetiBox_Clear(); |
//execute menu item handler |
((pFctMenu)(pgm_read_word(&(JetiBox_Menu[item].pHandler))))(key); |
} |
#endif |
return (0); |
} |
/tags/V2.12a/jetimenu.h |
---|
0,0 → 1,6 |
#ifndef _JETIMENU_H |
#define _JETIMENU_H |
extern unsigned char JetiBox_Update(unsigned char key); |
#endif //_JETIMENU_H |
/tags/V2.12a/led.c |
---|
0,0 → 1,144 |
#include <inttypes.h> |
#include "main.h" |
uint16_t LED1_Timing = 0; |
uint16_t LED2_Timing = 0; |
unsigned char J16Blinkcount = 0, J16Mask = 1; |
unsigned char J17Blinkcount = 0, J17Mask = 1; |
unsigned char NC_Wait_for_LED = 0; // signal to NC: Wait for the LAD PAtter before switching to the next WP |
unsigned int ShutterCounter = 0; |
unsigned char Out1ChangedFlag = 0; // can be 0 or 0x80 |
// initializes the LED control outputs J16, J17 |
void LED_Init(void) |
{ |
// set PC2 & PC3 as output (control of J16 & J17) |
DDRC |= (1<<DDC2)|(1<<DDC3); |
J16_OFF; |
J17_OFF; |
J16Blinkcount = 0; J16Mask = 128; |
J17Blinkcount = 0; J17Mask = 128; |
} |
// called in UpdateMotors() every 2ms |
void LED_Update(void) |
{ |
static char delay = 0, last_portC = 0; |
static unsigned char J16Bitmask = 0; |
static unsigned char J17Bitmask = 0; |
static unsigned char J16Warn = 0, J17Warn = 0; |
static unsigned char from_nc = 0; // Copy for the timing |
if(!NC_Wait_for_LED) from_nc = (unsigned char) PPM_in[WP_EVENT_PPM_IN] + 127; |
if(!delay--) // 20ms Intervall |
{ |
J16Bitmask = EE_Parameter.J16Bitmask; |
J17Bitmask = EE_Parameter.J17Bitmask; |
delay = 9; |
if(FC_StatusFlags & (FC_STATUS_LOWBAT | FC_STATUS_EMERGENCY_LANDING) || (VersionInfo.HardwareError[1] & FC_ERROR1_I2C) || !SenderOkay) |
{ |
if(EE_Parameter.WARN_J16_Bitmask) |
{ |
if(!J16Warn) J16Blinkcount = 4; |
J16Warn = 1; |
} |
if(EE_Parameter.WARN_J17_Bitmask) |
{ |
if(!J17Warn) J17Blinkcount = 4; |
J17Warn = 1; |
} |
} |
else |
{ |
J16Warn = 0; |
J17Warn = 0; |
} |
//DebugOut.Analog[29] = EE_Parameter.GlobalConfig3; |
// Output 1 |
if(!J16Warn) |
{ |
if((EE_Parameter.BitConfig & CFG_MOTOR_BLINK1) && !MotorenEin) {if(EE_Parameter.BitConfig & CFG_MOTOR_OFF_LED1) J16_ON; else J16_OFF;} |
else |
if((EE_Parameter.J16Timing > 247) && (Parameter_J16Timing > 220)) {if(J16Bitmask & 128) J16_OFF; else J16_ON; J16Mask = 1; NC_Wait_for_LED = 0;} // Manual overwrite |
else |
if((EE_Parameter.J16Timing > 247) && (Parameter_J16Timing == 5)) {if(J16Bitmask & 128) J16_ON; else J16_OFF; J16Mask = 1; NC_Wait_for_LED = 0;} // Manual overwrite |
else |
if(!J16Blinkcount--) |
{ |
if(EE_Parameter.GlobalConfig3 & CFG3_USE_NC_FOR_OUT1) |
{ |
J16Blinkcount = from_nc / 2; |
if(!from_nc) { NC_Wait_for_LED = 0; if(J16Bitmask & 128) J16_ON; else J16_OFF; J16Mask = 0; } // Ausschalten |
else |
{ |
NC_Wait_for_LED = 1; |
if(J16Mask == 0) |
{ |
from_nc = FromNC_WP_EventChannel_New; |
J16Mask = 64; |
if(J16Bitmask & 128) J16_ON; else J16_OFF; // Ausschalten |
} |
else |
{ |
if(J16Mask & J16Bitmask) J16_ON; else J16_OFF; |
J16Mask /= 2; |
if(J16Mask == 0x01) FromNC_WP_EventChannel_New = 0; // Last Bit -> Refresh the value by NC now |
} |
} |
} |
else |
{ |
J16Blinkcount = Parameter_J16Timing / 2; |
if(J16Mask == 1) { from_nc = 0; J16Mask = 64; } else J16Mask /= 2; |
if(J16Mask & J16Bitmask) J16_ON; else J16_OFF; |
NC_Wait_for_LED = 0; |
} |
} |
} |
else // warning case |
if(!J16Blinkcount--) |
{ |
J16Blinkcount = 10-1; |
if(J16Mask == 1) J16Mask = 128; else J16Mask /= 2; |
if(J16Mask & EE_Parameter.WARN_J16_Bitmask) J16_ON; else J16_OFF; |
} |
// Output 2 |
if(!J17Warn) |
{ |
if((EE_Parameter.BitConfig & CFG_MOTOR_BLINK2) && !MotorenEin) {if(EE_Parameter.BitConfig & CFG_MOTOR_OFF_LED2) J17_ON; else J17_OFF;} |
else |
if((EE_Parameter.J17Timing > 247) && (Parameter_J17Timing > 220)) {if(J17Bitmask & 128) J17_OFF; else J17_ON; J17Mask = 1;} |
else |
if((EE_Parameter.J17Timing > 247) && (Parameter_J17Timing == 5)) {if(J17Bitmask & 128) J17_ON; else J17_OFF; J17Mask = 1;} |
else |
if(!J17Blinkcount--) |
{ |
J17Blinkcount = Parameter_J17Timing / 2; |
if(J17Mask == 1) J17Mask = 64; else J17Mask /= 2; |
if(J17Mask & J17Bitmask) J17_ON; else J17_OFF; |
} |
} |
else // warning case |
if(!J17Blinkcount--) |
{ |
J17Blinkcount = 10-1; |
if(J17Mask == 1) J17Mask = 128; else J17Mask /= 2; |
if(J17Mask & EE_Parameter.WARN_J17_Bitmask) J17_ON; else J17_OFF; |
} |
if(PORTC & (1<<PORTC2)) // output is on |
{ |
if(!(last_portC & (1<<PORTC2))) |
{ |
Out1ChangedFlag = 0x80;// this Flag marks a changed Out1; |
ShutterCounter++; // count if output swiched to high |
} |
FC_StatusFlags2 |= FC_STATUS2_OUT1_ACTIVE; //else FC_StatusFlags2 &= ~FC_STATUS2_OUT1_ACTIVE; // Out1 (J16) -> wird in der SPI zurück gesetzt |
} |
if(PORTC & (1<<PORTC3)) FC_StatusFlags2 |= FC_STATUS2_OUT2_ACTIVE; else FC_StatusFlags2 &= ~FC_STATUS2_OUT2_ACTIVE; // Out2 (J17) |
last_portC = PORTC; |
} |
} |
/tags/V2.12a/led.h |
---|
0,0 → 1,14 |
#include <avr/io.h> |
#define J16_ON PORTC |= (1<<PORTC2) |
#define J16_OFF PORTC &= ~(1<<PORTC2) |
#define J16_TOGGLE PORTC ^= (1<<PORTC2) |
#define J17_ON PORTC |= (1<<PORTC3) |
#define J17_OFF PORTC &= ~(1<<PORTC3) |
#define J17_TOGGLE PORTC ^= (1<<PORTC3) |
extern void LED_Init(void); |
extern void LED_Update(void); |
extern unsigned char NC_Wait_for_LED; |
extern unsigned int ShutterCounter; |
extern unsigned char Out1ChangedFlag; // can be 0 or 0x80 |
/tags/V2.12a/libfc.h |
---|
0,0 → 1,24 |
#ifndef _LIBFC_H |
#define _LIBFC_H |
#define CPU_UNKNOWN 0 |
#define CPU_ATMEGA644 1 |
#define CPU_ATMEGA644P 2 |
#define CPU_ATMEGA1284 3 |
#define CPU_ATMEGA1284P 4 |
extern void LIBFC_Init(unsigned char); |
extern void LIBFC_Polling(void); |
extern void LIBFC_ReceiverInit(unsigned char rtype); |
extern void LIBFC_JetiBox_Putchar(char c); |
extern void LIBFC_JetiBox_SetPos(unsigned char index); |
extern void LIBFC_JetiBox_Clear(void); |
extern void LIBFC_CheckSettings(void); |
extern unsigned char LIBFC_GetCPUType(void); |
#if (defined(__AVR_ATmega1284__) || defined(__AVR_ATmega1284P__)) |
extern long ACC_AltitudeFusion(unsigned char init); |
#endif |
#endif //_LIBFC_H |
/tags/V2.12a/libfc1284.a |
---|
Cannot display: file marked as a binary type. |
svn:mime-type = application/octet-stream |
Property changes: |
Added: svn:mime-type |
+application/octet-stream |
\ No newline at end of property |
/tags/V2.12a/libfc644.a |
---|
Cannot display: file marked as a binary type. |
svn:mime-type = application/octet-stream |
Property changes: |
Added: svn:mime-type |
+application/octet-stream |
\ No newline at end of property |
/tags/V2.12a/main.c |
---|
0,0 → 1,683 |
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
// + www.MikroKopter.com |
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
// + Software Nutzungsbedingungen (english version: see below) |
// + der Fa. HiSystems GmbH, Flachsmeerstrasse 2, 26802 Moormerland - nachfolgend Lizenzgeber genannt - |
// + Der Lizenzgeber räumt dem Kunden ein nicht-ausschließliches, zeitlich und räumlich* unbeschränktes Recht ein, die im den |
// + Mikrocontroller verwendete Firmware für die Hardware Flight-Ctrl, Navi-Ctrl, BL-Ctrl, MK3Mag & PC-Programm MikroKopter-Tool |
// + - nachfolgend Software genannt - nur für private Zwecke zu nutzen. |
// + Der Einsatz dieser Software ist nur auf oder mit Produkten des Lizenzgebers zulässig. |
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
// + Die vom Lizenzgeber gelieferte Software ist urheberrechtlich geschützt. Alle Rechte an der Software sowie an sonstigen im |
// + Rahmen der Vertragsanbahnung und Vertragsdurchführung überlassenen Unterlagen stehen im Verhältnis der Vertragspartner ausschließlich dem Lizenzgeber zu. |
// + Die in der Software enthaltenen Copyright-Vermerke, Markenzeichen, andere Rechtsvorbehalte, Seriennummern sowie |
// + sonstige der Programmidentifikation dienenden Merkmale dürfen vom Kunden nicht verändert oder unkenntlich gemacht werden. |
// + Der Kunde trifft angemessene Vorkehrungen für den sicheren Einsatz der Software. Er wird die Software gründlich auf deren |
// + Verwendbarkeit zu dem von ihm beabsichtigten Zweck testen, bevor er diese operativ einsetzt. |
// + Die Haftung des Lizenzgebers wird - soweit gesetzlich zulässig - begrenzt in Höhe des typischen und vorhersehbaren |
// + Schadens. Die gesetzliche Haftung bei Personenschäden und nach dem Produkthaftungsgesetz bleibt unberührt. Dem Lizenzgeber steht jedoch der Einwand |
// + des Mitverschuldens offen. |
// + Der Kunde trifft angemessene Vorkehrungen für den Fall, dass die Software ganz oder teilweise nicht ordnungsgemäß arbeitet. |
// + Er wird die Software gründlich auf deren Verwendbarkeit zu dem von ihm beabsichtigten Zweck testen, bevor er diese operativ einsetzt. |
// + Der Kunde wird er seine Daten vor Einsatz der Software nach dem Stand der Technik sichern. |
// + Der Kunde ist darüber unterrichtet, dass der Lizenzgeber seine Daten im zur Vertragsdurchführung erforderlichen Umfang |
// + und auf Grundlage der Datenschutzvorschriften erhebt, speichert, verarbeitet und, sofern notwendig, an Dritte übermittelt. |
// + *) Die räumliche Nutzung bezieht sich nur auf den Einsatzort, nicht auf die Reichweite der programmierten Software. |
// + #### ENDE DER NUTZUNGSBEDINGUNGEN ####' |
// + Hinweis: Informationen über erweiterte Nutzungsrechte (wie z.B. Nutzung für nicht-private Zwecke) sind auf Anfrage per Email an info(@)hisystems.de verfügbar. |
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
// + Software LICENSING TERMS |
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
// + of HiSystems GmbH, Flachsmeerstrasse 2, 26802 Moormerland, Germany - the Licensor - |
// + The Licensor grants the customer a non-exclusive license to use the microcontroller firmware of the Flight-Ctrl, Navi-Ctrl, BL-Ctrl, and MK3Mag hardware |
// + (the Software) exclusively for private purposes. The License is unrestricted with respect to time and territory*. |
// + The Software may only be used with the Licensor's products. |
// + The Software provided by the Licensor is protected by copyright. With respect to the relationship between the parties to this |
// + agreement, all rights pertaining to the Software and other documents provided during the preparation and execution of this |
// + agreement shall be the property of the Licensor. |
// + The information contained in the Software copyright notices, trademarks, other legal reservations, serial numbers and other |
// + features that can be used to identify the program may not be altered or defaced by the customer. |
// + The customer shall be responsible for taking reasonable precautions |
// + for the safe use of the Software. The customer shall test the Software thoroughly regarding its suitability for the |
// + intended purpose before implementing it for actual operation. The Licensor's liability shall be limited to the extent of typical and |
// + foreseeable damage to the extent permitted by law, notwithstanding statutory liability for bodily injury and product |
// + liability. However, the Licensor shall be entitled to the defense of contributory negligence. |
// + The customer will take adequate precautions in the case, that the software is not working properly. The customer will test |
// + the software for his purpose before any operational usage. The customer will backup his data before using the software. |
// + The customer understands that the Licensor collects, stores and processes, and, where required, forwards, customer data |
// + to third parties to the extent necessary for executing the agreement, subject to applicable data protection and privacy regulations. |
// + *) The territory aspect only refers to the place where the Software is used, not its programmed range. |
// + #### END OF LICENSING TERMS #### |
// + Note: For information on license extensions (e.g. commercial use), please contact us at info(@)hisystems.de. |
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
#include "main.h" |
unsigned char DisableRcOffBeeping = 0; |
unsigned char PlatinenVersion = 10; |
unsigned char BattLowVoltageWarning = 94; |
unsigned char BattAutoLandingVoltage = 0, BattComingHomeVoltage = 0; |
unsigned int FlugMinuten = 0,FlugMinutenGesamt = 0; |
unsigned int FlugSekunden = 0; |
pVoidFnct_pVoidFnctChar_const_fmt _printf_P; |
unsigned char FoundMotors = 0; |
unsigned char JetiBeep = 0; // to allow any Morse-Beeping of the Jeti-Box |
unsigned char ActiveParamSet = 3; |
unsigned char LipoCells = 4; |
void PrintLine(void) |
{ |
printf("\n\r==================================="); |
} |
void CalMk3Mag(void) |
{ |
static unsigned char stick = 1; |
ChannelAssingment(); |
if(ChannelNick > -20) stick = 0; |
if((ChannelNick < -70) && !stick) |
{ |
stick = 1; |
WinkelOut.CalcState++; |
if(WinkelOut.CalcState > 4) |
{ |
// WinkelOut.CalcState = 0; // in Uart.c |
beeptime = 1000; |
} |
else Piep(WinkelOut.CalcState,150); |
} |
} |
void LipoDetection(unsigned char print) |
{ |
unsigned int warning; |
#define MAX_CELL_VOLTAGE 43 // max cell voltage for LiPO |
if(print) |
{ |
printf("\n\rBatt:"); |
LipoCells = 1 + UBat / MAX_CELL_VOLTAGE; |
if(LipoCells > 6) LipoCells = 6; |
} |
if(EE_Parameter.UnterspannungsWarnung < 50) |
{ |
warning = LipoCells * EE_Parameter.UnterspannungsWarnung; |
if(print) |
{ |
Piep(LipoCells, 200); |
printf(" %d Cells ", LipoCells); |
} |
} |
else warning = EE_Parameter.UnterspannungsWarnung; |
if(warning > 255) warning = 255; BattLowVoltageWarning = warning; |
// automatische Zellenerkennung |
if(EE_Parameter.AutoLandingVoltage < 50) warning = LipoCells * EE_Parameter.AutoLandingVoltage; else warning = EE_Parameter.AutoLandingVoltage; |
if(warning > 255) warning = 255; BattAutoLandingVoltage = warning; |
if(EE_Parameter.ComingHomeVoltage < 50) warning = LipoCells * EE_Parameter.ComingHomeVoltage; else warning = EE_Parameter.ComingHomeVoltage; |
if(warning > 255) warning = 255; BattComingHomeVoltage = warning; |
if(BattAutoLandingVoltage > BattLowVoltageWarning) BattAutoLandingVoltage = BattLowVoltageWarning - 1; |
if(BattComingHomeVoltage >= BattLowVoltageWarning) BattComingHomeVoltage = BattLowVoltageWarning - 1; |
if(BattAutoLandingVoltage >= BattComingHomeVoltage && EE_Parameter.ComingHomeVoltage) BattAutoLandingVoltage = BattComingHomeVoltage - 1; |
if(print) |
{ |
printf(" Low warning: %d.%dV",BattLowVoltageWarning/10,BattLowVoltageWarning%10); |
if(BattComingHomeVoltage) printf(" Auto-CH: %d.%dV",BattComingHomeVoltage/10,BattComingHomeVoltage%10); |
if(BattAutoLandingVoltage) printf(" Autolanding: %d.%dV",BattAutoLandingVoltage/10,BattAutoLandingVoltage%10); |
} |
} |
#if (defined(__AVR_ATmega1284__) || defined(__AVR_ATmega1284P__)) |
void LoadStoreSingleWP(void) |
{ |
// +++++++++++++++++++++++++++++++++++++++++++ |
// + Load/Store one single point |
// +++++++++++++++++++++++++++++++++++++++++++ |
static unsigned char switch_hyterese = 0, hyterese = 1, wp_tmp_s = 0, wp_tmp_l = 0; |
static int delay; |
if(PPM_in[EE_Parameter.SingleWpControlChannel] > 50) // Switch Up -> load |
{ |
if(switch_hyterese == 1 || switch_hyterese == 3) |
{ |
ToNC_Load_SingePoint = 1; |
switch_hyterese = 2; |
SpeakHoTT = SPEAK_NEXT_WP; |
Show_Load_Time = 5; |
Show_Load_Value = 1; |
wp_tmp_l = 1; |
} |
// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
// Bedienung per Taster am Sender |
if(PPM_in[EE_Parameter.MenuKeyChannel] > 50) // |
{ |
hyterese = 2; |
if(CheckDelay(delay)) { wp_tmp_l = 0; hyterese = 1;} |
} |
else |
if(PPM_in[EE_Parameter.MenuKeyChannel] < -50) |
{ |
delay = SetDelay(2500); |
if(hyterese == 2 && (wp_tmp_l < NaviData_MaxWpListIndex)) |
{ |
wp_tmp_l++; |
ToNC_Load_SingePoint = wp_tmp_l; |
Show_Load_Time = 5; |
Show_Load_Value = wp_tmp_l; |
SpeakHoTT = SPEAK_NEXT_WP; |
} |
hyterese = 0; |
} |
// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
} |
else |
if(PPM_in[EE_Parameter.SingleWpControlChannel] < -50) // Switch Down -> store |
{ |
if(switch_hyterese == 1 || switch_hyterese == 2) |
{ |
ToNC_Store_SingePoint = 1; |
switch_hyterese = 3; |
SpeakHoTT = SPEAK_MIKROKOPTER; |
Show_Store_Time = 5; |
Show_Store_Value = 1; |
wp_tmp_s = 1; |
} |
// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
// Bedienung per Taster am Sender |
if(PPM_in[EE_Parameter.MenuKeyChannel] > 50) // |
{ |
hyterese = 2; |
if(CheckDelay(delay)) { wp_tmp_s = 0; hyterese = 1;} |
} |
else |
if(PPM_in[EE_Parameter.MenuKeyChannel] < -50) |
{ |
delay = SetDelay(2500); |
if(hyterese == 2 && (wp_tmp_s < NaviData_MaxWpListIndex)) |
{ |
wp_tmp_s++; |
ToNC_Store_SingePoint = wp_tmp_s; |
Show_Store_Time = 5; |
Show_Store_Value = wp_tmp_s; |
SpeakHoTT = SPEAK_MIKROKOPTER; |
} |
hyterese = 0; |
} |
} |
else // Middle |
{ |
switch_hyterese = 1; |
} |
} |
// +++++++++++++++++++++++++++++++++++++++++++ |
#endif |
//############################################################################ |
//Hauptprogramm |
int main (void) |
//############################################################################ |
{ |
unsigned int timer,i,timer2 = 0, timerPolling; |
unsigned char update_spi = 1; |
DDRB = 0x00; |
PORTB = 0x00; |
DDRD = 0x0A; // UART & J3 J4 J5 |
PORTD = 0x5F; // PPM-Input & UART |
for(timer = 0; timer < 1000; timer++); // verzögern |
#if (defined(__AVR_ATmega1284__) || defined(__AVR_ATmega1284P__)) |
unsigned char AccZ_ErrorCnt = 0; |
if(PINB & 0x02) |
{ |
if(PIND & 0x10) PlatinenVersion = 21; // No Bridge from J4 to GND |
else { PlatinenVersion = 22; ACC_AltitudeControl = 1;}; |
} |
else |
{ |
PlatinenVersion = 25; |
ACC_AltitudeControl = 1; |
J4Low; |
} |
#else |
if(PINB & 0x01) |
{ |
if(PINB & 0x02) PlatinenVersion = 13; |
else PlatinenVersion = 11; |
} |
else |
{ |
if(PINB & 0x02) PlatinenVersion = 20; |
else |
{ |
PlatinenVersion = 10; |
DDRD = 0x3E; // Speaker & TXD & J3 J4 J5 |
PORTD = 0x47; // |
} |
} |
#endif |
DDRC = 0x81; // I2C, Spaker |
DDRC |=0x40; // HEF4017 Reset |
PORTC = 0xff; // Pullup SDA |
DDRB = 0x1B; // LEDs und Druckoffset |
PORTB = 0x01; // LED_Rot |
HEF4017Reset_ON; |
MCUSR &=~(1<<WDRF); |
WDTCSR |= (1<<WDCE)|(1<<WDE); |
WDTCSR = 0; |
beeptime = 2500; |
StickGier = 0; StickRoll = 0; StickNick = 0; |
if(PlatinenVersion >= 20) GIER_GRAD_FAKTOR = 1220; else GIER_GRAD_FAKTOR = 1291; // unterschiedlich für ME und ENC |
ROT_OFF; |
GRN_ON; |
Timer_Init(); |
TIMER2_Init(); |
UART_Init(); |
rc_sum_init(); |
ADC_Init(); |
I2C_Init(1); |
SPI_MasterInit(); |
Capacity_Init(); |
LIBFC_Init(LIB_FC_COMPATIBLE); |
GRN_ON; |
sei(); |
ParamSet_Init(); |
// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
if(PlatinenVersion < 20) |
{ |
wdt_enable(WDTO_250MS); // Reset-Commando |
while(1) printf("\n\rOld FC Hardware not supported by this Firmware!"); |
} |
#ifndef REDUNDANT_FC_SLAVE |
// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
// + Check connected BL-Ctrls |
// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
// Check connected BL-Ctrls |
BLFlags |= BLFLAG_READ_VERSION; |
motor_read = 0; // read the first I2C-Data |
for(i=0; i < 500; i++) |
{ |
SendMotorData(); |
timer = SetDelay(5); |
while(!(BLFlags & BLFLAG_TX_COMPLETE) && !CheckDelay(timer)); //wait for complete transfer |
} |
printf("\n\rFound BL-Ctrl: "); |
// timer = SetDelay(1000); |
for(i=0; i < MAX_MOTORS; i++) |
{ |
// SendMotorData(); |
// while(!(BLFlags & BLFLAG_TX_COMPLETE) && !CheckDelay(timer)); //wait for complete transfer |
if(Mixer.Motor[i][0] > 0) // wait max 4 sec for the BL-Ctrls to wake up |
{ |
while(!CheckDelay(timer) && !(Motor[i].State & MOTOR_STATE_PRESENT_MASK) ) |
{ |
if((BLFlags & BLFLAG_TX_COMPLETE)) SendMotorData(); |
//while(!(BLFlags & BLFLAG_TX_COMPLETE) && !CheckDelay(timer)); //wait for complete transfer |
} |
} |
if(Motor[i].State & MOTOR_STATE_PRESENT_MASK) |
{ |
unsigned char vers; |
printf("%d",(i+1)%10); |
FoundMotors++; |
vers = Motor[i].VersionMajor * 100 + Motor[i].VersionMinor; // creates 104 from 1.04 |
if(vers && VersionInfo.BL_Firmware > vers) VersionInfo.BL_Firmware = vers; |
//if(Motor[i].Version & MOTOR_STATE_FAST_MODE) printf("(fast)"); |
//if(Motor[i].Version & MOTOR_STATE_NEW_PROTOCOL_MASK) printf("(new)"); |
//printf(":V%03d\n\r",vers); |
} |
} |
for(i=0; i < MAX_MOTORS; i++) |
{ |
if(!(Motor[i].State & MOTOR_STATE_PRESENT_MASK) && Mixer.Motor[i][0] > 0) |
{ |
printf("\n\r\n\r!! MISSING BL-CTRL: %d !!",i+1); |
ServoActive = 2; // just in case the FC would be used as camera-stabilizer |
} |
Motor[i].State &= ~MOTOR_STATE_ERROR_MASK; // clear error counter |
} |
#if (defined(__AVR_ATmega1284__) || defined(__AVR_ATmega1284P__)) |
if(VersionInfo.BL_Firmware != 255) |
{ |
printf("\n\rBL-Firmware %d.%02d",VersionInfo.BL_Firmware/100,VersionInfo.BL_Firmware%100); |
if(VersionInfo.BL_Firmware >= 100 && VersionInfo.BL_Firmware <= 102) printf("<-- warning old Version!"); |
} |
#endif |
PrintLine();// ("\n\r==================================="); |
if(RequiredMotors < FoundMotors) VersionInfo.HardwareError[1] |= FC_ERROR1_MIXER; |
if(RequiredMotors > 8) Max_I2C_Packets = 8; else Max_I2C_Packets = RequiredMotors; |
#else |
printf("\n\r\n\r--> REDUNDANT SLAVE <---\n\r"); |
#endif |
#ifdef REDUNDANT_FC_MASTER |
printf("\n\r\n\r--> REDUNDANT MASTER <---\n\r"); |
#endif |
// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
// Calibrating altitude sensor |
// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
//if(EE_Parameter.GlobalConfig & CFG_HOEHENREGELUNG) |
{ |
printf("\n\rCalibrating pressure sensor.."); |
timer = SetDelay(1000); |
SucheLuftruckOffset(); |
while (!CheckDelay(timer)); |
printf("OK\n\r"); |
} |
#ifdef REDUNDANT_FC_SLAVE |
VersionInfo.HardwareError[0] = 0; |
VersionInfo.HardwareError[1] = 0; |
#endif |
SetNeutral(0); |
ROT_OFF; |
beeptime = 2000; |
FlugMinuten = (unsigned int)GetParamByte(PID_FLIGHT_MINUTES) * 256 + (unsigned int)GetParamByte(PID_FLIGHT_MINUTES + 1); |
FlugMinutenGesamt = (unsigned int)GetParamByte(PID_FLIGHT_MINUTES_TOTAL) * 256 + (unsigned int)GetParamByte(PID_FLIGHT_MINUTES_TOTAL + 1); |
if((FlugMinutenGesamt == 0xFFFF) || (FlugMinuten == 0xFFFF)) |
{ |
FlugMinuten = 0; |
FlugMinutenGesamt = 0; |
} |
printf("\n\rFlight-time %u min Total:%u min", FlugMinuten, FlugMinutenGesamt); |
LcdClear(); |
I2CTimeout = 5000; |
WinkelOut.Orientation = 1; |
LipoDetection(1); |
LIBFC_ReceiverInit(EE_Parameter.Receiver); |
PrintLine();// ("\n\r==================================="); |
//SpektrumBinding(); |
timer = SetDelay(2000); |
timerPolling = SetDelay(250); |
Debug(ANSI_CLEAR "FC-Start!\n\rFlugzeit: %d min", FlugMinutenGesamt); // Note: this won't waste flash memory, if #DEBUG is not active |
//printf("\n\rEE_Parameter size:%i\n\r", PARAMSET_STRUCT_LEN); |
DebugOut.Status[0] = 0x01 | 0x02; |
JetiBeep = 0; |
if(EE_Parameter.ExtraConfig & CFG_NO_RCOFF_BEEPING) DisableRcOffBeeping = 1; |
ReadBlSize = 3; // don't read the version any more |
#ifdef REDUNDANT_FC_SLAVE |
timer = SetDelay(2500); |
while(!CheckDelay(timer)); |
printf("\n\rStart\n\r"); |
#endif |
while(1) |
{ |
EEAR = EE_DUMMY; // Set the EEPROM Address pointer to an unused space |
if(ReceiverUpdateModeActive) while (1) PORTC &= ~(1<<7); // Beeper off |
if(UpdateMotor && AdReady) // ReglerIntervall |
{ |
cli(); |
UpdateMotor--; |
sei(); |
if(WinkelOut.CalcState) CalMk3Mag(); |
else MotorRegler(); |
SendMotorData(); |
ROT_OFF; |
if(SenderOkay) { SenderOkay--; /*VersionInfo.HardwareError[1] &= ~FC_ERROR1_PPM;*/ } |
else |
{ |
TIMSK1 |= _BV(ICIE1); // enable PPM-Input |
PPM_in[0] = 0; // set RSSI to zero on data timeout |
VersionInfo.HardwareError[1] |= FC_ERROR1_PPM; |
// Now clear the channel values - they would be wrong |
PPM_diff[EE_Parameter.Kanalbelegung[K_NICK]] = 0; |
PPM_diff[EE_Parameter.Kanalbelegung[K_ROLL]] = 0; |
PPM_in[EE_Parameter.Kanalbelegung[K_NICK]] = 0; |
PPM_in[EE_Parameter.Kanalbelegung[K_ROLL]] = 0; |
PPM_in[EE_Parameter.Kanalbelegung[K_GIER]] = 0; |
PPM_in[EE_Parameter.Kanalbelegung[K_GAS]] = 0; |
ChannelNick = 0; |
ChannelRoll = 0; |
ChannelYaw = 0; |
ChannelGas = 0; |
} |
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
//if(HoehenReglerAktiv && NaviDataOkay && SenderOkay < 160 && SenderOkay > 10 && FromNaviCtrl_Value.SerialDataOkay > 220) SenderOkay = 160; |
//if(HoehenReglerAktiv && NaviDataOkay && SenderOkay < 101 && SenderOkay > 10 && FromNaviCtrl_Value.SerialDataOkay > 1) SenderOkay = 101; |
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
if(!--I2CTimeout || MissingMotor) |
{ |
if(!I2CTimeout) |
{ |
I2C_Reset(); |
I2CTimeout = 5; |
DebugOut.Analog[28]++; // I2C-Error |
VersionInfo.HardwareError[1] |= FC_ERROR1_I2C; |
DebugOut.Status[1] |= 0x02; // BL-Error-Status |
} |
if((BeepMuster == 0xffff) && MotorenEin) |
{ |
beeptime = 25000; |
BeepMuster = 0x0080; |
} |
} |
else |
{ |
ROT_OFF; |
} |
LIBFC_Polling(); |
if(!UpdateMotor) |
{ |
#if (defined(__AVR_ATmega1284__) || defined(__AVR_ATmega1284P__)) |
if(NewSBusData) ProcessSBus(); |
else |
if(NewMlinkData) ProcessMlinkData(); |
else |
#endif |
{ |
if(BytegapSPI == 0) SPI_TransmitByte(); |
if(CalculateServoSignals) CalculateServo(); |
DatenUebertragung(); |
BearbeiteRxDaten(); |
if(CheckDelay(timer)) |
{ |
static unsigned char second; |
timer += 20; // 20 ms interval |
CalcNickServoValue(); |
// ++++++++++++++++++++++++++++ |
// + New direction setpoint from NC |
if(NC_CompassSetpoint != -1) |
{ |
int diff; |
if(!NeueKompassRichtungMerken && (KompassSollWert != NC_CompassSetpoint) && (CareFree || NCForcesNewDirection)) |
{ |
diff = ((540 + (KompassSollWert - NC_CompassSetpoint)) % 360) - 180; |
if(diff > 2) diff = 2; // max. 2° in 20ms = 100°/sec |
else |
if(diff < -2) diff = -2; |
KompassSollWert -= diff; |
} |
else |
{ |
NC_CompassSetpoint = -1; |
NCForcesNewDirection = 0; // allows Yawing without CareFree (Yawing at Coming Home) |
} |
} |
// ++++++++++++++++++++++++++++ |
#if (defined(__AVR_ATmega1284__) || defined(__AVR_ATmega1284P__)) |
if(EE_Parameter.Receiver == RECEIVER_HOTT) HoTT_Menu(); |
else |
if(EE_Parameter.Receiver == RECEIVER_JETI) BuildJeti_Vario(); |
// ++++++++++++++++++++++++++++ |
// + check the ACC-Z range |
if(ACC_AltitudeControl && ((Aktuell_az < 300) || (DebugOut.Analog[7] < (128 * 4) && Aktuell_az > 850))) // DebugOut.Analog[7] = GasMischanteil |
{ |
if(++AccZ_ErrorCnt > 50) |
{ |
if(MotorenEin) VersionInfo.HardwareError[0] |= FC_ERROR0_ACC_TOP; |
else CalibrationDone = 0; |
} |
} |
else AccZ_ErrorCnt = 0; |
// ++++++++++++++++++++++++++++ |
#endif |
if(MissingMotor || Capacity.MinOfMaxPWM < 30) |
{ |
if(MissingMotor) VersionInfo.HardwareError[1] |= FC_ERROR1_BL_MISSING; |
DebugOut.Status[1] |= 0x02; // BL-Error-Status |
} |
else |
{ |
if(!beeptime) |
{ |
if(I2CTimeout > 6) DebugOut.Status[1] &= ~0x02; // BL-Error-Status |
} |
} |
if(DisableRcOffBeeping) if(SenderOkay > 150) { DisableRcOffBeeping = 0; beeptime = 5000;}; |
if(PcZugriff) PcZugriff--; |
else |
{ |
if(!SenderOkay) |
{ |
if(BeepMuster == 0xffff && DisableRcOffBeeping != 2) |
{ |
beeptime = 15000; |
BeepMuster = 0x0c00; |
if(DisableRcOffBeeping) DisableRcOffBeeping = 2; |
} |
} |
} |
if(NaviDataOkay > 200) |
{ |
NaviDataOkay--; |
VersionInfo.HardwareError[1] &= ~FC_ERROR1_SPI_RX; |
VersionInfo.Flags |= FC_VERSION_FLAG_NC_PRESENT; |
} |
else |
{ |
if(NC_Version.Compatible) |
{ |
VersionInfo.HardwareError[1] |= FC_ERROR1_SPI_RX; |
NC_ErrorCode = 9; // "ERR: no NC communication" |
if(BeepMuster == 0xffff && MotorenEin) |
{ |
beeptime = 15000; |
BeepMuster = 0xA800; |
} |
} |
GPS_Nick = 0; |
GPS_Roll = 0; |
GPS_Aid_StickMultiplikator = 0; |
GPSInfo.Flags = 0; |
FromNaviCtrl_Value.Kalman_K = -1; |
FromNaviCtrl.AccErrorN = 0; |
FromNaviCtrl.AccErrorR = 0; |
FromNaviCtrl.CompassValue = -1; |
FromNC_AltitudeSpeed = 0; |
FromNC_AltitudeSetpoint = 0; |
VersionInfo.Flags &= ~FC_VERSION_FLAG_NC_PRESENT; |
NC_To_FC_Flags = 0; |
NaviDataOkay = 0; |
} |
if(UBat <= BattLowVoltageWarning) |
{ |
FC_StatusFlags |= FC_STATUS_LOWBAT; |
if(BeepMuster == 0xffff && UBat > 10) // Do not beep, if the voltage reading is below 1V (Supplied via MKUSB) |
{ |
beeptime = 6000; |
BeepMuster = 0x0300; |
} |
} |
// +++++++++++++++++++++++++++++++++ |
if(ExternalControlTimeout) |
{ |
ExternalControlTimeout--; |
if(ExternalControlTimeout == 1) |
{ |
ExternalControl.Config = 0; |
beeptime = 2000; |
} |
} |
#if (defined(__AVR_ATmega1284__) || defined(__AVR_ATmega1284P__)) |
// +++++++++++++++++++++++++++++++++++++++++++ |
// + Load/Store one single point |
// +++++++++++++++++++++++++++++++++++++++++++ |
if(EE_Parameter.SingleWpControlChannel) LoadStoreSingleWP(); |
// +++++++++++++++++++++++++++++++++++++++++++ |
#endif |
#ifdef NO_RECEIVER |
PPM_in[EE_Parameter.Kanalbelegung[K_NICK]] = 0; PPM_in[EE_Parameter.Kanalbelegung[K_ROLL]] = 0; PPM_in[EE_Parameter.Kanalbelegung[K_GIER]] = 0; PPM_in[EE_Parameter.Kanalbelegung[K_GAS]] = 0; |
PPM_in[EE_Parameter.HoeheChannel] = (unsigned char) 200; |
PPM_in[EE_Parameter.NaviGpsModeChannel] = (unsigned char) 200; |
PPM_in[EE_Parameter.CareFreeChannel] = (unsigned char) 200; |
SenderOkay = 180; |
MotorenEin = 0; |
#endif |
// +++++++++++++++++++++++++++++++++ |
// Sekundentakt |
if(++second == 49) |
{ |
second = 0; |
#if (defined(__AVR_ATmega1284__) || defined(__AVR_ATmega1284P__)) |
if(ShowSettingNameTime) ShowSettingNameTime--; |
if(Show_Load_Time) Show_Load_Time--; |
if(Show_Store_Time) Show_Store_Time--; |
#endif |
if(NC_To_FC_Flags & NC_TO_FC_FAILSAFE_LANDING) ServoFailsafeActive = SERVO_FS_TIME; |
else |
if(ServoFailsafeActive) ServoFailsafeActive--; |
if(FC_StatusFlags & FC_STATUS_FLY) FlugSekunden++; |
else timer2 = 1450; // 0,5 Minuten aufrunden |
if(modell_fliegt < 1024) |
{ |
if(StartLuftdruck < Luftdruck) StartLuftdruck += 5; |
else |
if(StartLuftdruck > Luftdruck) StartLuftdruck -= 5; |
FC_StatusFlags3 &= ~FC_STATUS3_REDUNDANCE_ERROR; |
} |
else |
{ |
#ifdef REDUNDANT_FC_MASTER |
if(!(FC_StatusFlags3 & FC_STATUS3_REDUNDANCE_AKTIVE)) FC_StatusFlags3 |= FC_STATUS3_REDUNDANCE_ERROR; |
else FC_StatusFlags3 &= ~FC_STATUS3_REDUNDANCE_ERROR; |
#endif |
} |
if(UBat > BattLowVoltageWarning + 1) FC_StatusFlags &= ~FC_STATUS_LOWBAT; |
} |
// +++++++++++++++++++++++++++++++++ |
if(++timer2 == 2930) // eine Minute |
{ |
timer2 = 0; |
FlugMinuten++; |
FlugMinutenGesamt++; |
SetParamByte(PID_FLIGHT_MINUTES,FlugMinuten / 256); |
SetParamByte(PID_FLIGHT_MINUTES+1,FlugMinuten % 256); |
SetParamByte(PID_FLIGHT_MINUTES_TOTAL,FlugMinutenGesamt / 256); |
SetParamByte(PID_FLIGHT_MINUTES_TOTAL+1,FlugMinutenGesamt % 256); |
timer = SetDelay(20); // falls "timer += 20;" mal nicht geht |
} |
} |
LED_Update(); |
Capacity_Update(); |
} |
} //else DebugOut.Analog[18]++; |
if(update_spi) update_spi--; |
} // 500Hz |
if(update_spi == 0) // 41Hz |
{ |
if(SPI_StartTransmitPacket()) update_spi = 12; |
else |
if(BytegapSPI == 0) SPI_TransmitByte(); |
} |
else if(BytegapSPI == 0) SPI_TransmitByte(); |
} |
} |
//DebugOut.Analog[] |
/tags/V2.12a/main.h |
---|
0,0 → 1,97 |
#ifndef _MAIN_H |
#define _MAIN_H |
//#define REDUNDANT_FC_SLAVE |
//#define REDUNDANT_FC_MASTER |
//#define NO_RECEIVER |
//#define DEBUG // use to activate debug output to MK-Tool: use Debug(text); |
//#define ACT_S3D_SUMMENSIGNAL |
//#define UserParameter8_FAILSAFE |
//#define RECEIVER_SPEKTRUM_DX7EXP |
//#define RECEIVER_SPEKTRUM_DX8EXP |
// neue Hardware |
//#define ROT_OFF {if((PlatinenVersion == 10)||(PlatinenVersion >= 20)) PORTB &=~0x01; else PORTB |= 0x01;} |
//#define ROT_ON {if((PlatinenVersion == 10)||(PlatinenVersion >= 20)) PORTB |= 0x01; else PORTB &=~0x01;} |
#define ROT_OFF {PORTB &=~0x01;} |
#define ROT_ON {PORTB |= 0x01;} |
#define ROT_FLASH PORTB ^= 0x01 |
//#define GRN_OFF {if((PlatinenVersion < 12) || PlatinenVersion == 25) PORTB &=~0x02; else PORTB |= 0x02;} |
//#define GRN_ON {if((PlatinenVersion < 12) || PlatinenVersion == 25) PORTB |= 0x02; else PORTB &=~0x02;} |
#define GRN_OFF {if(PlatinenVersion == 25) PORTB &=~0x02; else PORTB |= 0x02;} |
#define GRN_ON {if(PlatinenVersion == 25) PORTB |= 0x02; else PORTB &=~0x02;} |
#define GRN_FLASH PORTB ^= 0x02 |
#define SYSCLK F_CPU |
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
#define J3High PORTD |= 0x20 |
#define J3Low PORTD &= ~0x20 |
#define J4High PORTD |= 0x10 |
#define J4Low PORTD &= ~0x10 |
#define J5High PORTD |= 0x08 |
#define J5Low PORTD &= ~0x08 |
extern volatile unsigned char SenderOkay; |
extern unsigned char BattLowVoltageWarning; |
extern unsigned char BattAutoLandingVoltage, BattComingHomeVoltage; |
extern unsigned char CosinusNickWinkel, CosinusRollWinkel; |
extern unsigned char PlatinenVersion; |
extern unsigned char FoundMotors,DisableRcOffBeeping; |
extern unsigned char JetiBeep; |
void LipoDetection(unsigned char print); |
extern unsigned int FlugMinuten,FlugMinutenGesamt,FlugSekunden; |
extern void PrintLine(void); // "=================================" |
extern unsigned char ActiveParamSet; |
extern unsigned int BL3_Current(unsigned char who); // in 0,1A |
extern unsigned char LipoCells; |
#include <avr/pgmspace.h> |
#if (defined(__AVR_ATmega1284__) || defined(__AVR_ATmega1284P__)) |
#endif |
#include <stdlib.h> |
#include <string.h> |
#include <avr/io.h> |
#include <avr/pgmspace.h> |
#include <avr/interrupt.h> |
#include <avr/eeprom.h> |
#include <avr/boot.h> |
#include <avr/wdt.h> |
#include "old_macros.h" |
#include "printf_P.h" |
#include "timer0.h" |
#include "uart.h" |
#include "analog.h" |
#include "twimaster.h" |
#include "menu.h" |
#include "rc.h" |
#include "fc.h" |
#include "gps.h" |
#include "spi.h" |
#include "led.h" |
#include "spektrum.h" |
#include "capacity.h" |
#include "eeprom.h" |
#include "libfc.h" |
#include "hottmenu.h" |
#include "debug.h" |
#include "sbus.h" |
#include "jeti_ex.h" |
#include "M-Link.h" |
#endif //_MAIN_H |
/tags/V2.12a/makefile |
---|
0,0 → 1,496 |
#-------------------------------------------------------------------- |
# MCU name |
MCU = atmega1284p |
#MCU = atmega644p |
F_CPU = 20000000 |
#------------------------------------------------------------------- |
VERSION_MAJOR = 2 |
VERSION_MINOR = 12 |
VERSION_PATCH = 0 |
VERSION_SERIAL_MAJOR = 11 # Serial Protocol to KopterTool -> do not change! |
VERSION_SERIAL_MINOR = 0 # Serial Protocol |
NC_SPI_COMPATIBLE = 76 # Navi-Kompatibilität |
LIB_FC_COMPATIBLE = 7 # Library |
#------------------------------------------------------------------- |
# ATMEGA644: 63487 is maximum |
#------------------------------------------------------------------- |
# 0 a |
# 1 b |
# 2 c |
# 3 d |
# 4 e |
# 5 f |
# 6 g |
# 7 h |
# 8 i |
# 9 j |
# 10 k |
# 11 L |
#------------------------------------------------------------------- |
# get SVN revision |
REV := $(shell sh -c "cat .svn/entries | sed -n '4p'") |
ifeq ($(MCU), atmega1284p) |
FUSE_SETTINGS = -u -U lfuse:w:0xff:m -U hfuse:w:0xdf:m |
HEX_NAME = MEGA1284P |
LIBFC_EXT = 1284 |
endif |
ifeq ($(MCU), atmega644p) |
FUSE_SETTINGS = -u -U lfuse:w:0xff:m -U hfuse:w:0xdf:m |
HEX_NAME = MEGA644 |
LIBFC_EXT = 644 |
endif |
ifeq ($(F_CPU), 16000000) |
QUARZ = 16MHZ |
endif |
ifeq ($(F_CPU), 20000000) |
QUARZ = 20MHZ |
endif |
# Output format. (can be srec, ihex, binary) |
FORMAT = ihex |
# Target file name (without extension). |
ifeq ($(VERSION_PATCH), 0) |
TARGET = Flight-Ctrl_$(HEX_NAME)_V$(VERSION_MAJOR)_$(VERSION_MINOR)a_SVN$(REV) |
endif |
ifeq ($(VERSION_PATCH), 1) |
TARGET = Flight-Ctrl_$(HEX_NAME)_V$(VERSION_MAJOR)_$(VERSION_MINOR)b_SVN$(REV) |
endif |
ifeq ($(VERSION_PATCH), 2) |
TARGET = Flight-Ctrl_$(HEX_NAME)_V$(VERSION_MAJOR)_$(VERSION_MINOR)c_SVN$(REV) |
endif |
ifeq ($(VERSION_PATCH), 3) |
TARGET = Flight-Ctrl_$(HEX_NAME)_V$(VERSION_MAJOR)_$(VERSION_MINOR)d_SVN$(REV) |
endif |
ifeq ($(VERSION_PATCH), 4) |
TARGET = Flight-Ctrl_$(HEX_NAME)_V$(VERSION_MAJOR)_$(VERSION_MINOR)e_SVN$(REV) |
endif |
ifeq ($(VERSION_PATCH), 5) |
TARGET = Flight-Ctrl_$(HEX_NAME)_V$(VERSION_MAJOR)_$(VERSION_MINOR)f_SVN$(REV) |
endif |
ifeq ($(VERSION_PATCH), 6) |
TARGET = Flight-Ctrl_$(HEX_NAME)_V$(VERSION_MAJOR)_$(VERSION_MINOR)g_SVN$(REV) |
endif |
ifeq ($(VERSION_PATCH), 7) |
TARGET = Flight-Ctrl_$(HEX_NAME)_V$(VERSION_MAJOR)_$(VERSION_MINOR)h_SVN$(REV) |
endif |
ifeq ($(VERSION_PATCH), 8) |
TARGET = Flight-Ctrl_$(HEX_NAME)_V$(VERSION_MAJOR)_$(VERSION_MINOR)i_SVN$(REV) |
endif |
ifeq ($(VERSION_PATCH), 9) |
TARGET = Flight-Ctrl_$(HEX_NAME)_V$(VERSION_MAJOR)_$(VERSION_MINOR)j_SVN$(REV) |
endif |
ifeq ($(VERSION_PATCH), 10) |
TARGET = Flight-Ctrl_$(HEX_NAME)_V$(VERSION_MAJOR)_$(VERSION_MINOR)k_SVN$(REV) |
endif |
ifeq ($(VERSION_PATCH), 11) |
TARGET = Flight-Ctrl_$(HEX_NAME)_V$(VERSION_MAJOR)_$(VERSION_MINOR)L_SVN$(REV) |
endif |
ifeq ($(VERSION_PATCH), 12) |
TARGET = Flight-Ctrl_$(HEX_NAME)_V$(VERSION_MAJOR)_$(VERSION_MINOR)m_SVN$(REV) |
endif |
ifeq ($(VERSION_PATCH), 13) |
TARGET = Flight-Ctrl_$(HEX_NAME)_V$(VERSION_MAJOR)_$(VERSION_MINOR)n_SVN$(REV) |
endif |
ifeq ($(VERSION_PATCH), 14) |
TARGET = Flight-Ctrl_$(HEX_NAME)_V$(VERSION_MAJOR)_$(VERSION_MINOR)o_SVN$(REV) |
endif |
ifeq ($(VERSION_PATCH), 15) |
TARGET = Flight-Ctrl_$(HEX_NAME)_V$(VERSION_MAJOR)_$(VERSION_MINOR)p_SVN$(REV) |
endif |
ifeq ($(VERSION_PATCH), 16) |
TARGET = Flight-Ctrl_$(HEX_NAME)_V$(VERSION_MAJOR)_$(VERSION_MINOR)q_SVN$(REV) |
endif |
ifeq ($(VERSION_PATCH), 17) |
TARGET = Flight-Ctrl_$(HEX_NAME)_V$(VERSION_MAJOR)_$(VERSION_MINOR)r_SVN$(REV) |
endif |
ifeq ($(VERSION_PATCH), 18) |
TARGET = Flight-Ctrl_$(HEX_NAME)_V$(VERSION_MAJOR)_$(VERSION_MINOR)s_SVN$(REV) |
endif |
ifeq ($(VERSION_PATCH), 19) |
TARGET = Flight-Ctrl_$(HEX_NAME)_V$(VERSION_MAJOR)_$(VERSION_MINOR)t_SVN$(REV) |
endif |
ifeq ($(VERSION_PATCH), 20) |
TARGET = Flight-Ctrl_$(HEX_NAME)_V$(VERSION_MAJOR)_$(VERSION_MINOR)u_SVN$(REV) |
endif |
ifeq ($(VERSION_PATCH), 21) |
TARGET = Flight-Ctrl_$(HEX_NAME)_V$(VERSION_MAJOR)_$(VERSION_MINOR)v_SVN$(REV) |
endif |
ifeq ($(VERSION_PATCH), 22) |
TARGET = Flight-Ctrl_$(HEX_NAME)_V$(VERSION_MAJOR)_$(VERSION_MINOR)w_SVN$(REV) |
endif |
ifeq ($(VERSION_PATCH), 23) |
TARGET = Flight-Ctrl_$(HEX_NAME)_V$(VERSION_MAJOR)_$(VERSION_MINOR)x_SVN$(REV) |
endif |
ifeq ($(VERSION_PATCH), 24) |
TARGET = Flight-Ctrl_$(HEX_NAME)_V$(VERSION_MAJOR)_$(VERSION_MINOR)y_SVN$(REV) |
endif |
ifeq ($(VERSION_PATCH), 25) |
TARGET = Flight-Ctrl_$(HEX_NAME)_V$(VERSION_MAJOR)_$(VERSION_MINOR)z_SVN$(REV) |
endif |
# Optimization level, can be [0, 1, 2, 3, s]. 0 turns off optimization. |
# (Note: 3 is not always the best optimization level. See avr-libc FAQ.) |
OPT = s |
#OPT = 2 |
########################################################################################################## |
# List C source files here. (C dependencies are automatically generated.) |
SRC = main.c uart.c timer0.c analog.c menu.c eeprom.c |
SRC += twimaster.c rc.c fc.c GPS.c spi.c led.c Spektrum.c |
SRC += mymath.c jetimenu.c capacity.c debug.c |
SRC += hottmenu.c sbus.c user_receiver.c M-Link.c |
SRC += jeti_ex.c |
########################################################################################################## |
# List Assembler source files here. |
# Make them always end in a capital .S. Files ending in a lowercase .s |
# will not be considered source files but generated files (assembler |
# output from the compiler), and will be deleted upon "make clean"! |
# Even though the DOS/Win* filesystem matches both .s and .S the same, |
# it will preserve the spelling of the filenames, and gcc itself does |
# care about how the name is spelled on its command-line. |
ASRC = isqrt.S |
# List any extra directories to look for include files here. |
# Each directory must be seperated by a space. |
EXTRAINCDIRS = |
# Optional compiler flags. |
# -g: generate debugging information (for GDB, or for COFF conversion) |
# -O*: optimization level |
# -f...: tuning, see gcc manual and avr-libc documentation |
# -Wall...: warning level |
# -Wa,...: tell GCC to pass this to the assembler. |
# -ahlms: create assembler listing |
CFLAGS = -O$(OPT) -funsigned-char -funsigned-bitfields -fpack-struct -fshort-enums -Wall -Wstrict-prototypes -Wa,-adhlns=$(<:%.c=%.lst) $(patsubst %,-I%,$(EXTRAINCDIRS)) |
# Set a "language standard" compiler flag. |
# Unremark just one line below to set the language standard to use. |
# gnu99 = C99 + GNU extensions. See GCC manual for more information. |
#CFLAGS += -std=c89 |
#CFLAGS += -std=gnu89 |
#CFLAGS += -std=c99 |
CFLAGS += -std=gnu99 |
# shrink code size |
CFLAGS += -mtiny-stack |
#CFLAGS += -fno-inline-functions |
CFLAGS += -mcall-prologues |
CFLAGS += -DF_CPU=$(F_CPU) -DVERSION_MAJOR=$(VERSION_MAJOR) -DVERSION_MINOR=$(VERSION_MINOR) -DVERSION_PATCH=$(VERSION_PATCH) -DVERSION_SERIAL_MAJOR=$(VERSION_SERIAL_MAJOR) -DVERSION_SERIAL_MINOR=$(VERSION_SERIAL_MINOR) -DNC_SPI_COMPATIBLE=$(NC_SPI_COMPATIBLE) -DLIB_FC_COMPATIBLE=$(LIB_FC_COMPATIBLE) |
# Optional assembler flags. |
# -Wa,...: tell GCC to pass this to the assembler. |
# -ahlms: create listing |
# -gstabs: have the assembler create line number information; note that |
# for use in COFF files, additional information about filenames |
# and function names needs to be present in the assembler source |
# files -- see avr-libc docs [FIXME: not yet described there] |
ASFLAGS = -Wa,-adhlns=$(<:.S=.lst),-gstabs |
# Optional linker flags. |
# -Wl,...: tell GCC to pass this to linker. |
# -Map: create map file |
# --cref: add cross reference to map file |
LDFLAGS = -Wl,-Map=$(TARGET).map,--cref |
# Additional libraries |
# Minimalistic printf version |
#LDFLAGS += -Wl,-u,vfprintf -lprintf_min |
# Floating point printf version (requires -lm below) |
#LDFLAGS += -Wl,-u,vfprintf -lprintf_flt |
# -lm = math library |
LDFLAGS += -lm |
LDFLAGS += libfc$(LIBFC_EXT).a |
##LDFLAGS += -T./linkerfile/avr5.x |
# Programming support using avrdude. Settings and variables. |
# Programming hardware: alf avr910 avrisp bascom bsd |
# dt006 pavr picoweb pony-stk200 sp12 stk200 stk500 |
# |
# Type: avrdude -c ? |
# to get a full listing. |
# |
#AVRDUDE_PROGRAMMER = dt006 |
#AVRDUDE_PROGRAMMER = stk200 |
#AVRDUDE_PROGRAMMER = ponyser |
AVRDUDE_PROGRAMMER = avrispv2 |
#falls Ponyser ausgewählt wird, muss sich unsere avrdude-Configdatei im Bin-Verzeichnis des Compilers befinden |
#AVRDUDE_PORT = com1 # programmer connected to serial device |
#AVRDUDE_PORT = lpt1 # programmer connected to parallel port |
AVRDUDE_PORT = usb # programmer connected to USB |
#AVRDUDE_WRITE_FLASH = -U flash:w:$(TARGET).hex |
AVRDUDE_WRITE_FLASH = -U flash:w:$(TARGET).hex $(FUSE_SETTINGS) |
#AVRDUDE_WRITE_EEPROM = -U eeprom:w:$(TARGET).eep |
#avrdude -c avrispv2 -P usb -p m32 -U flash:w:blink.hex |
AVRDUDE_FLAGS = -p $(MCU) -P $(AVRDUDE_PORT) -c $(AVRDUDE_PROGRAMMER) |
# Uncomment the following if you want avrdude's erase cycle counter. |
# Note that this counter needs to be initialized first using -Yn, |
# see avrdude manual. |
#AVRDUDE_ERASE += -y |
# Uncomment the following if you do /not/ wish a verification to be |
# performed after programming the device. |
AVRDUDE_FLAGS += -V |
# Increase verbosity level. Please use this when submitting bug |
# reports about avrdude. See <http://savannah.nongnu.org/projects/avrdude> |
# to submit bug reports. |
#AVRDUDE_FLAGS += -v -v |
# --------------------------------------------------------------------------- |
# Define directories, if needed. |
DIRAVR = c:/winavr |
DIRAVRBIN = $(DIRAVR)/bin |
DIRAVRUTILS = $(DIRAVR)/utils/bin |
DIRINC = . |
DIRLIB = $(DIRAVR)/avr/lib |
# Define programs and commands. |
SHELL = sh |
CC = avr-gcc |
OBJCOPY = avr-objcopy |
OBJDUMP = avr-objdump |
SIZE = avr-size |
# Programming support using avrdude. |
AVRDUDE = avrdude |
REMOVE = rm -f |
COPY = cp |
HEXSIZE = $(SIZE) --target=$(FORMAT) $(TARGET).hex |
ELFSIZE = $(SIZE) -x -A $(TARGET).elf |
LIMITS = $(SIZE) --mcu=$(MCU) -C $(TARGET).elf |
# Define Messages |
# English |
MSG_ERRORS_NONE = Errors: none |
MSG_BEGIN = -------- begin -------- |
MSG_END = -------- end -------- |
MSG_SIZE_BEFORE = Size before: |
MSG_SIZE_AFTER = Size after: |
MSG_COFF = Converting to AVR COFF: |
MSG_EXTENDED_COFF = Converting to AVR Extended COFF: |
MSG_FLASH = Creating load file for Flash: |
MSG_EEPROM = Creating load file for EEPROM: |
MSG_EXTENDED_LISTING = Creating Extended Listing: |
MSG_SYMBOL_TABLE = Creating Symbol Table: |
MSG_LINKING = Linking: |
MSG_COMPILING = Compiling: |
MSG_ASSEMBLING = Assembling: |
MSG_CLEANING = Cleaning project: |
# Define all object files. |
OBJ = $(SRC:.c=.o) $(ASRC:.S=.o) |
# Define all listing files. |
LST = $(ASRC:.S=.lst) $(SRC:.c=.lst) |
# Combine all necessary flags and optional flags. |
# Add target processor to flags. |
#ALL_CFLAGS = -mmcu=$(MCU) -DF_CPU=$(F_CPU) -I. $(CFLAGS) |
ALL_CFLAGS = -mmcu=$(MCU) -I. $(CFLAGS) |
ALL_ASFLAGS = -mmcu=$(MCU) -I. -x assembler-with-cpp $(ASFLAGS) |
# Default target. |
all: begin gccversion sizebefore $(TARGET).elf $(TARGET).hex sizeafter finished end |
# Eye candy. |
# AVR Studio 3.x does not check make's exit code but relies on |
# the following magic strings to be generated by the compile job. |
begin: |
@echo |
@echo $(MSG_BEGIN) |
finished: |
@echo $(MSG_ERRORS_NONE) |
end: |
@echo $(MSG_END) |
@echo |
# Display size of file. |
sizebefore: |
@if [ -f $(TARGET).elf ]; then echo Size before:; $(ELFSIZE); $(HEXSIZE); $(LIMITS); echo; fi |
sizeafter: |
@if [ -f $(TARGET).elf ]; then echo Size after:; $(ELFSIZE); $(HEXSIZE); $(LIMITS); echo; fi |
# Display compiler version information. |
gccversion : |
@$(CC) --version |
# Convert ELF to COFF for use in debugging / simulating in |
# AVR Studio or VMLAB. |
COFFCONVERT=$(OBJCOPY) --debugging \ |
--change-section-address .data-0x800000 \ |
--change-section-address .bss-0x800000 \ |
--change-section-address .noinit-0x800000 \ |
--change-section-address .eeprom-0x810000 |
coff: $(TARGET).elf |
@echo |
@echo $(MSG_COFF) $(TARGET).cof |
$(COFFCONVERT) -O coff-avr $< $(TARGET).cof |
extcoff: $(TARGET).elf |
@echo |
@echo $(MSG_EXTENDED_COFF) $(TARGET).cof |
$(COFFCONVERT) -O coff-ext-avr $< $(TARGET).cof |
# Program the device. |
program: $(TARGET).hex $(TARGET).eep |
$(AVRDUDE) $(AVRDUDE_FLAGS) $(AVRDUDE_WRITE_FLASH) $(AVRDUDE_WRITE_EEPROM) |
# Create final output files (.hex, .eep) from ELF output file. |
%.hex: %.elf |
@echo |
@echo $(MSG_FLASH) $@ |
$(OBJCOPY) -O $(FORMAT) -R .eeprom $< $@ |
%.eep: %.elf |
@echo |
@echo $(MSG_EEPROM) $@ |
-$(OBJCOPY) -j .eeprom --set-section-flags=.eeprom="alloc,load" \ |
--change-section-lma .eeprom=0 -O $(FORMAT) $< $@ |
# Create extended listing file from ELF output file. |
%.lss: %.elf |
@echo |
@echo $(MSG_EXTENDED_LISTING) $@ |
$(OBJDUMP) -h -S $< > $@ |
# Create a symbol table from ELF output file. |
%.sym: %.elf |
@echo |
@echo $(MSG_SYMBOL_TABLE) $@ |
avr-nm -n $< > $@ |
# Link: create ELF output file from object files. |
.SECONDARY : $(TARGET).elf |
.PRECIOUS : $(OBJ) |
%.elf: $(OBJ) |
@echo |
@echo $(MSG_LINKING) $@ |
$(CC) $(ALL_CFLAGS) $(OBJ) --output $@ $(LDFLAGS) |
# Compile: create object files from C source files. |
%.o : %.c |
@echo |
@echo $(MSG_COMPILING) $< |
$(CC) -c $(ALL_CFLAGS) $< -o $@ |
# Compile: create assembler files from C source files. |
%.s : %.c |
$(CC) -S $(ALL_CFLAGS) $< -o $@ |
# Assemble: create object files from assembler source files. |
%.o : %.S |
@echo |
@echo $(MSG_ASSEMBLING) $< |
$(CC) -c $(ALL_ASFLAGS) $< -o $@ |
# Target: clean project. |
clean: begin clean_list finished end |
clean_list : |
@echo |
@echo $(MSG_CLEANING) |
$(REMOVE) Flight-Ctrl_*.hex |
$(REMOVE) Flight-Ctrl_*.eep |
$(REMOVE) $(TARGET).obj |
$(REMOVE) $(TARGET).cof |
$(REMOVE) Flight-Ctrl_*.elf |
$(REMOVE) Flight-Ctrl_*.map |
$(REMOVE) $(TARGET).obj |
$(REMOVE) $(TARGET).a90 |
$(REMOVE) Flight-Ctrl_*.sym |
$(REMOVE) $(TARGET).lnk |
$(REMOVE) $(TARGET).lss |
$(REMOVE) $(OBJ) |
$(REMOVE) $(LST) |
$(REMOVE) $(SRC:.c=.s) |
$(REMOVE) $(SRC:.c=.d) |
$(REMOVE) $(SRC:.c=.o) |
# Automatically generate C source code dependencies. |
# (Code originally taken from the GNU make user manual and modified |
# (See README.txt Credits).) |
# |
# Note that this will work with sh (bash) and sed that is shipped with WinAVR |
# (see the SHELL variable defined above). |
# This may not work with other shells or other seds. |
# |
%.d: %.c |
set -e; $(CC) -MM $(ALL_CFLAGS) $< \ |
| sed 's,\(.*\)\.o[ :]*,\1.o \1.d : ,g' > $@; \ |
[ -s $@ ] || rm -f $@ |
# Remove the '-' if you want to see the dependency files generated. |
-include $(SRC:%.c=%.d) |
# Listing of phony targets. |
.PHONY : all begin finish end sizebefore sizeafter gccversion coff extcoff \ |
clean clean_list program |
/tags/V2.12a/menu.c |
---|
0,0 → 1,358 |
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
// + www.MikroKopter.com |
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
// + Software Nutzungsbedingungen (english version: see below) |
// + der Fa. HiSystems GmbH, Flachsmeerstrasse 2, 26802 Moormerland - nachfolgend Lizenzgeber genannt - |
// + Der Lizenzgeber räumt dem Kunden ein nicht-ausschließliches, zeitlich und räumlich* unbeschränktes Recht ein, die im den |
// + Mikrocontroller verwendete Firmware für die Hardware Flight-Ctrl, Navi-Ctrl, BL-Ctrl, MK3Mag & PC-Programm MikroKopter-Tool |
// + - nachfolgend Software genannt - nur für private Zwecke zu nutzen. |
// + Der Einsatz dieser Software ist nur auf oder mit Produkten des Lizenzgebers zulässig. |
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
// + Die vom Lizenzgeber gelieferte Software ist urheberrechtlich geschützt. Alle Rechte an der Software sowie an sonstigen im |
// + Rahmen der Vertragsanbahnung und Vertragsdurchführung überlassenen Unterlagen stehen im Verhältnis der Vertragspartner ausschließlich dem Lizenzgeber zu. |
// + Die in der Software enthaltenen Copyright-Vermerke, Markenzeichen, andere Rechtsvorbehalte, Seriennummern sowie |
// + sonstige der Programmidentifikation dienenden Merkmale dürfen vom Kunden nicht verändert oder unkenntlich gemacht werden. |
// + Der Kunde trifft angemessene Vorkehrungen für den sicheren Einsatz der Software. Er wird die Software gründlich auf deren |
// + Verwendbarkeit zu dem von ihm beabsichtigten Zweck testen, bevor er diese operativ einsetzt. |
// + Die Haftung des Lizenzgebers wird - soweit gesetzlich zulässig - begrenzt in Höhe des typischen und vorhersehbaren |
// + Schadens. Die gesetzliche Haftung bei Personenschäden und nach dem Produkthaftungsgesetz bleibt unberührt. Dem Lizenzgeber steht jedoch der Einwand |
// + des Mitverschuldens offen. |
// + Der Kunde trifft angemessene Vorkehrungen für den Fall, dass die Software ganz oder teilweise nicht ordnungsgemäß arbeitet. |
// + Er wird die Software gründlich auf deren Verwendbarkeit zu dem von ihm beabsichtigten Zweck testen, bevor er diese operativ einsetzt. |
// + Der Kunde wird er seine Daten vor Einsatz der Software nach dem Stand der Technik sichern. |
// + Der Kunde ist darüber unterrichtet, dass der Lizenzgeber seine Daten im zur Vertragsdurchführung erforderlichen Umfang |
// + und auf Grundlage der Datenschutzvorschriften erhebt, speichert, verarbeitet und, sofern notwendig, an Dritte übermittelt. |
// + *) Die räumliche Nutzung bezieht sich nur auf den Einsatzort, nicht auf die Reichweite der programmierten Software. |
// + #### ENDE DER NUTZUNGSBEDINGUNGEN ####' |
// + Hinweis: Informationen über erweiterte Nutzungsrechte (wie z.B. Nutzung für nicht-private Zwecke) sind auf Anfrage per Email an info(@)hisystems.de verfügbar. |
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
// + Software LICENSING TERMS |
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
// + of HiSystems GmbH, Flachsmeerstrasse 2, 26802 Moormerland, Germany - the Licensor - |
// + The Licensor grants the customer a non-exclusive license to use the microcontroller firmware of the Flight-Ctrl, Navi-Ctrl, BL-Ctrl, and MK3Mag hardware |
// + (the Software) exclusively for private purposes. The License is unrestricted with respect to time and territory*. |
// + The Software may only be used with the Licensor's products. |
// + The Software provided by the Licensor is protected by copyright. With respect to the relationship between the parties to this |
// + agreement, all rights pertaining to the Software and other documents provided during the preparation and execution of this |
// + agreement shall be the property of the Licensor. |
// + The information contained in the Software copyright notices, trademarks, other legal reservations, serial numbers and other |
// + features that can be used to identify the program may not be altered or defaced by the customer. |
// + The customer shall be responsible for taking reasonable precautions |
// + for the safe use of the Software. The customer shall test the Software thoroughly regarding its suitability for the |
// + intended purpose before implementing it for actual operation. The Licensor's liability shall be limited to the extent of typical and |
// + foreseeable damage to the extent permitted by law, notwithstanding statutory liability for bodily injury and product |
// + liability. However, the Licensor shall be entitled to the defense of contributory negligence. |
// + The customer will take adequate precautions in the case, that the software is not working properly. The customer will test |
// + the software for his purpose before any operational usage. The customer will backup his data before using the software. |
// + The customer understands that the Licensor collects, stores and processes, and, where required, forwards, customer data |
// + to third parties to the extent necessary for executing the agreement, subject to applicable data protection and privacy regulations. |
// + *) The territory aspect only refers to the place where the Software is used, not its programmed range. |
// + #### END OF LICENSING TERMS #### |
// + Note: For information on license extensions (e.g. commercial use), please contact us at info(@)hisystems.de. |
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
#include "main.h" |
#include "eeprom.h" |
char DisplayBuff[80]; |
unsigned char DispPtr = 0; |
unsigned char MaxMenue = 19; |
unsigned char MenuePunkt = 0; |
unsigned char RemoteKeys = 0; |
#define KEY1 0x01 |
#define KEY2 0x02 |
#define KEY3 0x04 |
#define KEY4 0x08 |
#define KEY5 0x10 |
void LcdClear(void) |
{ |
unsigned char i; |
for(i=0;i<80;i++) DisplayBuff[i] = ' '; |
} |
void Menu_Putchar(char c) |
{ |
if(DispPtr < 80) DisplayBuff[DispPtr++] = c; |
} |
void Menu(void) |
{ |
unsigned char i; |
static char DisableMenu = 0, AccMenu = 0, changed = 0; |
if(!DisableMenu) |
{ |
if(RemoteKeys & KEY1) { if(MenuePunkt) MenuePunkt--; else MenuePunkt = MaxMenue;} |
if(RemoteKeys & KEY2) { if(MenuePunkt == MaxMenue) MenuePunkt = 0; else MenuePunkt++;} |
if((RemoteKeys & KEY1) && (RemoteKeys & KEY2)) MenuePunkt = 0; |
} |
LcdClear(); |
if(MenuePunkt < 10) {LCD_printfxy(17,0,"[%i]",MenuePunkt);} |
else {LCD_printfxy(16,0,"[%i]",MenuePunkt);}; |
switch(MenuePunkt) |
{ |
case 0: |
LCD_printfxy(0,0,"+ MikroKopter +"); |
LCD_printfxy(0,1,"HW:V%d.%d SW:%d.%02d%c ",PlatinenVersion/10,PlatinenVersion%10, VERSION_MAJOR, VERSION_MINOR, VERSION_PATCH +'a'); |
LCD_printfxy(0,2,"Set:%d %s", ActiveParamSet,Mixer.Name); |
if(FC_StatusFlags3 & FC_STATUS3_BOAT) LCD_printfxy(16,2,"BOAT"); |
if(VersionInfo.HardwareError[1] & FC_ERROR1_MIXER) LCD_printfxy(0,3,"Mixer Error!") |
else |
#if (defined(__AVR_ATmega1284__) || defined(__AVR_ATmega1284P__)) |
if(NC_ErrorCode) |
{ |
LCD_printfxy(0,3,"ERR%2d:",NC_ErrorCode); |
_printf_P(&Menu_Putchar, NC_ERROR_TEXT[NC_ErrorCode] , 0); |
} |
else |
#endif |
if(VersionInfo.HardwareError[0]) LCD_printfxy(0,3,"Hardware Error 1:%d !!",VersionInfo.HardwareError[0]) |
else |
if(MissingMotor) LCD_printfxy(0,3,"Missing BL-Ctrl:%d !!",MissingMotor) |
#if (defined(__AVR_ATmega1284__) || defined(__AVR_ATmega1284P__)) |
#else |
else |
if(NC_ErrorCode) |
{ |
LCD_printfxy(0,3,"! NC-ERR: %2d ! ",NC_ErrorCode); |
} |
#endif |
// if(VersionInfo.HardwareError[1]) LCD_printfxy(0,3,"Error 2:%d !!",VersionInfo.HardwareError[1]) |
else |
if(I2CTimeout < 6) LCD_printfxy(0,3,"I2C ERROR!!!") |
else |
if(Capacity.MinOfMaxPWM < 30) LCD_printfxy(0,3,"BL-Selftest Err:%2d",Capacity.MinOfMaxPWM) |
break; |
case 1: |
LCD_printfxy(0,0,"Height: %5i",(int)(HoehenWert/5)); |
LCD_printfxy(0,1,"Setpoint:%5i",(int)(SollHoehe/5)); |
LCD_printfxy(0,2,"Pressure:%5i",MessLuftdruck); |
LCD_printfxy(0,3,"Offset: %5i",OCR0A); |
#if (defined(__AVR_ATmega1284__) || defined(__AVR_ATmega1284P__)) |
if(ACC_AltitudeControl) |
{ |
LCD_printfxy(17,2,"(A)"); |
LCD_printfxy(17,3,"%i",CalAthmospheare); |
} |
#endif |
break; |
case 2: |
LCD_printfxy(0,0,"act. bearing"); |
LCD_printfxy(0,1,"Nick: %5i",IntegralNick/1024); |
LCD_printfxy(0,2,"Roll: %5i",IntegralRoll/1024); |
LCD_printfxy(0,3,"Compass: %5i",CompassCorrected); |
break; |
case 3: |
for(i=1;i<9;i+=2) LCD_printfxy(0,i/2,"K%i:%4i K%i:%4i ",i,PPM_in[i],i+1,PPM_in[i+1]); |
break; |
case 4: |
LCD_printfxy(0,0,"Ni:%4i Ro:%4i ",ChannelNick,ChannelRoll); |
LCD_printfxy(0,1,"Gs:%4i Gi:%4i ",ChannelGas+127,ChannelYaw); |
LCD_printfxy(0,2,"P1:%4i P2:%4i ",PPM_in[EE_Parameter.Kanalbelegung[K_POTI1]]+127,PPM_in[EE_Parameter.Kanalbelegung[K_POTI2]]+127); |
LCD_printfxy(0,3,"P3:%4i P4:%4i ",PPM_in[EE_Parameter.Kanalbelegung[K_POTI3]]+127,PPM_in[EE_Parameter.Kanalbelegung[K_POTI4]]+127); |
break; |
case 5: |
LCD_printfxy(0,0,"Gyro - Sensor"); |
LCD_printfxy(0,1,"Nick %4i (%4i)",AdWertNick - AdNeutralNick/8, AdNeutralNick); |
LCD_printfxy(0,2,"Roll %4i (%4i)",AdWertRoll - AdNeutralRoll/8, AdNeutralRoll); |
LCD_printfxy(0,3,"Yaw %4i (%4i)",AdNeutralGier - AdWertGier, AdNeutralGier); |
AccMenu = 0; |
break; |
case 6: |
switch(AccMenu) |
{ |
case 0: |
LCD_printfxy(0,0,"ACC - Sensor"); |
LCD_printfxy(0,1,"Nick %4i (%3i)",AdWertAccNick,NeutralAccX); |
LCD_printfxy(0,2,"Roll %4i (%3i)",AdWertAccRoll,NeutralAccY); |
LCD_printfxy(0,3,"Z %4i (%3i)(cal)",AdWertAccHoch,(int)NeutralAccZ); |
if(RemoteKeys & KEY4) AccMenu++; |
changed = 0; |
break; |
case 1: |
LCD_printfxy(0,0,"Calibration:"); |
LCD_printfxy(0,1,"ACC: N:%3i R:%3i ",NeutralAccY,NeutralAccX); |
if(ChannelNick || ChannelRoll) LCD_printfxy(0,2,"Stick: (%i/%i) !! ",ChannelNick,ChannelRoll); |
if((FC_StatusFlags & FC_STATUS_MOTOR_RUN) && ((NC_GPS_ModeCharacter == ' ') || (NC_GPS_ModeCharacter == '/') || (NC_GPS_ModeCharacter == '-'))) |
{ |
DisableMenu = 1; |
if(!EE_Parameter.Driftkomp) EE_Parameter.Driftkomp = 6; // enables the Gyro-Drift compensation to make sure that a litlte calibration error won't effect the attitude |
if(RemoteKeys & KEY1) { NeutralAccY--; changed = 1;} |
if(RemoteKeys & KEY2) { NeutralAccY++; changed = 1;} |
if(RemoteKeys & KEY3) { NeutralAccX--; changed = 1;} |
if(RemoteKeys & KEY4) { NeutralAccX++; changed = 1;} |
LCD_printfxy(13,0,"on "); |
if(changed) LCD_printfxy(0,3,"land to save ") |
else LCD_printfxy(0,3,"use keys to trim ACC") |
} |
else |
{ |
LCD_printfxy(13,0,"off"); |
DisableMenu = 0; |
if(!(FC_StatusFlags & FC_STATUS_MOTOR_RUN) && changed) |
{ |
LCD_printfxy(0,3,"Save? (yes)(no)"); |
if(RemoteKeys & KEY3) { StoreNeutralToEeprom(); AccMenu = 0;} |
if(RemoteKeys & KEY4) { changed = 0;} |
} |
else LCD_printfxy(0,3,"Fly with GPS off"); |
} |
break; |
default: AccMenu = 0; break; |
} |
break; |
case 7: |
LCD_printfxy(0,0,"Voltage: %3i.%1iV",UBat/10, UBat%10); |
LCD_printfxy(0,1,"Current: %3i.%1iA",Capacity.ActualCurrent/10, Capacity.ActualCurrent%10); |
LCD_printfxy(0,2,"Power: %4iW",Capacity.ActualPower); |
LCD_printfxy(0,3,"Discharge: %5imAh", Capacity.UsedCapacity); |
AccMenu = 0; |
break; |
case 8: |
LCD_printfxy(0,0,"Receiver"); |
LCD_printfxy(0,2,"RC-Quality: %4i", SenderOkay); |
LCD_printfxy(0,3,"RC-Channels:%4i", Channels-1); |
break; |
case 9: |
LCD_printfxy(0,0,"Undervoltages " ); |
LCD_printfxy(0,1,"Warn: %2d.%dV",BattLowVoltageWarning/10,BattLowVoltageWarning%10); |
LCD_printfxy(0,2,"Home: %2d.%dV",BattComingHomeVoltage/10,BattComingHomeVoltage%10); |
LCD_printfxy(0,3,"Land: %2d.%dV",BattAutoLandingVoltage/10,BattAutoLandingVoltage%10); |
break; |
case 10: |
for(i=0;i<4;i++) LCD_printfxy(0,i,"Poti%i: %3i",i+1,Poti[i]); |
break; |
case 11: |
for(i=0;i<4;i++) LCD_printfxy(0,i,"Poti%i: %3i",i+5,Poti[i+4]); |
break; |
case 12: |
LCD_printfxy(0,0,"Flight-Time " ); |
LCD_printfxy(0,1,"Total:%5umin",FlugMinutenGesamt); |
LCD_printfxy(0,2,"Act: %5umin",FlugMinuten); |
LCD_printfxy(13,3,"(reset)"); |
if(RemoteKeys & KEY4) |
{ |
FlugMinuten = 0; |
SetParamWord(PID_FLIGHT_MINUTES, FlugMinuten); |
} |
break; |
#if (defined(__AVR_ATmega1284__) || defined(__AVR_ATmega1284P__)) |
case 13: |
LCD_printfxy(0,0,"Compass"); |
LCD_printfxy(0,1,"Magnet: %5i",KompassValue); |
LCD_printfxy(0,2,"Gyro: %5i",ErsatzKompassInGrad); |
LCD_printfxy(0,3,"True: %5i",CompassCorrected); |
break; |
case 14: |
LCD_printfxy(0,0,"Servo " ); |
LCD_printfxy(0,1,"Setpoint %3i",Parameter_ServoNickControl); |
LCD_printfxy(0,2,"Position: %3i",ServoNickValue/4); |
LCD_printfxy(0,3,"Range:%3i-%3i",EE_Parameter.ServoNickMin,EE_Parameter.ServoNickMax); |
break; |
case 15: |
if(RequiredMotors < 13) |
{ |
LCD_printfxy(0,0,"BL-Ctrl Errors " ); |
for(i=0;i<3;i++) |
LCD_printfxy(0,i+1,"%3d %3d %3d %3d ",Motor[i*4].State & MOTOR_STATE_ERROR_MASK,Motor[i*4+1].State & MOTOR_STATE_ERROR_MASK,Motor[i*4+2].State & MOTOR_STATE_ERROR_MASK,Motor[i*4+3].State & MOTOR_STATE_ERROR_MASK); |
} |
else |
{ |
for(i=0;i<4;i++) |
LCD_printfxy(0,i,"%3d %3d %3d %3d ",Motor[i*4].State & MOTOR_STATE_ERROR_MASK,Motor[i*4+1].State & MOTOR_STATE_ERROR_MASK,Motor[i*4+2].State & MOTOR_STATE_ERROR_MASK,Motor[i*4+3].State & MOTOR_STATE_ERROR_MASK); |
LCD_printfxy(16,1,"BL-"); |
LCD_printfxy(16,2,"Err."); |
} |
break; |
case 16: |
if(RequiredMotors < 13) |
{ |
LCD_printfxy(0,0,"BL- Temperature" ); |
for(i=0;i<3;i++) |
{ |
LCD_printfxy(0,i+1,"%3d %3d %3d %3d ",Motor[i*4].Temperature,Motor[i*4+1].Temperature,Motor[i*4+2].Temperature,Motor[i*4+3].Temperature); |
} |
} |
else |
{ |
for(i=0;i<4;i++) |
{ |
LCD_printfxy(0,i,"%3d %3d %3d %3d ",Motor[i*4].Temperature,Motor[i*4+1].Temperature,Motor[i*4+2].Temperature,Motor[i*4+3].Temperature); |
} |
LCD_printfxy(16,1,"BL-"); |
LCD_printfxy(16,2,"Temp"); |
} |
LCD_printfxy(18,3,"C"); |
break; |
case 17: |
if(RequiredMotors < 13) |
{ |
LCD_printfxy(0,0,"BL Current" ); |
LCD_printfxy(11,3,"(in 0.1A)" ); |
for(i=0;i<3;i++) |
{ |
LCD_printfxy(0,i+1,"%3d %3d %3d %3d ",BL3_Current(i*4),BL3_Current(i*4+1),BL3_Current(i*4+2),BL3_Current(i*4+3)); |
if(4 + i * 4 >= RequiredMotors) break; |
} |
} |
else |
{ |
for(i=0;i<4;i++) |
{ |
LCD_printfxy(0,i,"%3d %3d %3d %3d ",BL3_Current(i*4),BL3_Current(i*4+1),BL3_Current(i*4+2),BL3_Current(i*4+3)); |
} |
LCD_printfxy(16,2,"BL-"); |
LCD_printfxy(16,3,"I"); |
} |
break; |
case 18: |
LCD_printfxy(0,0,"BL-Ctrl found " ); |
DispPtr = 20; |
for(i=0; i<MAX_MOTORS; i++) |
{ |
if(i == 6 || i == 12) LCD_printf(" "); |
if(Motor[i].State & MOTOR_STATE_PRESENT_MASK) |
{ |
LCD_printf(" %2i",i+1); |
} |
else LCD_printf(" -"); |
} |
break; |
case 19: |
if(RequiredMotors < 13) |
{ |
LCD_printfxy(0,0,"BL Versions" ); |
for(i=0;i<3;i++) |
{ |
LCD_printfxy(0,i+1,"%1d.%02d %1d.%02d %1d.%02d %1d.%02d",Motor[i*4].VersionMajor,Motor[i*4].VersionMinor,Motor[i*4+1].VersionMajor,Motor[i*4+1].VersionMinor,Motor[i*4+2].VersionMajor,Motor[i*4+2].VersionMinor,Motor[i*4+3].VersionMajor,Motor[i*4+3].VersionMinor); |
if(4 + i * 4 >= RequiredMotors) break; |
} |
} |
else |
{ |
for(i=0;i<4;i++) |
LCD_printfxy(0,i," %1d.%02d %1d.%02d %1d.%02d %1d.%02d",Motor[i*4].VersionMajor,Motor[i*4].VersionMinor,Motor[i*4+1].VersionMajor,Motor[i*4+1].VersionMinor,Motor[i*4+2].VersionMajor,Motor[i*4+2].VersionMinor,Motor[i*4+3].VersionMajor,Motor[i*4+3].VersionMinor); |
} |
break; |
/* case 20: |
LCD_printfxy(0,0,"BL MaxPWM " ); |
for(i=0;i<3;i++) |
{ |
LCD_printfxy(0,i+1,"%3d %3d %3d %3d ",Motor[i*4].MaxPWM,Motor[i*4+1].MaxPWM,Motor[i*4+2].MaxPWM,Motor[i*4+3].MaxPWM); |
if(4 + i * 4 >= RequiredMotors) break; |
} |
break; |
*/ |
#endif |
default: |
if(MenuePunkt == MaxMenue) MaxMenue--; |
MenuePunkt = 0; |
break; |
} |
RemoteKeys = 0; |
} |
/tags/V2.12a/menu.h |
---|
0,0 → 1,17 |
#ifndef _MENU_H |
#define _MENU_H |
extern void Menu(void); |
extern void LcdClear(void); |
extern void Menu_Putchar(char c); |
extern char DisplayBuff[80]; |
extern unsigned char DispPtr; |
extern unsigned char MaxMenue; |
extern unsigned char MenuePunkt; |
extern unsigned char RemoteKeys; |
#define LCD_printfxy(x,y,format, args...) { DispPtr = (y) * 20 + (x); _printf_P(&Menu_Putchar,PSTR(format) , ## args);} |
#define LCD_printf(format, args...) { _printf_P(&Menu_Putchar, PSTR(format) , ## args);} |
#endif //_MENU_H |
/tags/V2.12a/mymath.c |
---|
0,0 → 1,42 |
#include <stdlib.h> |
#include <avr/pgmspace.h> |
#include "mymath.h" |
// discrete mathematics |
// Sinus with argument in degree at an angular resolution of 1 degree and a discretisation of 13 bit. |
const uint16_t pgm_sinlookup[91] PROGMEM = {0, 143, 286, 429, 571, 714, 856, 998, 1140, 1282, 1423, 1563, 1703, 1843, 1982, 2120, 2258, 2395, 2531, 2667, 2802, 2936, 3069, 3201, 3332, 3462, 3591, 3719, 3846, 3972, 4096, 4219, 4341, 4462, 4581, 4699, 4815, 4930, 5043, 5155, 5266, 5374, 5482, 5587, 5691, 5793, 5893, 5991, 6088, 6183, 6275, 6366, 6455, 6542, 6627, 6710, 6791, 6870, 6947, 7022, 7094, 7165, 7233, 7299, 7363, 7424, 7484, 7541, 7595, 7648, 7698, 7746, 7791, 7834, 7875, 7913, 7949, 7982, 8013, 8041, 8068, 8091, 8112, 8131, 8147, 8161, 8172, 8181, 8187, 8191, 8192}; |
int16_t c_cos_8192(int16_t angle) |
{ |
int8_t m,n; |
int16_t sinus; |
angle = 90 - angle; // we need the cosinus and not the sinus |
// avoid negative angles |
if (angle < 0) |
{ |
m = -1; |
angle = abs(angle); |
} |
else m = +1; |
// fold angle to intervall 0 to 359 |
angle %= 360; |
// check quadrant |
if (angle <= 90) n=1; // first quadrant |
else if ((angle > 90) && (angle <= 180)) {angle = 180 - angle; n = 1;} // second quadrant |
else if ((angle > 180) && (angle <= 270)) {angle = angle - 180; n = -1;} // third quadrant |
else {angle = 360 - angle; n = -1;} //fourth quadrant |
// get lookup value |
sinus = pgm_read_word(&pgm_sinlookup[angle]); |
// calculate sinus value |
return (sinus * m * n); |
} |
/* |
// Cosinus with argument in degree at an angular resolution of 1 degree and a discretisation of 13 bit. |
int16_t c_cos_8192(int16_t angle) |
{ |
return (c_sin_8192(90 - angle)); |
} |
*/ |
/tags/V2.12a/mymath.h |
---|
0,0 → 1,10 |
#ifndef _MYMATH_H |
#define _MYMATH_H |
#include <inttypes.h> |
//extern int16_t c_sin_8192(int16_t angle); |
extern int16_t c_cos_8192(int16_t angle); |
extern int16_t c_atan2(int16_t y, int16_t x); |
extern uint32_t c_sqrt(uint32_t a); |
#endif // _MYMATH_H |
/tags/V2.12a/old_macros.h |
---|
0,0 → 1,47 |
/* |
For backwards compatibility only. |
Ingo Busker ingo@mikrocontroller.com |
*/ |
#ifndef cbi |
#define cbi(sfr, bit) (_SFR_BYTE(sfr) &= ~_BV(bit)) |
#endif |
#ifndef sbi |
#define sbi(sfr, bit) (_SFR_BYTE(sfr) |= _BV(bit)) |
#endif |
#ifndef inb |
#define inb(sfr) _SFR_BYTE(sfr) |
#endif |
#ifndef outb |
#define outb(sfr, val) (_SFR_BYTE(sfr) = (val)) |
#endif |
#ifndef inw |
#define inw(sfr) _SFR_WORD(sfr) |
#endif |
#ifndef outw |
#define outw(sfr, val) (_SFR_WORD(sfr) = (val)) |
#endif |
#ifndef outp |
#define outp(val, sfr) outb(sfr, val) |
#endif |
#ifndef inp |
#define inp(sfr) inb(sfr) |
#endif |
#ifndef BV |
#define BV(bit) _BV(bit) |
#endif |
#ifndef PRG_RDB |
#define PRG_RDB pgm_read_byte |
#endif |
/tags/V2.12a/printf_P.h |
---|
0,0 → 1,69 |
// Die Funktion printf_P() unterliegt ihrer eigenen Lizenz und ist nicht von der Lizenz für den MikroKopter-Teil unterstellt |
/* |
Copyright (C) 1993 Free Software Foundation |
This file is part of the GNU IO Library. This library is free |
software; you can redistribute it and/or modify it under the |
terms of the GNU General Public License as published by the |
Free Software Foundation; either version 2, or (at your option) |
any later version. |
This library is distributed in the hope that it will be useful, |
but WITHOUT ANY WARRANTY; without even the implied warranty of |
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
GNU General Public License for more details. |
You should have received a copy of the GNU General Public License |
along with this library; see the file COPYING. If not, write to the Free |
Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. |
As a special exception, if you link this library with files |
compiled with a GNU compiler to produce an executable, this does not cause |
the resulting executable to be covered by the GNU General Public License. |
This exception does not however invalidate any other reasons why |
the executable file might be covered by the GNU General Public License. */ |
/* |
* Copyright (c) 1990 Regents of the University of California. |
* All rights reserved. |
* |
* Redistribution and use in source and binary forms, with or without |
* modification, are permitted provided that the following conditions |
* are met: |
* 1. Redistributions of source code must retain the above copyright |
* notice, this list of conditions and the following disclaimer. |
* 2. Redistributions in binary form must reproduce the above copyright |
* notice, this list of conditions and the following disclaimer in the |
* documentation and/or other materials provided with the distribution. |
* 3. [rescinded 22 July 1999] |
* 4. Neither the name of the University nor the names of its contributors |
* may be used to endorse or promote products derived from this software |
* without specific prior written permission. |
* |
* THIS SOFTWARE IS PROVIDED BY THE REGENTS 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 REGENTS 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. |
*/ |
/******************************************************************************/ |
#ifndef _PRINTF_P_H_ |
#define _PRINTF_P_H_ |
#include <avr/pgmspace.h> |
// function pointer to external callback function |
typedef void (*pVoidFnctChar) (char ); |
typedef void (*pVoidFnct_pVoidFnctChar_const_fmt) (pVoidFnctChar, char const *fmt0, ...); |
extern pVoidFnct_pVoidFnctChar_const_fmt _printf_P; |
#endif //_PRINTF_P_H_ |
/tags/V2.12a/rc.c |
---|
0,0 → 1,189 |
/*####################################################################################### |
Decodieren eines RC Summen Signals |
#######################################################################################*/ |
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
// + www.MikroKopter.com |
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
// + Software Nutzungsbedingungen (english version: see below) |
// + der Fa. HiSystems GmbH, Flachsmeerstrasse 2, 26802 Moormerland - nachfolgend Lizenzgeber genannt - |
// + Der Lizenzgeber räumt dem Kunden ein nicht-ausschließliches, zeitlich und räumlich* unbeschränktes Recht ein, die im den |
// + Mikrocontroller verwendete Firmware für die Hardware Flight-Ctrl, Navi-Ctrl, BL-Ctrl, MK3Mag & PC-Programm MikroKopter-Tool |
// + - nachfolgend Software genannt - nur für private Zwecke zu nutzen. |
// + Der Einsatz dieser Software ist nur auf oder mit Produkten des Lizenzgebers zulässig. |
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
// + Die vom Lizenzgeber gelieferte Software ist urheberrechtlich geschützt. Alle Rechte an der Software sowie an sonstigen im |
// + Rahmen der Vertragsanbahnung und Vertragsdurchführung überlassenen Unterlagen stehen im Verhältnis der Vertragspartner ausschließlich dem Lizenzgeber zu. |
// + Die in der Software enthaltenen Copyright-Vermerke, Markenzeichen, andere Rechtsvorbehalte, Seriennummern sowie |
// + sonstige der Programmidentifikation dienenden Merkmale dürfen vom Kunden nicht verändert oder unkenntlich gemacht werden. |
// + Der Kunde trifft angemessene Vorkehrungen für den sicheren Einsatz der Software. Er wird die Software gründlich auf deren |
// + Verwendbarkeit zu dem von ihm beabsichtigten Zweck testen, bevor er diese operativ einsetzt. |
// + Die Haftung des Lizenzgebers wird - soweit gesetzlich zulässig - begrenzt in Höhe des typischen und vorhersehbaren |
// + Schadens. Die gesetzliche Haftung bei Personenschäden und nach dem Produkthaftungsgesetz bleibt unberührt. Dem Lizenzgeber steht jedoch der Einwand |
// + des Mitverschuldens offen. |
// + Der Kunde trifft angemessene Vorkehrungen für den Fall, dass die Software ganz oder teilweise nicht ordnungsgemäß arbeitet. |
// + Er wird die Software gründlich auf deren Verwendbarkeit zu dem von ihm beabsichtigten Zweck testen, bevor er diese operativ einsetzt. |
// + Der Kunde wird er seine Daten vor Einsatz der Software nach dem Stand der Technik sichern. |
// + Der Kunde ist darüber unterrichtet, dass der Lizenzgeber seine Daten im zur Vertragsdurchführung erforderlichen Umfang |
// + und auf Grundlage der Datenschutzvorschriften erhebt, speichert, verarbeitet und, sofern notwendig, an Dritte übermittelt. |
// + *) Die räumliche Nutzung bezieht sich nur auf den Einsatzort, nicht auf die Reichweite der programmierten Software. |
// + #### ENDE DER NUTZUNGSBEDINGUNGEN ####' |
// + Hinweis: Informationen über erweiterte Nutzungsrechte (wie z.B. Nutzung für nicht-private Zwecke) sind auf Anfrage per Email an info(@)hisystems.de verfügbar. |
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
// + Software LICENSING TERMS |
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
// + of HiSystems GmbH, Flachsmeerstrasse 2, 26802 Moormerland, Germany - the Licensor - |
// + The Licensor grants the customer a non-exclusive license to use the microcontroller firmware of the Flight-Ctrl, Navi-Ctrl, BL-Ctrl, and MK3Mag hardware |
// + (the Software) exclusively for private purposes. The License is unrestricted with respect to time and territory*. |
// + The Software may only be used with the Licensor's products. |
// + The Software provided by the Licensor is protected by copyright. With respect to the relationship between the parties to this |
// + agreement, all rights pertaining to the Software and other documents provided during the preparation and execution of this |
// + agreement shall be the property of the Licensor. |
// + The information contained in the Software copyright notices, trademarks, other legal reservations, serial numbers and other |
// + features that can be used to identify the program may not be altered or defaced by the customer. |
// + The customer shall be responsible for taking reasonable precautions |
// + for the safe use of the Software. The customer shall test the Software thoroughly regarding its suitability for the |
// + intended purpose before implementing it for actual operation. The Licensor's liability shall be limited to the extent of typical and |
// + foreseeable damage to the extent permitted by law, notwithstanding statutory liability for bodily injury and product |
// + liability. However, the Licensor shall be entitled to the defense of contributory negligence. |
// + The customer will take adequate precautions in the case, that the software is not working properly. The customer will test |
// + the software for his purpose before any operational usage. The customer will backup his data before using the software. |
// + The customer understands that the Licensor collects, stores and processes, and, where required, forwards, customer data |
// + to third parties to the extent necessary for executing the agreement, subject to applicable data protection and privacy regulations. |
// + *) The territory aspect only refers to the place where the Software is used, not its programmed range. |
// + #### END OF LICENSING TERMS #### |
// + Note: For information on license extensions (e.g. commercial use), please contact us at info(@)hisystems.de. |
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
#include "rc.h" |
#include "main.h" |
// Achtung: ACT_S3D_SUMMENSIGNAL wird in der Main.h gesetzt |
#define MAX_RC_IN 16+12+3+4 // 16ch + 12ser + 3stages + 4 reserved |
volatile int PPM_in[MAX_RC_IN]; |
volatile int PPM_diff[MAX_RC_IN]; // das differnzierte Stick-Signal |
volatile char Channels,tmpChannels = 0; |
volatile unsigned char NewPpmData = 1; |
unsigned int PPM_Neutral = 466; |
signed int ChannelNick,ChannelRoll,ChannelGas,ChannelYaw; |
//############################################################################ |
// Clear the values |
void rc_sum_init(void) |
//############################################################################ |
{ |
unsigned char i; |
for(i=0;i<MAX_RC_IN;i++) |
{ |
if(i < 5) PPM_in[i] = 0; else PPM_in[i] = -127; |
PPM_diff[i] = 0; |
} |
PPM_in[PPM_IN_MAX] = +127; |
PPM_in[PPM_IN_OFF] = -127; |
PPM_in[PPM_IN_MID] = 0; |
AdNeutralGier = 0; |
AdNeutralRoll = 0; |
AdNeutralNick = 0; |
return; |
} |
#ifndef ACT_S3D_SUMMENSIGNAL |
//############################################################################ |
// Interrupt function for the PPM-Input |
ISR(TIMER1_CAPT_vect) |
//############################################################################ |
{ |
static unsigned int AltICR=0; |
signed int signal = 0,tmp; |
static int index; |
signal = (unsigned int) ICR1 - AltICR; |
AltICR = ICR1; |
//Syncronisationspause? (3.52 ms < signal < 25.6 ms) |
if((signal > 1100) && (signal < 8000)) |
{ |
Channels = index; |
if(index >= 4) NewPpmData = 0; // Null bedeutet: Neue Daten |
index = 1; |
} |
else |
{ |
if(index < 13+4) |
{ |
if((signal > 250) && (signal < 687)) |
{ |
signal -= PPM_Neutral; |
// Stabiles Signal |
if(EE_Parameter.FailsafeChannel == 0 || PPM_in[EE_Parameter.FailsafeChannel] < 100) // forces Failsafe if the receiver doesn't have 'signal loss' on Failsafe |
{ |
if(abs(signal - PPM_in[index]) < 6) { if(SenderOkay < 200) SenderOkay += 10; else SenderOkay = 200;} |
} |
tmp = (3 * (PPM_in[index]) + signal) / 4; |
if(tmp > signal+1) tmp--; else |
if(tmp < signal-1) tmp++; |
if(SenderOkay >= 195) PPM_diff[index] = ((tmp - PPM_in[index]) / 3) * 3; |
else PPM_diff[index] = 0; |
PPM_in[index] = tmp; |
if(SenderOkay < 50) |
{ |
PPM_in[EE_Parameter.Kanalbelegung[K_NICK]] = 0; |
PPM_in[EE_Parameter.Kanalbelegung[K_ROLL]] = 0; |
PPM_in[EE_Parameter.Kanalbelegung[K_GIER]] = 0; |
PPM_in[EE_Parameter.Kanalbelegung[K_GAS]] = 0; |
} |
} |
index++; |
/* |
if(PlatinenVersion < 20) |
{ |
if(index == 5) J3High; else J3Low; // Servosignal an J3 anlegen |
if(index == 6) J4High; else J4Low; // Servosignal an J4 anlegen |
if(index == 7) J5High; else J5Low; // Servosignal an J5 anlegen |
} |
*/ |
} |
} |
} |
#else |
//############################################################################ |
// Interrupt function for the PPM-Input |
ISR(TIMER1_CAPT_vect) |
//############################################################################ |
{ |
static unsigned int AltICR=0; |
signed int signal = 0,tmp; |
static int index; |
signal = (unsigned int) ICR1 - AltICR; |
signal /= 2; |
AltICR = ICR1; |
//Syncronisationspause? |
if((signal > 1100*2) && (signal < 8000*2)) |
{ |
if(index >= 4) NewPpmData = 0; // Null bedeutet: Neue Daten |
index = 1; |
} |
else |
{ |
if(index < 13) |
{ |
if((signal > 250) && (signal < 687*2)) |
{ |
signal -= 962; |
// Stabiles Signal |
if(abs(signal - PPM_in[index]) < 6) { if(SenderOkay < 200) SenderOkay += 10;} |
tmp = (3 * (PPM_in[index]) + signal) / 4; |
if(tmp > signal+1) tmp--; else |
if(tmp < signal-1) tmp++; |
if(SenderOkay >= 195) PPM_diff[index] = ((tmp - PPM_in[index]) / 3) * 3; |
else PPM_diff[index] = 0; |
PPM_in[index] = tmp; |
} |
index++; |
} |
} |
} |
#endif |
/tags/V2.12a/rc.h |
---|
0,0 → 1,43 |
/*####################################################################################### |
Derkodieren eines RC Summen Signals |
#######################################################################################*/ |
#ifndef _RC_H |
#define _RC_H |
#if defined (__AVR_ATmega644__) |
#define TIMER_RELOAD_VALUE 250 |
#endif |
#if defined (__AVR_ATmega644P__) |
#define TIMER_RELOAD_VALUE 250 |
#endif |
#define MAX_RC_IN 16+12+3+4 // 16ch + 12ser + 3stages + 4 reserved |
extern void rc_sum_init (void); |
extern volatile int PPM_in[MAX_RC_IN]; |
extern volatile int PPM_diff[MAX_RC_IN]; // das diffenzierte Stick-Signal |
extern volatile unsigned char NewPpmData; |
extern volatile char Channels,tmpChannels; |
extern unsigned int PPM_Neutral; |
extern signed int ChannelNick,ChannelRoll,ChannelGas,ChannelYaw; |
// 0 -> frei bzw. ACT rssi |
// 1 - 16 -> 1-16 |
// 17 - 28 -> 12 Serial channels |
// 29 -> WP-Event kanal |
// 30 -> -127 |
// 31 -> 0 |
// 32 -> 128 |
#define SERIAL_POTI_START 17 |
#define WP_EVENT_PPM_IN 29 |
#define PPM_IN_OFF 30 |
#define PPM_IN_MAX 31 |
#define PPM_IN_MID 32 |
#define FromNC_WP_EventChannel PPM_in[WP_EVENT_PPM_IN] // WP_EVENT-Channel-Value |
#endif //_RC_H |
/tags/V2.12a/sbus.c |
---|
0,0 → 1,199 |
/*####################################################################################### |
Decodes the sbus protocol |
#######################################################################################*/ |
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
// + www.MikroKopter.com |
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
// + Software Nutzungsbedingungen (english version: see below) |
// + der Fa. HiSystems GmbH, Flachsmeerstrasse 2, 26802 Moormerland - nachfolgend Lizenzgeber genannt - |
// + Der Lizenzgeber räumt dem Kunden ein nicht-ausschließliches, zeitlich und räumlich* unbeschränktes Recht ein, die im den |
// + Mikrocontroller verwendete Firmware für die Hardware Flight-Ctrl, Navi-Ctrl, BL-Ctrl, MK3Mag & PC-Programm MikroKopter-Tool |
// + - nachfolgend Software genannt - nur für private Zwecke zu nutzen. |
// + Der Einsatz dieser Software ist nur auf oder mit Produkten des Lizenzgebers zulässig. |
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
// + Die vom Lizenzgeber gelieferte Software ist urheberrechtlich geschützt. Alle Rechte an der Software sowie an sonstigen im |
// + Rahmen der Vertragsanbahnung und Vertragsdurchführung überlassenen Unterlagen stehen im Verhältnis der Vertragspartner ausschließlich dem Lizenzgeber zu. |
// + Die in der Software enthaltenen Copyright-Vermerke, Markenzeichen, andere Rechtsvorbehalte, Seriennummern sowie |
// + sonstige der Programmidentifikation dienenden Merkmale dürfen vom Kunden nicht verändert oder unkenntlich gemacht werden. |
// + Der Kunde trifft angemessene Vorkehrungen für den sicheren Einsatz der Software. Er wird die Software gründlich auf deren |
// + Verwendbarkeit zu dem von ihm beabsichtigten Zweck testen, bevor er diese operativ einsetzt. |
// + Die Haftung des Lizenzgebers wird - soweit gesetzlich zulässig - begrenzt in Höhe des typischen und vorhersehbaren |
// + Schadens. Die gesetzliche Haftung bei Personenschäden und nach dem Produkthaftungsgesetz bleibt unberührt. Dem Lizenzgeber steht jedoch der Einwand |
// + des Mitverschuldens offen. |
// + Der Kunde trifft angemessene Vorkehrungen für den Fall, dass die Software ganz oder teilweise nicht ordnungsgemäß arbeitet. |
// + Er wird die Software gründlich auf deren Verwendbarkeit zu dem von ihm beabsichtigten Zweck testen, bevor er diese operativ einsetzt. |
// + Der Kunde wird er seine Daten vor Einsatz der Software nach dem Stand der Technik sichern. |
// + Der Kunde ist darüber unterrichtet, dass der Lizenzgeber seine Daten im zur Vertragsdurchführung erforderlichen Umfang |
// + und auf Grundlage der Datenschutzvorschriften erhebt, speichert, verarbeitet und, sofern notwendig, an Dritte übermittelt. |
// + *) Die räumliche Nutzung bezieht sich nur auf den Einsatzort, nicht auf die Reichweite der programmierten Software. |
// + #### ENDE DER NUTZUNGSBEDINGUNGEN ####' |
// + Hinweis: Informationen über erweiterte Nutzungsrechte (wie z.B. Nutzung für nicht-private Zwecke) sind auf Anfrage per Email an info(@)hisystems.de verfügbar. |
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
// + Software LICENSING TERMS |
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
// + of HiSystems GmbH, Flachsmeerstrasse 2, 26802 Moormerland, Germany - the Licensor - |
// + The Licensor grants the customer a non-exclusive license to use the microcontroller firmware of the Flight-Ctrl, Navi-Ctrl, BL-Ctrl, and MK3Mag hardware |
// + (the Software) exclusively for private purposes. The License is unrestricted with respect to time and territory*. |
// + The Software may only be used with the Licensor's products. |
// + The Software provided by the Licensor is protected by copyright. With respect to the relationship between the parties to this |
// + agreement, all rights pertaining to the Software and other documents provided during the preparation and execution of this |
// + agreement shall be the property of the Licensor. |
// + The information contained in the Software copyright notices, trademarks, other legal reservations, serial numbers and other |
// + features that can be used to identify the program may not be altered or defaced by the customer. |
// + The customer shall be responsible for taking reasonable precautions |
// + for the safe use of the Software. The customer shall test the Software thoroughly regarding its suitability for the |
// + intended purpose before implementing it for actual operation. The Licensor's liability shall be limited to the extent of typical and |
// + foreseeable damage to the extent permitted by law, notwithstanding statutory liability for bodily injury and product |
// + liability. However, the Licensor shall be entitled to the defense of contributory negligence. |
// + The customer will take adequate precautions in the case, that the software is not working properly. The customer will test |
// + the software for his purpose before any operational usage. The customer will backup his data before using the software. |
// + The customer understands that the Licensor collects, stores and processes, and, where required, forwards, customer data |
// + to third parties to the extent necessary for executing the agreement, subject to applicable data protection and privacy regulations. |
// + *) The territory aspect only refers to the place where the Software is used, not its programmed range. |
// + #### END OF LICENSING TERMS #### |
// + Note: For information on license extensions (e.g. commercial use), please contact us at info(@)hisystems.de. |
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
#include "sbus.h" |
#include "main.h" |
#if (defined(__AVR_ATmega1284__) || defined(__AVR_ATmega1284P__)) |
unsigned char NewSBusData = 0, sBusBuffer[25]; |
//############################################################################ |
// USART1 initialisation from killagreg |
void SbusUartInit(void) |
//############################################################################ |
{ |
// -- Start of USART1 initialisation for Spekturm seriell-mode |
// USART1 Control and Status Register A, B, C and baud rate register |
uint8_t sreg = SREG; |
uint16_t ubrr = (uint16_t) ((uint32_t) SYSCLK/(8 * 100000) - 1); |
// disable all interrupts before reconfiguration |
cli(); |
// disable RX-Interrupt |
UCSR1B &= ~(1 << RXCIE1); |
// disable TX-Interrupt |
UCSR1B &= ~(1 << TXCIE1); |
// disable DRE-Interrupt |
UCSR1B &= ~(1 << UDRIE1); |
/* |
// set direction of RXD1 and TXD1 pins |
// set RXD1 (PD2) as an input pin |
PORTD |= (1 << PORTD2); |
DDRD &= ~(1 << DDD2); |
// set TXD1 (PD3) as an output pin |
PORTD |= (1 << PORTD3); |
DDRD |= (1 << DDD3); |
*/ |
// USART0 Baud Rate Register |
// set clock divider |
UBRR1H = (uint8_t)(ubrr>>8); |
UBRR1L = (uint8_t)ubrr; |
// enable double speed operation |
UCSR1A |= (1 << U2X1); |
// enable receiver and transmitter |
//UCSR1B = (1<<RXEN1)|(1<<TXEN1); |
UCSR1B = (1<<RXEN1); |
// set asynchronous mode |
UCSR1C &= ~(1 << UMSEL11); |
UCSR1C &= ~(1 << UMSEL10); |
// parity |
UCSR1C <= (1 << UPM11); // even |
UCSR1C &= ~(1 << UPM10); |
// stop bit |
UCSR1C |= (1 << USBS1); // two |
// 8-bit |
UCSR1B &= ~(1 << UCSZ12); |
UCSR1C |= (1 << UCSZ11); |
UCSR1C |= (1 << UCSZ10); |
// flush receive buffer explicit |
while(UCSR1A & (1<<RXC1)) UDR1; |
// enable RX-interrupts at the end |
UCSR1B |= (1 << RXCIE1); |
// -- End of USART1 initialisation |
// restore global interrupt flags |
sBusBuffer[23] |= 4; // This Bit contains the 'Signal loss' |
SREG = sreg; |
return; |
} |
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
#define MIN_FRAMEGAP 68 // 7ms |
#define MAX_BYTEGAP 3 // 310us |
//############################################################################ |
// Is called by the uart RX interrupt |
//############################################################################ |
void SbusParser(unsigned char udr) |
{ |
static unsigned char ptr = 0; |
if(!SpektrumTimer && udr == 0x0f) // wait for the start |
{ |
ptr = 0; |
SpektrumTimer = 80; // 8ms gap |
} |
else |
{ |
if(++ptr == 24) // last byte |
{ |
NewSBusData = 1; |
} |
else |
if(ptr > 24) ptr = 25; |
else |
{ |
sBusBuffer[ptr] = udr; // collect all bytes |
} |
} |
} |
void ProcessSBus(void) |
{ |
static unsigned char load = 0; |
unsigned char bitmask8 = 1, sbyte = 2, i, index = 1, process; |
unsigned int bitmask11 = 256; |
signed int signal = 0,tmp; |
if(!(sBusBuffer[23] & 4)) // This Bit contains the 'Signal loss' |
{ |
TIMSK1 &= ~_BV(ICIE1); // disable PPM-Input |
if(EE_Parameter.FailsafeChannel == 0 || PPM_in[EE_Parameter.FailsafeChannel] < 100) // forces Failsafe if the receiver doesn't have 'signal loss' on Failsafe |
{ |
if(SenderOkay < 200) SenderOkay += 20; else SenderOkay = 200; |
} |
signal = sBusBuffer[1]; |
if(!load--) { process = (16*11 - 8); load = 2;} else process = (4*11 - 8); // lowers the processor load |
for(i = 0; i < process; i++) // collect the single bits |
{ |
if(sBusBuffer[sbyte] & bitmask8) signal |= bitmask11; |
bitmask8 *= 2; |
if(!bitmask8) |
{ |
bitmask8 = 1; |
sbyte++; |
} |
bitmask11 *= 2; |
if(bitmask11 == 2048) |
{ |
bitmask11 = 1; |
signal = (signal-1024) / 5; // the resolution is higher than required |
tmp = (3 * (PPM_in[index]) + signal) / 4; |
if(tmp > signal+1) tmp--; else |
if(tmp < signal-1) tmp++; |
if(SenderOkay >= 195) PPM_diff[index] = ((tmp - PPM_in[index]) / 3) * 3; |
else PPM_diff[index] = 0; |
PPM_in[index] = tmp; |
signal = 0; |
index++; // next channel |
} |
} |
NewPpmData = 0; // Null bedeutet: Neue Daten |
} |
NewSBusData = 0; |
} |
#endif |
/tags/V2.12a/sbus.h |
---|
0,0 → 1,11 |
#ifndef _SBUS_H |
#define _SBUS_H |
#if (defined(__AVR_ATmega1284__) || defined(__AVR_ATmega1284P__)) |
extern unsigned char NewSBusData, sBusBuffer[25]; |
extern void SbusParser(unsigned char); |
extern void SbusUartInit(void); |
extern void ProcessSBus(void); |
#endif |
#endif |
/tags/V2.12a/spi.c |
---|
0,0 → 1,454 |
// ######################## SPI - FlightCtrl ################### |
#include "main.h" |
#include "eeprom.h" |
#include "uart.h" |
//struct str_ToNaviCtrl_Version ToNaviCtrl_Version; |
//struct str_FromNaviCtrl_Version FromNaviCtrl_Version; |
struct str_ToNaviCtrl ToNaviCtrl; |
struct str_FromNaviCtrl FromNaviCtrl; |
struct str_FromNaviCtrl_Value FromNaviCtrl_Value; |
struct str_SPI_VersionInfo NC_Version; |
struct str_GPSInfo GPSInfo; |
unsigned char SPI_BufferIndex; |
unsigned char SPI_RxBufferIndex; |
signed char FromNC_Rotate_C = 32, FromNC_Rotate_S = 0; |
signed char FromNC_WP_EventChannel_New = 0; |
volatile unsigned char SPI_Buffer[sizeof(FromNaviCtrl)]; |
unsigned char *SPI_TX_Buffer; |
unsigned char SPITransferCompleted, SPI_ChkSum; |
unsigned char SPI_RxDataValid,NaviDataOkay = 250; |
unsigned char SPI_CommandSequence[] = { SPI_FCCMD_STICK, SPI_FCCMD_USER, SPI_FCCMD_SLOW,SPI_FCCMD_BL_ACCU, |
SPI_FCCMD_STICK, SPI_FCCMD_MISC, SPI_FCCMD_BL_ACCU, |
SPI_FCCMD_STICK, SPI_FCCMD_USER, SPI_FCCMD_BL_ACCU, |
SPI_FCCMD_STICK, SPI_FCCMD_PARAMETER2, SPI_FCCMD_BL_ACCU |
}; |
unsigned char SPI_CommandCounter = 0; |
unsigned char NC_ErrorCode = 0; |
unsigned char NC_GPS_ModeCharacter = ' '; |
unsigned char EarthMagneticField = 0; |
unsigned char EarthMagneticInclination = 0, EarthMagneticInclinationTheoretic = 0; |
unsigned char NC_To_FC_Flags = 0; |
unsigned char NCForcesNewDirection = 0; // allows Yawing without CareFree (Yawing at Coming Home) |
//unsigned char NC_To_FC_MaxAltitude = 0; // this is a Parameter on the SD-card |
signed int POI_KameraNick = 0; // in 0,1° |
vector16_t MagVec = {0,0,0}; |
#ifdef USE_SPI_COMMUNICATION |
//------------------------------------------------------ |
void SPI_MasterInit(void) |
{ |
DDR_SPI |= (1<<DD_MOSI)|(1<<DD_SCK); // Set MOSI and SCK output, all others input |
SLAVE_SELECT_DDR_PORT |= (1 << SPI_SLAVE_SELECT); |
SPCR = (1<<SPE)|(1<<MSTR)|(1<<SPR1)|(0<<SPR0)|(0<<SPIE); // Enable SPI, Master, set clock rate fck/64 |
SPSR = 0;//(1<<SPI2X); |
SLAVE_SELECT_PORT |= (1 << SPI_SLAVE_SELECT); |
SPITransferCompleted = 1; |
//SPDR = 0x00; // dummy write |
ToNaviCtrl.Sync1 = 0xAA; |
ToNaviCtrl.Sync2 = 0x83; |
ToNaviCtrl.Command = SPI_FCCMD_USER; |
ToNaviCtrl.IntegralNick = 0; |
ToNaviCtrl.IntegralRoll = 0; |
FromNaviCtrl_Value.SerialDataOkay = 0; |
SPI_RxDataValid = 0; |
} |
//------------------------------------------------------ |
unsigned char SPI_StartTransmitPacket(void) |
{ |
if(!SPITransferCompleted) return(0); |
SLAVE_SELECT_PORT &= ~(1 << SPI_SLAVE_SELECT); // SelectSlave |
SPI_TX_Buffer = (unsigned char *) &ToNaviCtrl; |
ToNaviCtrl.Command = SPI_CommandSequence[SPI_CommandCounter++]; |
if (SPI_CommandCounter >= sizeof(SPI_CommandSequence)) SPI_CommandCounter = 0; |
SPITransferCompleted = 0; |
UpdateSPI_Buffer(); // update buffer |
SPI_BufferIndex = 1; |
ToNaviCtrl.Chksum = ToNaviCtrl.Sync1; |
SPDR = ToNaviCtrl.Sync1; // Start transmission |
return(1); |
} |
//------------------------------------------------------ |
//SIaNAL(SIG_SPI) |
void SPI_TransmitByte(void) |
{ |
static unsigned char SPI_RXState = 0; |
unsigned char rxdata; |
static unsigned char rxchksum; |
if (SPITransferCompleted) return; |
if (!(SPSR & (1 << SPIF))) return; |
BytegapSPI = SPI_BYTEGAP; |
// _delay_us(30); |
SLAVE_SELECT_PORT |= (1 << SPI_SLAVE_SELECT); // DeselectSlave |
rxdata = SPDR; |
switch ( SPI_RXState) |
{ |
case 0: |
SPI_RxBufferIndex = 0; |
rxchksum = rxdata; |
if (rxdata == 0x81 ) { SPI_RXState = 1; } // 1. Syncbyte ok |
break; |
case 1: |
if (rxdata == 0x55) { rxchksum += rxdata; SPI_RXState = 2; } // 2. Syncbyte ok |
else SPI_RXState = 0; |
break; |
case 2: |
SPI_Buffer[SPI_RxBufferIndex++]= rxdata; // get data |
//DebugOut.Analog[19]++; |
if (SPI_RxBufferIndex >= sizeof(FromNaviCtrl)) |
{ |
if (rxdata == rxchksum) |
{ |
unsigned char *ptr = (unsigned char *)&FromNaviCtrl; |
memcpy(ptr, (unsigned char *) SPI_Buffer, sizeof(SPI_Buffer)); |
SPI_RxDataValid = 1; |
} |
else |
{ |
SPI_RxDataValid = 0; |
} |
SPI_RXState = 0; |
} |
else rxchksum += rxdata; |
break; |
} |
if (SPI_BufferIndex < sizeof(ToNaviCtrl)) |
{ |
SLAVE_SELECT_PORT &= ~(1 << SPI_SLAVE_SELECT); // SelectSlave |
asm volatile ("nop"); asm volatile ("nop"); asm volatile ("nop"); asm volatile ("nop"); |
SPDR = SPI_TX_Buffer[SPI_BufferIndex]; |
ToNaviCtrl.Chksum += SPI_TX_Buffer[SPI_BufferIndex]; |
} |
else SPITransferCompleted = 1; |
SPI_BufferIndex++; |
} |
//------------------------------------------------------ |
void UpdateSPI_Buffer(void) |
{ |
// signed int tmp; |
static unsigned char motorindex, oldcommand = SPI_NCCMD_VERSION, slow_command = 0; |
ToNaviCtrl.IntegralNick = (int) (IntegralNick / (long)(EE_Parameter.GyroAccFaktor * 4)); // etwa in 0.1 Grad |
ToNaviCtrl.IntegralRoll = (int) (IntegralRoll / (long)(EE_Parameter.GyroAccFaktor * 4)); // etwa in 0.1 Grad |
ToNaviCtrl.GyroCompass = (10 * ErsatzKompass) / GIER_GRAD_FAKTOR; |
ToNaviCtrl.GyroGier = (signed int) AdNeutralGier - AdWertGier; |
ToNaviCtrl.AccNick = ((int) ACC_AMPLIFY * (NaviAccNick / NaviCntAcc))/4; |
ToNaviCtrl.AccRoll = ((int) ACC_AMPLIFY * (NaviAccRoll / NaviCntAcc))/4; |
NaviCntAcc = 0; NaviAccNick = 0; NaviAccRoll = 0; |
// ToNaviCtrl.User8 = Parameter_UserParam8; |
// ToNaviCtrl.CalState = WinkelOut.CalcState; |
switch(ToNaviCtrl.Command) // |
{ |
case SPI_FCCMD_USER: |
ToNaviCtrl.Param.Byte[0] = Parameter_UserParam1; |
ToNaviCtrl.Param.Byte[1] = Parameter_UserParam2; |
ToNaviCtrl.Param.Byte[2] = Parameter_UserParam3; |
ToNaviCtrl.Param.Byte[3] = Parameter_UserParam4; |
ToNaviCtrl.Param.Byte[4] = Parameter_UserParam5; |
ToNaviCtrl.Param.Byte[5] = Parameter_UserParam6; |
ToNaviCtrl.Param.Byte[6] = Parameter_UserParam7; |
ToNaviCtrl.Param.Byte[7] = Parameter_UserParam8; |
ToNaviCtrl.Param.Byte[8] = FC_StatusFlags; |
ToNaviCtrl.Param.Byte[9] = FC_StatusFlags2; |
//if(FC_StatusFlags2 & FC_STATUS2_WAIT_FOR_TAKEOFF) ToNaviCtrl.Param.Byte[8] &= ~FC_STATUS_FLY; |
FC_StatusFlags &= ~(FC_STATUS_CALIBRATE | FC_STATUS_START); |
ToNaviCtrl.Param.Int[5] = UBat; // 10 & 11 |
if(!(PORTC & (1<<PORTC2))) FC_StatusFlags2 &= ~FC_STATUS2_OUT1_ACTIVE; // Out1 (J16) |
break; |
case SPI_FCCMD_BL_ACCU: |
ToNaviCtrl.Param.Int[0] = Capacity.ActualCurrent; // 0.1A |
ToNaviCtrl.Param.Byte[2] = motorindex | Out1ChangedFlag; // 0x80 this Flag marks a changed Out1 |
ToNaviCtrl.Param.Byte[3] = Capacity.MinOfMaxPWM; |
ToNaviCtrl.Param.Byte[4] = GetChannelValue(EE_Parameter.NaviGpsModeChannel); // GPS-Mode control |
ToNaviCtrl.Param.Byte[5] = VarioCharacter; |
ToNaviCtrl.Param.Byte[6] = Motor[motorindex].NotReadyCnt; |
ToNaviCtrl.Param.Byte[7] = Motor[motorindex].Version; |
ToNaviCtrl.Param.Byte[8] = Motor[motorindex].MaxPWM; |
ToNaviCtrl.Param.Byte[9] = Motor[motorindex].State; |
ToNaviCtrl.Param.Byte[10] = Motor[motorindex].Temperature; |
ToNaviCtrl.Param.Byte[11] = Motor[motorindex].Current; |
if(Mixer.Motor[++motorindex][0] <= 0) // next motor is not used ? |
while(Mixer.Motor[motorindex][0] <= 0 && motorindex) motorindex = (motorindex + 1) % 13; |
Out1ChangedFlag = 0; |
break; |
case SPI_FCCMD_SLOW: |
switch(slow_command) |
{ |
case 0: |
ToNaviCtrl.Command = SPI_FCCMD_VERSION; |
ToNaviCtrl.Param.Byte[0] = VERSION_MAJOR; |
ToNaviCtrl.Param.Byte[1] = VERSION_MINOR; |
ToNaviCtrl.Param.Byte[2] = VERSION_PATCH; |
ToNaviCtrl.Param.Byte[3] = NC_SPI_COMPATIBLE; |
ToNaviCtrl.Param.Byte[4] = PlatinenVersion; |
ToNaviCtrl.Param.Byte[5] = EE_Parameter.LandingSpeed; |
ToNaviCtrl.Param.Byte[6] = EE_Parameter.ComingHomeAltitude; |
ToNaviCtrl.Param.Byte[7] = EE_Parameter.AutoPhotoAtitudes; |
ToNaviCtrl.Param.Byte[8] = VersionInfo.BL_Firmware; |
ToNaviCtrl.Param.Byte[9] = ActiveParamSet; |
ToNaviCtrl.Param.Int[5] = FlugMinutenGesamt; // 10 & 11 |
slow_command++; |
break; |
case 1: |
ToNaviCtrl.Command = SPI_FCCMD_PARAMETER1; |
ToNaviCtrl.Param.Byte[0] = (unsigned char) BattLowVoltageWarning; //0.1V |
ToNaviCtrl.Param.Byte[1] = EE_Parameter.NaviGpsGain; // Parameters for the Naviboard |
ToNaviCtrl.Param.Byte[2] = EE_Parameter.NaviGpsP; |
ToNaviCtrl.Param.Byte[3] = EE_Parameter.NaviGpsI; |
ToNaviCtrl.Param.Byte[4] = EE_Parameter.NaviGpsD; |
ToNaviCtrl.Param.Byte[5] = EE_Parameter.NaviGpsA; |
ToNaviCtrl.Param.Byte[6] = EE_Parameter.NaviGpsMinSat; |
ToNaviCtrl.Param.Byte[7] = EE_Parameter.NaviStickThreshold; |
ToNaviCtrl.Param.Byte[8] = EE_Parameter.NaviMaxFlyingRange; |
ToNaviCtrl.Param.Byte[9] = EE_Parameter.NaviWindCorrection; |
ToNaviCtrl.Param.Byte[10] = EE_Parameter.NaviAccCompensation; |
ToNaviCtrl.Param.Byte[11] = EE_Parameter.NaviAngleLimitation; |
slow_command++; |
break; |
case 2: |
ToNaviCtrl.Command = SPI_FCCMD_SLOW2; |
ToNaviCtrl.Param.Int[0] = BoatNeutralNick; // 0 & 1 |
ToNaviCtrl.Param.Int[1] = BoatNeutralRoll; // 2 & 3 |
ToNaviCtrl.Param.Int[2] = BoatNeutralGier; // 4 & 5 |
ToNaviCtrl.Param.Byte[6] = EE_Parameter.CamOrientation; |
ToNaviCtrl.Param.Byte[7] = EE_Parameter.CompassOffset; |
ToNaviCtrl.Param.Byte[8] = Parameter_GlobalConfig; |
ToNaviCtrl.Param.Byte[9] = Parameter_ExtraConfig; |
ToNaviCtrl.Param.Byte[10] = EE_Parameter.OrientationAngle; |
ToNaviCtrl.Param.Byte[11] = EE_Parameter.GlobalConfig3; |
slow_command++; |
break; |
case 3: |
ToNaviCtrl.Command = SPI_FCCMD_SLOW3; |
ToNaviCtrl.Param.Byte[0] = Parameter_ServoNickControl; |
ToNaviCtrl.Param.Byte[1] = Parameter_ServoRollControl; |
ToNaviCtrl.Param.Byte[2] = EE_Parameter.NaviDescendRange; // in 10m |
ToNaviCtrl.Param.Byte[3] = Parameter_MaximumAltitude; |
ToNaviCtrl.Param.Byte[4] = EE_Parameter.ServoCompInvert; |
ToNaviCtrl.Param.Byte[5] = LipoCells; |
ToNaviCtrl.Param.Int[3] = ShutterCounter; // 6 & 7 |
ToNaviCtrl.Param.Byte[8] = LowVoltageLandingActive; |
ToNaviCtrl.Param.Byte[9] = EE_Parameter.FailSafeTime; |
ToNaviCtrl.Param.Byte[10] = 0; |
ToNaviCtrl.Param.Byte[11] = 0; |
slow_command++; |
break; |
default: |
ToNaviCtrl.Command = SPI_FCCMD_NEUTRAL; |
ToNaviCtrl.Param.Int[0] = AdNeutralNick; // 0 & 1 |
ToNaviCtrl.Param.Int[1] = AdNeutralRoll; // 2 & 3 |
ToNaviCtrl.Param.Int[2] = AdNeutralGier; // 4 & 5 |
ToNaviCtrl.Param.Byte[6] = EE_Parameter.Driftkomp; |
ToNaviCtrl.Param.Byte[7] = EE_Parameter.NaviPH_LoginTime; |
ToNaviCtrl.Param.Byte[8] = EE_Parameter.Receiver; |
ToNaviCtrl.Param.Byte[9] = EE_Parameter.NaviGpsPLimit; |
ToNaviCtrl.Param.Byte[10] = EE_Parameter.NaviGpsILimit; |
ToNaviCtrl.Param.Byte[11] = EE_Parameter.NaviGpsDLimit; |
slow_command = 0; |
break; |
} |
break; |
case SPI_FCCMD_PARAMETER2: |
ToNaviCtrl.Param.Byte[0] = EE_Parameter.AutoPhotoDistance; // Distance between Photo releases |
#if (defined(__AVR_ATmega1284__) || defined(__AVR_ATmega1284P__)) |
// create the ToNC_SpeakHoTT |
if(EE_Parameter.Receiver != RECEIVER_HOTT) |
{ |
if(JetiBeep != 'B') JetiBeep = pgm_read_byte(&JETI_CODE[HoTT_Waring()]); |
else HoTT_Waring(); |
} |
ToNaviCtrl.Param.Byte[1] = ToNC_SpeakHoTT; |
#else |
ToNaviCtrl.Param.Byte[1] = 0; |
#endif |
ToNaviCtrl.Param.Int[1] = Capacity.UsedCapacity; // mAh // 2 & 3 |
ToNaviCtrl.Param.Byte[4] = LowVoltageHomeActive; |
ToNaviCtrl.Param.Byte[5] = ToNC_Load_WP_List; |
ToNaviCtrl.Param.Byte[6] = ToNC_Load_SingePoint; |
ToNaviCtrl.Param.Byte[7] = ToNC_Store_SingePoint; |
ToNC_Load_WP_List = 0; |
ToNC_Load_SingePoint = 0; |
ToNC_Store_SingePoint = 0; |
if(Parameter_KompassWirkung) ToNaviCtrl.Param.sInt[4] = KompassSollWert; // Pos. 8 & 9 |
else ToNaviCtrl.Param.sInt[4] = ErsatzKompassInGrad; // answer with the compass value if the Compass effect is zero |
ToNaviCtrl.Param.Byte[10] = FC_StatusFlags3; |
ToNaviCtrl.Param.Byte[11] = EE_Parameter.SingleWpSpeed; |
break; |
case SPI_FCCMD_STICK: |
/* |
cli(); |
tmp = PPM_in[EE_Parameter.Kanalbelegung[K_GAS]]; if(tmp > 127) tmp = 127; else if(tmp < -127) tmp = -127; |
ToNaviCtrl.Param.Byte[0] = (char) tmp; |
tmp = PPM_in[EE_Parameter.Kanalbelegung[K_GIER]]; if(tmp > 127) tmp = 127; else if(tmp < -127) tmp = -127; |
ToNaviCtrl.Param.Byte[1] = (char) tmp; |
tmp = PPM_in[EE_Parameter.Kanalbelegung[K_ROLL]]; if(tmp > 127) tmp = 127; else if(tmp < -127) tmp = -127; |
ToNaviCtrl.Param.Byte[2] = (char) tmp; |
tmp = PPM_in[EE_Parameter.Kanalbelegung[K_NICK]]; if(tmp > 127) tmp = 127; else if(tmp < -127) tmp = -127; |
sei(); |
ToNaviCtrl.Param.Byte[3] = (char) tmp; |
*/ |
ToNaviCtrl.Param.Byte[0] = ChannelGas; |
ToNaviCtrl.Param.Byte[1] = ChannelYaw; |
ToNaviCtrl.Param.Byte[2] = ChannelRoll; |
ToNaviCtrl.Param.Byte[3] = ChannelNick; |
ToNaviCtrl.Param.Byte[4] = (unsigned char) Poti[0]; |
ToNaviCtrl.Param.Byte[5] = (unsigned char) Poti[1]; |
ToNaviCtrl.Param.Byte[6] = (unsigned char) Poti[2]; |
ToNaviCtrl.Param.Byte[7] = (unsigned char) Poti[3]; |
ToNaviCtrl.Param.Byte[8] = (unsigned char) Poti[4]; |
ToNaviCtrl.Param.Byte[9] = (unsigned char) Poti[5]; |
ToNaviCtrl.Param.Byte[10] = (unsigned char) Poti[6]; |
ToNaviCtrl.Param.Byte[11] = (unsigned char) Poti[7]; |
break; |
case SPI_FCCMD_MISC: |
if(WinkelOut.CalcState >= 5) |
{ |
WinkelOut.CalcState = 0; |
ToNaviCtrl.Param.Byte[0] = 5; |
} |
else ToNaviCtrl.Param.Byte[0] = WinkelOut.CalcState; |
ToNaviCtrl.Param.Byte[1] = HoverGas / 4; |
ToNaviCtrl.Param.Int[1] = (int)(HoehenWert/5); //2 & 3 |
ToNaviCtrl.Param.Int[2] = (int)(SollHoehe/5); //4 & 5 |
ToNaviCtrl.Param.Byte[6] = VersionInfo.HardwareError[0]; |
ToNaviCtrl.Param.Byte[7] = VersionInfo.HardwareError[1]; |
VersionInfo.HardwareError[0] &= ~FC_ERROR0_CAREFREE; // VersionInfo.HardwareError[0] = 0; |
VersionInfo.HardwareError[1] &= FC_ERROR1_MIXER; |
ToNaviCtrl.Param.Byte[8] = DebugOut.Analog[28]; // I2C-Error counter |
ToNaviCtrl.Param.Byte[9] = (unsigned char) SenderOkay; |
ToNaviCtrl.Param.Byte[10] = NC_Wait_for_LED; |
ToNaviCtrl.Param.Byte[11] = DebugOut.Analog[7] / 4; //GasMischanteil |
break; |
} |
if(SPI_RxDataValid) |
{ |
if(FromNaviCtrl.Command != oldcommand) NaviDataOkay = 250; |
oldcommand = FromNaviCtrl.Command; |
CalculateCompassTimer = 1; |
if(abs(FromNaviCtrl.GPS_Nick) < 512 && abs(FromNaviCtrl.GPS_Roll) < 512 && (EE_Parameter.GlobalConfig & CFG_GPS_AKTIV)) |
{ |
GPS_Nick = FromNaviCtrl.GPS_Nick; |
GPS_Roll = FromNaviCtrl.GPS_Roll; |
} |
// update compass readings |
// MagVec.x = FromNaviCtrl.MagVecX; |
// MagVec.y = FromNaviCtrl.MagVecY; |
// MagVec.z = FromNaviCtrl.MagVecZ; |
if(FromNaviCtrl.CompassValue <= 360) KompassValue = FromNaviCtrl.CompassValue; |
if(FromNaviCtrl.BeepTime > beeptime && !DisableRcOffBeeping) beeptime = FromNaviCtrl.BeepTime; |
switch (FromNaviCtrl.Command) |
{ |
case SPI_NCCMD_KALMAN: |
FromNaviCtrl_Value.Kalman_K = FromNaviCtrl.Param.sByte[0]; |
FromNaviCtrl_Value.Kalman_MaxFusion = FromNaviCtrl.Param.sByte[1]; |
FromNaviCtrl_Value.Kalman_MaxDrift = FromNaviCtrl.Param.sByte[2]; |
KompassFusion = FromNaviCtrl.Param.sByte[3]; |
if(FromNaviCtrl.Param.Byte[4] & 0x01) NCForcesNewDirection = 1; |
FromNC_Rotate_C = FromNaviCtrl.Param.Byte[5]; |
FromNC_Rotate_S = FromNaviCtrl.Param.Byte[6]; |
GPS_Aid_StickMultiplikator = FromNaviCtrl.Param.Byte[7]; |
if(FromNaviCtrl.Param.sInt[4] >= 0) |
{ |
NC_CompassSetpoint = FromNaviCtrl.Param.sInt[4]; // bei Carefree kann NC den Kompass-Sollwinkel vorgeben |
} |
POI_KameraNick = (POI_KameraNick + FromNaviCtrl.Param.sInt[5]) / 2; // FromNaviCtrl.Param.sInt[5]; // Nickwinkel |
break; |
case SPI_NCCMD_VERSION: |
NC_Version.Major = FromNaviCtrl.Param.Byte[0]; |
NC_Version.Minor = FromNaviCtrl.Param.Byte[1]; |
NC_Version.Patch = FromNaviCtrl.Param.Byte[2]; |
NC_Version.Compatible = FromNaviCtrl.Param.Byte[3]; |
NC_Version.Hardware = FromNaviCtrl.Param.Byte[4]; |
DebugOut.Status[0] |= FromNaviCtrl.Param.Byte[5]; |
DebugOut.Status[1] = (DebugOut.Status[1] & (0x01|0x02)) | (FromNaviCtrl.Param.Byte[6] & (0x04 | 0x08)); |
NC_ErrorCode = FromNaviCtrl.Param.Byte[7]; |
NC_GPS_ModeCharacter = FromNaviCtrl.Param.Byte[8]; |
FromNaviCtrl_Value.SerialDataOkay = FromNaviCtrl.Param.Byte[9]; |
NC_To_FC_Flags = FromNaviCtrl.Param.Byte[10]; |
//NC_To_FC_MaxAltitude = FromNaviCtrl.Param.Byte[11]; |
break; |
case SPI_NCCMD_GPSINFO: |
GPSInfo.Flags = FromNaviCtrl.Param.Byte[0]; |
GPSInfo.NumOfSats = FromNaviCtrl.Param.Byte[1]; |
GPSInfo.SatFix = FromNaviCtrl.Param.Byte[2]; |
GPSInfo.Speed = FromNaviCtrl.Param.Byte[3]; |
GPSInfo.HomeDistance = FromNaviCtrl.Param.Int[2]; |
GPSInfo.HomeBearing = FromNaviCtrl.Param.sInt[3]; |
if(!FromNC_WP_EventChannel_New) FromNC_WP_EventChannel_New = (unsigned char) FromNaviCtrl.Param.Byte[8] + 127; // zwischenspeichern, damit keiner verpasst wird |
PPM_in[WP_EVENT_PPM_IN] = (signed char) FromNaviCtrl.Param.Byte[8]; // WP_EVENT-Channel-Value (FromNC_WP_EventChannel) |
FromNC_AltitudeSpeed = FromNaviCtrl.Param.Byte[9]; |
FromNC_AltitudeSetpoint = (long) FromNaviCtrl.Param.sInt[5] * 10; // in cm |
break; |
case SPI_MISC: |
EarthMagneticField = FromNaviCtrl.Param.Byte[0]; |
EarthMagneticInclination = FromNaviCtrl.Param.Byte[1]; |
EarthMagneticInclinationTheoretic = FromNaviCtrl.Param.Byte[2]; |
#if (defined(__AVR_ATmega1284__) || defined(__AVR_ATmega1284P__)) |
if(FromNaviCtrl.Param.Byte[3]) |
if(!SpeakHoTT || (SpeakHoTT >= SPEAK_GPS_HOLD && SpeakHoTT <= SPEAK_GPS_OFF)) SpeakHoTT = FromNaviCtrl.Param.Byte[3]; |
NaviData_TargetDistance = FromNaviCtrl.Param.Int[3]; |
#endif |
NaviData_WaypointIndex = FromNaviCtrl.Param.Byte[4]; |
NaviData_WaypointNumber = FromNaviCtrl.Param.Byte[5]; |
NaviData_TargetHoldTime = FromNaviCtrl.Param.Byte[8]; |
NaviData_MaxWpListIndex = FromNaviCtrl.Param.Byte[9]; |
CompassCorrected = FromNaviCtrl.Param.sInt[5]; // Bytes 10 & 11 |
break; |
#if (defined(__AVR_ATmega1284__) || defined(__AVR_ATmega1284P__)) |
case SPI_NCCMD_HOTT_DATA: |
//if(EE_Parameter.Receiver == RECEIVER_HOTT) |
NC_Fills_HoTT_Telemety(); |
break; |
#endif |
// 0 = 0,1 |
// 1 = 2,3 |
// 2 = 4,5 |
// 3 = 6,7 |
// 4 = 8,9 |
// 5 = 10,11 |
default: |
break; |
} |
} |
else |
{ |
// KompassValue = 0; |
// KompassRichtung = 0; |
GPS_Nick = 0; |
GPS_Roll = 0; |
} |
} |
#endif |
/tags/V2.12a/spi.h |
---|
0,0 → 1,202 |
// ######################## SPI - FlightCtrl ################### |
#ifndef _SPI_H |
#define _SPI_H |
#include <util/delay.h> |
#include "vector.h" |
#define USE_SPI_COMMUNICATION |
#define SPI_BYTEGAP 5 |
//----------------------------------------- |
#define DDR_SPI DDRB |
#define SLAVE_SELECT_DDR_PORT DDRC |
#define SLAVE_SELECT_PORT PORTC |
#if defined(__AVR_ATmega1284P__) |
#define DD_SS PORTB4 |
#define DD_SCK PORTB7 |
#define DD_MOSI PORTB5 |
#define DD_MISO PORTB6 |
#define SPI_SLAVE_SELECT PORTC5 |
#else |
#define DD_SS PB4 |
#define DD_SCK PB7 |
#define DD_MOSI PB5 |
#define DD_MISO PB6 |
#define SPI_SLAVE_SELECT PC5 |
#endif |
// for compatibility reasons gcc3.x <-> gcc4.x |
#ifndef SPCR |
#define SPCR SPCR0 |
#endif |
#ifndef SPE |
#define SPE SPE0 |
#endif |
#ifndef MSTR |
#define MSTR MSTR0 |
#endif |
#ifndef SPR1 |
#define SPR1 SPR01 |
#endif |
#ifndef SPR0 |
#define SPR0 SPR00 |
#endif |
#ifndef SPIE |
#define SPIE SPIE0 |
#endif |
#ifndef SPDR |
#define SPDR SPDR0 |
#endif |
#ifndef SPIF |
#define SPIF SPIF0 |
#endif |
#ifndef SPSR |
#define SPSR SPSR0 |
#endif |
// ------------------------- |
#define SPI_FCCMD_USER 10 |
#define SPI_FCCMD_STICK 11 |
#define SPI_FCCMD_MISC 12 |
#define SPI_FCCMD_PARAMETER1 13 |
#define SPI_FCCMD_VERSION 14 |
#define SPI_FCCMD_SLOW3 15 |
#define SPI_FCCMD_BL_ACCU 16 |
#define SPI_FCCMD_PARAMETER2 17 |
#define SPI_FCCMD_NEUTRAL 18 |
#define SPI_FCCMD_SLOW 19 |
#define SPI_FCCMD_SLOW2 20 |
struct str_ToNaviCtrl |
{ |
unsigned char Sync1, Sync2; |
unsigned char Command; |
signed int IntegralNick; |
signed int IntegralRoll; |
signed int AccNick; |
signed int AccRoll; |
signed int GyroCompass; |
signed int GyroNick; |
signed int GyroRoll; |
signed int GyroGier; |
unsigned int FCStatus; |
union |
{ |
unsigned char Byte[12]; |
char sByte[12]; |
unsigned int Int[6]; |
int sInt[6]; |
unsigned long Long[3]; |
long sLong[3]; |
float Float[3]; |
} Param; |
unsigned char Chksum; |
}; |
#define SPI_NCCMD_KALMAN 103 |
#define SPI_NCCMD_VERSION 104 |
#define SPI_NCCMD_GPSINFO 105 |
#define SPI_NCCMD_HOTT_DATA 106 |
#define SPI_MISC 107 |
struct str_FromNaviCtrl |
{ |
unsigned char Command; |
signed int GPS_Nick; |
signed int GPS_Roll; |
signed int MagVecX; |
signed int CompassValue; |
signed int AccErrorN; |
signed int AccErrorR; |
signed int MagVecY; |
signed int MagVecZ; |
unsigned int BeepTime; |
union |
{ |
unsigned char Byte[12]; |
char sByte[12]; |
unsigned int Int[6]; |
int sInt[6]; |
unsigned long Long[3]; |
long sLong[3]; |
float Float[3]; |
} Param; |
unsigned char Chksum; |
}; |
struct str_FromNaviCtrl_Value |
{ |
signed char Kalman_K; |
signed char Kalman_MaxDrift; |
signed char Kalman_MaxFusion; |
unsigned char SerialDataOkay; |
signed char reserve; |
}; |
struct str_SPI_VersionInfo |
{ |
unsigned char Major; |
unsigned char Minor; |
unsigned char Patch; |
unsigned char Compatible; |
unsigned char Hardware; |
}; |
// Satfix types for GPSData.SatFix |
#define SATFIX_NONE 0x00 |
#define SATFIX_DEADRECKOING 0x01 |
#define SATFIX_2D 0x02 |
#define SATFIX_3D 0x03 |
#define SATFIX_GPS_DEADRECKOING 0x04 |
#define SATFIX_TIMEONLY 0x05 |
// Flags for interpretation of the GPSData.Flags |
#define FLAG_GPSFIXOK 0x01 // (i.e. within DOP & ACC Masks) |
#define FLAG_DIFFSOLN 0x02 // (is DGPS used) |
#define FLAG_WKNSET 0x04 // (is Week Number valid) |
#define FLAG_TOWSET 0x08 // (is Time of Week valid) |
#define FLAG_GPS_NAVIGATION_ACTIVE 0x10 // NC to FC -> NC is ready to navigate |
struct str_GPSInfo |
{ |
unsigned char Flags; // Status Flags |
unsigned char NumOfSats; // number of satelites |
unsigned char SatFix; // type of satfix |
unsigned char Speed; // m/sek |
unsigned int HomeDistance; // distance to Home in dm |
int HomeBearing; // bearing to home in deg |
}; |
#ifdef USE_SPI_COMMUNICATION |
extern struct str_GPSInfo GPSInfo; |
extern struct str_SPI_VersionInfo NC_Version; |
extern struct str_FromNaviCtrl_Value FromNaviCtrl_Value; |
extern struct str_ToNaviCtrl ToNaviCtrl; |
extern struct str_FromNaviCtrl FromNaviCtrl; |
extern unsigned char SPI_CommandCounter,NaviDataOkay; |
extern signed char FromNC_Rotate_C, FromNC_Rotate_S; |
extern unsigned char NC_ErrorCode; |
extern void SPI_MasterInit(void); |
extern unsigned char SPI_StartTransmitPacket(void); |
extern void UpdateSPI_Buffer(void); |
extern void SPI_TransmitByte(void); |
extern signed int POI_KameraNick; |
extern unsigned char NC_GPS_ModeCharacter, NC_To_FC_Flags, NC_To_FC_MaxAltitude; |
extern vector16_t MagVec; |
extern unsigned char EarthMagneticField; |
extern unsigned char EarthMagneticInclination,EarthMagneticInclinationTheoretic; |
extern signed char FromNC_WP_EventChannel_New; |
extern unsigned char NCForcesNewDirection; // allows Yawing without CareFree (Yawing at Coming Home) |
#else |
// -------------------------------- Dummy ----------------------------------------- |
#define SPI_MasterInit() ; |
//#define SPI_StartTransmitPacket() ; |
#define UpdateSPI_Buffer() ; |
#define SPI_TransmitByte() ; |
#endif |
#endif |
/tags/V2.12a/timer0.c |
---|
0,0 → 1,493 |
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
// + www.MikroKopter.com |
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
// + Software Nutzungsbedingungen (english version: see below) |
// + der Fa. HiSystems GmbH, Flachsmeerstrasse 2, 26802 Moormerland - nachfolgend Lizenzgeber genannt - |
// + Der Lizenzgeber räumt dem Kunden ein nicht-ausschließliches, zeitlich und räumlich* unbeschränktes Recht ein, die im den |
// + Mikrocontroller verwendete Firmware für die Hardware Flight-Ctrl, Navi-Ctrl, BL-Ctrl, MK3Mag & PC-Programm MikroKopter-Tool |
// + - nachfolgend Software genannt - nur für private Zwecke zu nutzen. |
// + Der Einsatz dieser Software ist nur auf oder mit Produkten des Lizenzgebers zulässig. |
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
// + Die vom Lizenzgeber gelieferte Software ist urheberrechtlich geschützt. Alle Rechte an der Software sowie an sonstigen im |
// + Rahmen der Vertragsanbahnung und Vertragsdurchführung überlassenen Unterlagen stehen im Verhältnis der Vertragspartner ausschließlich dem Lizenzgeber zu. |
// + Die in der Software enthaltenen Copyright-Vermerke, Markenzeichen, andere Rechtsvorbehalte, Seriennummern sowie |
// + sonstige der Programmidentifikation dienenden Merkmale dürfen vom Kunden nicht verändert oder unkenntlich gemacht werden. |
// + Der Kunde trifft angemessene Vorkehrungen für den sicheren Einsatz der Software. Er wird die Software gründlich auf deren |
// + Verwendbarkeit zu dem von ihm beabsichtigten Zweck testen, bevor er diese operativ einsetzt. |
// + Die Haftung des Lizenzgebers wird - soweit gesetzlich zulässig - begrenzt in Höhe des typischen und vorhersehbaren |
// + Schadens. Die gesetzliche Haftung bei Personenschäden und nach dem Produkthaftungsgesetz bleibt unberührt. Dem Lizenzgeber steht jedoch der Einwand |
// + des Mitverschuldens offen. |
// + Der Kunde trifft angemessene Vorkehrungen für den Fall, dass die Software ganz oder teilweise nicht ordnungsgemäß arbeitet. |
// + Er wird die Software gründlich auf deren Verwendbarkeit zu dem von ihm beabsichtigten Zweck testen, bevor er diese operativ einsetzt. |
// + Der Kunde wird er seine Daten vor Einsatz der Software nach dem Stand der Technik sichern. |
// + Der Kunde ist darüber unterrichtet, dass der Lizenzgeber seine Daten im zur Vertragsdurchführung erforderlichen Umfang |
// + und auf Grundlage der Datenschutzvorschriften erhebt, speichert, verarbeitet und, sofern notwendig, an Dritte übermittelt. |
// + *) Die räumliche Nutzung bezieht sich nur auf den Einsatzort, nicht auf die Reichweite der programmierten Software. |
// + #### ENDE DER NUTZUNGSBEDINGUNGEN ####' |
// + Hinweis: Informationen über erweiterte Nutzungsrechte (wie z.B. Nutzung für nicht-private Zwecke) sind auf Anfrage per Email an info(@)hisystems.de verfügbar. |
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
// + Software LICENSING TERMS |
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
// + of HiSystems GmbH, Flachsmeerstrasse 2, 26802 Moormerland, Germany - the Licensor - |
// + The Licensor grants the customer a non-exclusive license to use the microcontroller firmware of the Flight-Ctrl, Navi-Ctrl, BL-Ctrl, and MK3Mag hardware |
// + (the Software) exclusively for private purposes. The License is unrestricted with respect to time and territory*. |
// + The Software may only be used with the Licensor's products. |
// + The Software provided by the Licensor is protected by copyright. With respect to the relationship between the parties to this |
// + agreement, all rights pertaining to the Software and other documents provided during the preparation and execution of this |
// + agreement shall be the property of the Licensor. |
// + The information contained in the Software copyright notices, trademarks, other legal reservations, serial numbers and other |
// + features that can be used to identify the program may not be altered or defaced by the customer. |
// + The customer shall be responsible for taking reasonable precautions |
// + for the safe use of the Software. The customer shall test the Software thoroughly regarding its suitability for the |
// + intended purpose before implementing it for actual operation. The Licensor's liability shall be limited to the extent of typical and |
// + foreseeable damage to the extent permitted by law, notwithstanding statutory liability for bodily injury and product |
// + liability. However, the Licensor shall be entitled to the defense of contributory negligence. |
// + The customer will take adequate precautions in the case, that the software is not working properly. The customer will test |
// + the software for his purpose before any operational usage. The customer will backup his data before using the software. |
// + The customer understands that the Licensor collects, stores and processes, and, where required, forwards, customer data |
// + to third parties to the extent necessary for executing the agreement, subject to applicable data protection and privacy regulations. |
// + *) The territory aspect only refers to the place where the Software is used, not its programmed range. |
// + #### END OF LICENSING TERMS #### |
// + Note: For information on license extensions (e.g. commercial use), please contact us at info(@)hisystems.de. |
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
#include "main.h" |
#define MULTIPLYER 4 |
volatile unsigned int CountMilliseconds = 0; |
volatile unsigned int tim_main; |
volatile unsigned char UpdateMotor = 0; |
volatile unsigned int cntKompass = 0; |
volatile unsigned int beeptime = 0; |
volatile unsigned char BytegapSPI = 0, ServoActive = 0, CalculateServoSignals = 1; |
unsigned char JustMK3MagConnected = 0; |
uint16_t RemainingPulse = 0; |
volatile int16_t ServoNickOffset = (255 / 2) * MULTIPLYER * 16; // initial value near center positon |
volatile int16_t ServoRollOffset = (255 / 2) * MULTIPLYER * 16; // initial value near center positon |
unsigned int BeepMuster = 0xffff; |
signed int NickServoValue = 128 * MULTIPLYER * 16; |
volatile int16_t ServoNickValue = 0; |
volatile int16_t ServoRollValue = 0; |
enum { |
STOP = 0, |
CK = 1, |
CK8 = 2, |
CK64 = 3, |
CK256 = 4, |
CK1024 = 5, |
T0_FALLING_EDGE = 6, |
T0_RISING_EDGE = 7 |
}; |
ISR(TIMER0_OVF_vect) // 9,7kHz |
{ |
static unsigned char cnt_1ms = 1,cnt = 0; |
unsigned char pieper_ein = 0; |
if(BytegapSPI) BytegapSPI--; |
if(SpektrumTimer) SpektrumTimer--; |
if(!cnt--) |
{ |
cnt = 9; |
CountMilliseconds++; |
cnt_1ms++; |
cnt_1ms %= 2; |
if(!cnt_1ms) if(UpdateMotor < 4) UpdateMotor++; |
if(!(PINC & 0x10)) JustMK3MagConnected = 1; |
if(beeptime) |
{ |
if(beeptime > 10) beeptime -= 10; else beeptime = 0; |
if(beeptime & BeepMuster) |
{ |
pieper_ein = 1; |
} |
else pieper_ein = 0; |
} |
else |
{ |
pieper_ein = 0; |
BeepMuster = 0xffff; |
} |
#if (defined(__AVR_ATmega1284__) || defined(__AVR_ATmega1284P__)) |
if(pieper_ein) PORTC |= (1<<7); // Speaker an PORTC.7 |
else PORTC &= ~(1<<7); |
#else |
if(pieper_ein) |
{ |
// if(PlatinenVersion == 10) PORTD |= (1<<2); // Speaker an PORTD.2 |
// else |
PORTC |= (1<<7); // Speaker an PORTC.7 |
} |
else |
{ |
// if(PlatinenVersion == 10) PORTD &= ~(1<<2); |
// else |
PORTC &= ~(1<<7); |
} |
#endif |
} |
if(JustMK3MagConnected && !NaviDataOkay && Parameter_GlobalConfig & CFG_KOMPASS_AKTIV) |
{ |
if(PINC & 0x10) |
{ |
if(++cntKompass > 1000) JustMK3MagConnected = 0; |
} |
else |
{ |
if((cntKompass) && (cntKompass < 362)) |
{ |
cntKompass += cntKompass / 41; |
if(cntKompass > 10) KompassValue = cntKompass - 10; else KompassValue = 0; |
} |
cntKompass = 0; |
} |
} |
} |
// ----------------------------------------------------------------------- |
unsigned int SetDelay(unsigned int t) |
{ |
// TIMSK0 &= ~_BV(TOIE0); |
return(CountMilliseconds + t + 1); |
// TIMSK0 |= _BV(TOIE0); |
} |
// ----------------------------------------------------------------------- |
char CheckDelay(unsigned int t) |
{ |
// TIMSK0 &= ~_BV(TOIE0); |
return(((t - CountMilliseconds) & 0x8000) >> 9); |
// TIMSK0 |= _BV(TOIE0); |
} |
// ----------------------------------------------------------------------- |
void Delay_ms(unsigned int w) |
{ |
unsigned int akt; |
akt = SetDelay(w); |
while (!CheckDelay(akt)); |
} |
void Delay_ms_Mess(unsigned int w) |
{ |
unsigned int akt; |
akt = SetDelay(w); |
while (!CheckDelay(akt)) if(AdReady) {AdReady = 0; ANALOG_ON;} |
} |
/*****************************************************/ |
/* Initialize Timer 2 */ |
/*****************************************************/ |
// The timer 2 is used to generate the PWM at PD7 (J7) |
// to control a camera servo for nick compensation. |
void TIMER2_Init(void) |
{ |
uint8_t sreg = SREG; |
// disable all interrupts before reconfiguration |
cli(); |
PORTD &= ~(1<<PORTD7); // set PD7 to low |
DDRC |= (1<<DDC6); // set PC6 as output (Reset for HEF4017) |
HEF4017Reset_ON; |
// Timer/Counter 2 Control Register A |
// Timer Mode is FastPWM with timer reload at OCR2A (Bits: WGM22 = 1, WGM21 = 1, WGM20 = 1) |
// PD7: Normal port operation, OC2A disconnected, (Bits: COM2A1 = 0, COM2A0 = 0) |
// PD6: Normal port operation, OC2B disconnected, (Bits: COM2B1 = 0, COM2B0 = 0) |
TCCR2A &= ~((1<<COM2A1)|(1<<COM2A0)|(1<<COM2B1)|(1<<COM2B0)); |
TCCR2A |= (1<<WGM21)|(1<<WGM20); |
// Timer/Counter 2 Control Register B |
// Set clock divider for timer 2 to SYSKLOCK/32 = 20MHz / 32 = 625 kHz |
// The timer increments from 0x00 to 0xFF with an update rate of 625 kHz or 1.6 us |
// hence the timer overflow interrupt frequency is 625 kHz / 256 = 2.44 kHz or 0.4096 ms |
// divider 32 (Bits: CS022 = 0, CS21 = 1, CS20 = 1) |
TCCR2B &= ~((1<<FOC2A)|(1<<FOC2B)|(1<<CS22)); |
TCCR2B |= (1<<CS21)|(1<<CS20)|(1<<WGM22); |
// Initialize the Timer/Counter 2 Register |
TCNT2 = 0; |
// Initialize the Output Compare Register A used for PWM generation on port PD7. |
OCR2A = 255; |
TCCR2A |= (1<<COM2A1); // set or clear at compare match depends on value of COM2A0 |
// Timer/Counter 2 Interrupt Mask Register |
// Enable timer output compare match A Interrupt only |
TIMSK2 &= ~((1<<OCIE2B)|(1<<TOIE2)); |
TIMSK2 |= (1<<OCIE2A); |
SREG = sreg; |
} |
//---------------------------- |
void Timer_Init(void) |
{ |
tim_main = SetDelay(10); |
TCCR0B = CK8; |
// TCCR0A = (1<<COM0A1)|(1<<COM0B1)|3;//fast PWM |
TCCR0A = (1<<COM0A1)|(1<<COM0B1)|(1<<COM0B0)|3;//fast PWM |
OCR0B = 255; |
OCR0A = 180; |
TCNT0 = (unsigned char)-TIMER_RELOAD_VALUE; // reload |
//OCR1 = 0x00; |
TIMSK0 |= _BV(TOIE0); |
} |
/*****************************************************/ |
/* Control Servo Position */ |
/*****************************************************/ |
void CalcNickServoValue(void) |
{ |
signed int max, min; |
if(EE_Parameter.ServoCompInvert & SERVO_RELATIVE) // relative moving of the servo value |
{ |
max = ((unsigned int) EE_Parameter.ServoNickMax * MULTIPLYER * 15); |
min = ((unsigned int) EE_Parameter.ServoNickMin * MULTIPLYER * 20); |
NickServoValue -= ((signed char) (Parameter_ServoNickControl - 128) / 4) * 6; |
LIMIT_MIN_MAX(NickServoValue,min, max); |
} |
else NickServoValue = (int16_t)Parameter_ServoNickControl * (MULTIPLYER*16); // direct poti control |
} |
void CalculateServo(void) |
{ |
signed char cosinus, sinus; |
signed long nick, roll; |
cosinus = sintab[EE_Parameter.CamOrientation + 6]; |
sinus = sintab[EE_Parameter.CamOrientation]; |
if(CalculateServoSignals == 1) |
{ |
if(EE_Parameter.GlobalConfig3 & CFG3_SERVO_NICK_COMP_OFF) nick = 0; |
else nick = (cosinus * IntegralNick) / 128L - (sinus * IntegralRoll) / 128L; |
nick -= POI_KameraNick * 7; |
nick = ((long)Parameter_ServoNickComp * nick) / 512L; |
// offset (Range from 0 to 255 * 3 = 765) |
if(EE_Parameter.ServoCompInvert & SERVO_RELATIVE) ServoNickOffset = NickServoValue; |
else ServoNickOffset += (NickServoValue - ServoNickOffset) / EE_Parameter.ServoManualControlSpeed; |
if(EE_Parameter.ServoCompInvert & SERVO_NICK_INV) // inverting movement of servo |
{ |
nick = ServoNickOffset / 16 + nick; |
} |
else |
{ // inverting movement of servo |
nick = ServoNickOffset / 16 - nick; |
} |
if(EE_Parameter.ServoFilterNick) ServoNickValue = ((ServoNickValue * EE_Parameter.ServoFilterNick) + nick) / (EE_Parameter.ServoFilterNick + 1); |
else ServoNickValue = nick; |
// limit servo value to its parameter range definition |
if(ServoNickValue < ((int16_t)EE_Parameter.ServoNickMin * MULTIPLYER)) |
{ |
ServoNickValue = (int16_t)EE_Parameter.ServoNickMin * MULTIPLYER; |
} |
else |
if(ServoNickValue > ((int16_t)EE_Parameter.ServoNickMax * MULTIPLYER)) |
{ |
ServoNickValue = (int16_t)EE_Parameter.ServoNickMax * MULTIPLYER; |
} |
// if(PlatinenVersion < 20) CalculateServoSignals = 0; else |
CalculateServoSignals++; |
} |
else |
{ |
if(EE_Parameter.GlobalConfig3 & CFG3_SERVO_NICK_COMP_OFF) roll = 0; |
else roll = (cosinus * IntegralRoll) / 128L + (sinus * IntegralNick) / 128L; |
roll = ((long)Parameter_ServoRollComp * roll) / 512L; |
ServoRollOffset += ((int16_t)Parameter_ServoRollControl * (MULTIPLYER*16) - ServoRollOffset) / EE_Parameter.ServoManualControlSpeed; |
if(EE_Parameter.ServoCompInvert & SERVO_ROLL_INV) |
{ // inverting movement of servo |
roll = ServoRollOffset / 16 + roll; |
} |
else |
{ // inverting movement of servo |
roll = ServoRollOffset / 16 - roll; |
} |
if(EE_Parameter.ServoFilterRoll) ServoRollValue = ((ServoRollValue * EE_Parameter.ServoFilterRoll) + roll) / (EE_Parameter.ServoFilterRoll + 1); |
else ServoRollValue = roll; |
// limit servo value to its parameter range definition |
if(ServoRollValue < ((int16_t)EE_Parameter.ServoRollMin * MULTIPLYER)) |
{ |
ServoRollValue = (int16_t)EE_Parameter.ServoRollMin * MULTIPLYER; |
} |
else |
if(ServoRollValue > ((int16_t)EE_Parameter.ServoRollMax * MULTIPLYER)) |
{ |
ServoRollValue = (int16_t)EE_Parameter.ServoRollMax * MULTIPLYER; |
} |
CalculateServoSignals = 0; |
} |
} |
ISR(TIMER2_COMPA_vect) |
{ |
// frame len 22.5 ms = 14063 * 1.6 us |
// stop pulse: 0.3 ms = 188 * 1.6 us |
// min servo pulse: 0.6 ms = 375 * 1.6 us |
// max servo pulse: 2.4 ms = 1500 * 1.6 us |
// resolution: 1500 - 375 = 1125 steps |
#define IRS_RUNTIME 127 |
#define PPM_STOPPULSE 188 |
#define PPM_FRAMELEN (1757 * EE_Parameter.ServoNickRefresh) |
#define MINSERVOPULSE 375 |
#define MAXSERVOPULSE 1500 |
#define SERVORANGE (MAXSERVOPULSE - MINSERVOPULSE) |
static uint8_t PulseOutput = 0; |
static uint16_t ServoFrameTime = 0; |
static uint8_t ServoIndex = 0; |
/* |
if(PlatinenVersion < 20) |
{ |
//--------------------------- |
// Nick servo state machine |
//--------------------------- |
if(!PulseOutput) // pulse output complete |
{ |
if(TCCR2A & (1<<COM2A0)) // we had a low pulse |
{ |
TCCR2A &= ~(1<<COM2A0);// make a high pulse |
RemainingPulse = MINSERVOPULSE + SERVORANGE/2; // center position ~ 1.5ms |
RemainingPulse += ServoNickValue - (256 / 2) * MULTIPLYER; // shift ServoNickValue to center position |
// range servo pulse width |
if(RemainingPulse > MAXSERVOPULSE ) RemainingPulse = MAXSERVOPULSE; // upper servo pulse limit |
else if(RemainingPulse < MINSERVOPULSE ) RemainingPulse = MINSERVOPULSE; // lower servo pulse limit |
// accumulate time for correct update rate |
ServoFrameTime = RemainingPulse; |
} |
else // we had a high pulse |
{ |
TCCR2A |= (1<<COM2A0); // make a low pulse |
RemainingPulse = PPM_FRAMELEN - ServoFrameTime; |
CalculateServoSignals = 1; |
} |
// set pulse output active |
PulseOutput = 1; |
} |
} // EOF Nick servo state machine |
else |
*/ |
{ |
//----------------------------------------------------- |
// PPM state machine, onboard demultiplexed by HEF4017 |
//----------------------------------------------------- |
if(!PulseOutput) // pulse output complete |
{ |
if(TCCR2A & (1<<COM2A0)) // we had a low pulse |
{ |
TCCR2A &= ~(1<<COM2A0);// make a high pulse |
if(ServoIndex == 0) // if we are at the sync gap |
{ |
RemainingPulse = PPM_FRAMELEN - ServoFrameTime; // generate sync gap by filling time to full frame time |
ServoFrameTime = 0; // reset servo frame time |
HEF4017Reset_ON; // enable HEF4017 reset |
} |
else // servo channels |
if(ServoIndex > EE_Parameter.ServoNickRefresh) |
{ |
RemainingPulse = 10; // end it here |
} |
else |
{ |
RemainingPulse = MINSERVOPULSE + SERVORANGE/2; // center position ~ 1.5ms |
if(ServoFailsafeActive && ServoIndex < 6 && EE_Parameter.ServoFS_Pos[ServoIndex-1]) RemainingPulse += ((int16_t)EE_Parameter.ServoFS_Pos[ServoIndex-1] * MULTIPLYER) - (256 / 2) * MULTIPLYER; |
else |
switch(ServoIndex) // map servo channels |
{ |
case 1: // Nick Compensation Servo |
RemainingPulse += ServoNickValue - (256 / 2) * MULTIPLYER; |
break; |
case 2: // Roll Compensation Servo |
RemainingPulse += ServoRollValue - (256 / 2) * MULTIPLYER; |
break; |
case 3: |
RemainingPulse += ((int16_t)Parameter_Servo3 * MULTIPLYER) - (256 / 2) * MULTIPLYER; |
break; |
case 4: |
RemainingPulse += ((int16_t)Parameter_Servo4 * MULTIPLYER) - (256 / 2) * MULTIPLYER; |
break; |
case 5: |
RemainingPulse += ((int16_t)Parameter_Servo5 * MULTIPLYER) - (256 / 2) * MULTIPLYER; |
break; |
default: // other servo channels |
RemainingPulse += 2 * PPM_in[ServoIndex]; // add channel value, factor of 2 because timer 1 increments 3.2µs |
break; |
} |
// range servo pulse width |
if(RemainingPulse > MAXSERVOPULSE) RemainingPulse = MAXSERVOPULSE; // upper servo pulse limit |
else if(RemainingPulse < MINSERVOPULSE) RemainingPulse = MINSERVOPULSE; // lower servo pulse limit |
// substract stop pulse width |
RemainingPulse -= PPM_STOPPULSE; |
// accumulate time for correct sync gap |
ServoFrameTime += RemainingPulse; |
} |
} |
else // we had a high pulse |
{ |
TCCR2A |= (1<<COM2A0); // make a low pulse |
// set pulsewidth to stop pulse width |
RemainingPulse = PPM_STOPPULSE; |
// accumulate time for correct sync gap |
ServoFrameTime += RemainingPulse; |
if((ServoActive/* && SenderOkay*/) || ServoActive == 2) HEF4017Reset_OFF; // disable HEF4017 reset |
else HEF4017Reset_ON; |
ServoIndex++; |
if(ServoIndex > EE_Parameter.ServoNickRefresh+1) |
{ |
CalculateServoSignals = 1; |
ServoIndex = 0; // reset to the sync gap |
} |
} |
// set pulse output active |
PulseOutput = 1; |
} |
} // EOF PPM state machine |
// General pulse output generator |
if(RemainingPulse > (255 + IRS_RUNTIME)) |
{ |
OCR2A = 255; |
RemainingPulse -= 255; |
} |
else |
{ |
if(RemainingPulse > 255) // this is the 2nd last part |
{ |
if((RemainingPulse - 255) < IRS_RUNTIME) |
{ |
OCR2A = 255 - IRS_RUNTIME; |
RemainingPulse -= 255 - IRS_RUNTIME; |
} |
else // last part > ISR_RUNTIME |
{ |
OCR2A = 255; |
RemainingPulse -= 255; |
} |
} |
else // this is the last part |
{ |
OCR2A = RemainingPulse; |
RemainingPulse = 0; |
PulseOutput = 0; // trigger to stop pulse |
} |
} // EOF general pulse output generator |
} |
/tags/V2.12a/timer0.h |
---|
0,0 → 1,25 |
#define TIMER_TEILER CK8 |
#define TIMER_RELOAD_VALUE 250 |
#define HEF4017Reset_ON PORTC |= (1<<PORTC6) |
#define HEF4017Reset_OFF PORTC &= ~(1<<PORTC6) |
void Timer_Init(void); |
void TIMER2_Init(void); |
void Delay_ms(unsigned int); |
void Delay_ms_Mess(unsigned int); |
unsigned int SetDelay (unsigned int t); |
char CheckDelay (unsigned int t); |
void CalculateServo(void); |
void CalcNickServoValue(void); |
extern volatile unsigned int CountMilliseconds; |
extern volatile unsigned char UpdateMotor; |
extern volatile unsigned int beeptime; |
extern volatile unsigned int cntKompass; |
extern unsigned int BeepMuster; |
extern volatile unsigned char BytegapSPI, ServoActive, CalculateServoSignals; |
extern volatile int16_t ServoNickValue; |
extern volatile int16_t ServoRollValue; |
extern signed int NickServoValue; |
extern unsigned char JustMK3MagConnected; |
/tags/V2.12a/twimaster.c |
---|
0,0 → 1,487 |
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
// + www.MikroKopter.com |
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
// + Software Nutzungsbedingungen (english version: see below) |
// + der Fa. HiSystems GmbH, Flachsmeerstrasse 2, 26802 Moormerland - nachfolgend Lizenzgeber genannt - |
// + Der Lizenzgeber räumt dem Kunden ein nicht-ausschließliches, zeitlich und räumlich* unbeschränktes Recht ein, die im den |
// + Mikrocontroller verwendete Firmware für die Hardware Flight-Ctrl, Navi-Ctrl, BL-Ctrl, MK3Mag & PC-Programm MikroKopter-Tool |
// + - nachfolgend Software genannt - nur für private Zwecke zu nutzen. |
// + Der Einsatz dieser Software ist nur auf oder mit Produkten des Lizenzgebers zulässig. |
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
// + Die vom Lizenzgeber gelieferte Software ist urheberrechtlich geschützt. Alle Rechte an der Software sowie an sonstigen im |
// + Rahmen der Vertragsanbahnung und Vertragsdurchführung überlassenen Unterlagen stehen im Verhältnis der Vertragspartner ausschließlich dem Lizenzgeber zu. |
// + Die in der Software enthaltenen Copyright-Vermerke, Markenzeichen, andere Rechtsvorbehalte, Seriennummern sowie |
// + sonstige der Programmidentifikation dienenden Merkmale dürfen vom Kunden nicht verändert oder unkenntlich gemacht werden. |
// + Der Kunde trifft angemessene Vorkehrungen für den sicheren Einsatz der Software. Er wird die Software gründlich auf deren |
// + Verwendbarkeit zu dem von ihm beabsichtigten Zweck testen, bevor er diese operativ einsetzt. |
// + Die Haftung des Lizenzgebers wird - soweit gesetzlich zulässig - begrenzt in Höhe des typischen und vorhersehbaren |
// + Schadens. Die gesetzliche Haftung bei Personenschäden und nach dem Produkthaftungsgesetz bleibt unberührt. Dem Lizenzgeber steht jedoch der Einwand |
// + des Mitverschuldens offen. |
// + Der Kunde trifft angemessene Vorkehrungen für den Fall, dass die Software ganz oder teilweise nicht ordnungsgemäß arbeitet. |
// + Er wird die Software gründlich auf deren Verwendbarkeit zu dem von ihm beabsichtigten Zweck testen, bevor er diese operativ einsetzt. |
// + Der Kunde wird er seine Daten vor Einsatz der Software nach dem Stand der Technik sichern. |
// + Der Kunde ist darüber unterrichtet, dass der Lizenzgeber seine Daten im zur Vertragsdurchführung erforderlichen Umfang |
// + und auf Grundlage der Datenschutzvorschriften erhebt, speichert, verarbeitet und, sofern notwendig, an Dritte übermittelt. |
// + *) Die räumliche Nutzung bezieht sich nur auf den Einsatzort, nicht auf die Reichweite der programmierten Software. |
// + #### ENDE DER NUTZUNGSBEDINGUNGEN ####' |
// + Hinweis: Informationen über erweiterte Nutzungsrechte (wie z.B. Nutzung für nicht-private Zwecke) sind auf Anfrage per Email an info(@)hisystems.de verfügbar. |
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
// + Software LICENSING TERMS |
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
// + of HiSystems GmbH, Flachsmeerstrasse 2, 26802 Moormerland, Germany - the Licensor - |
// + The Licensor grants the customer a non-exclusive license to use the microcontroller firmware of the Flight-Ctrl, Navi-Ctrl, BL-Ctrl, and MK3Mag hardware |
// + (the Software) exclusively for private purposes. The License is unrestricted with respect to time and territory*. |
// + The Software may only be used with the Licensor's products. |
// + The Software provided by the Licensor is protected by copyright. With respect to the relationship between the parties to this |
// + agreement, all rights pertaining to the Software and other documents provided during the preparation and execution of this |
// + agreement shall be the property of the Licensor. |
// + The information contained in the Software copyright notices, trademarks, other legal reservations, serial numbers and other |
// + features that can be used to identify the program may not be altered or defaced by the customer. |
// + The customer shall be responsible for taking reasonable precautions |
// + for the safe use of the Software. The customer shall test the Software thoroughly regarding its suitability for the |
// + intended purpose before implementing it for actual operation. The Licensor's liability shall be limited to the extent of typical and |
// + foreseeable damage to the extent permitted by law, notwithstanding statutory liability for bodily injury and product |
// + liability. However, the Licensor shall be entitled to the defense of contributory negligence. |
// + The customer will take adequate precautions in the case, that the software is not working properly. The customer will test |
// + the software for his purpose before any operational usage. The customer will backup his data before using the software. |
// + The customer understands that the Licensor collects, stores and processes, and, where required, forwards, customer data |
// + to third parties to the extent necessary for executing the agreement, subject to applicable data protection and privacy regulations. |
// + *) The territory aspect only refers to the place where the Software is used, not its programmed range. |
// + #### END OF LICENSING TERMS #### |
// + Note: For information on license extensions (e.g. commercial use), please contact us at info(@)hisystems.de. |
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
#include <avr/io.h> |
#include <avr/interrupt.h> |
#include <util/twi.h> |
#include "eeprom.h" |
#include "twimaster.h" |
#include "fc.h" |
#include "analog.h" |
#include "uart.h" |
#include "timer0.h" |
#include "main.h" |
volatile uint8_t twi_state = TWI_STATE_MOTOR_TX, ReadBlSize = 9; |
volatile uint8_t dac_channel = 0; |
volatile uint8_t motor_write = 0; |
volatile uint8_t motor_read = 0; |
volatile uint8_t I2C_TransferActive = 0; |
uint8_t Max_I2C_Packets = 12; |
volatile uint16_t I2CTimeout = 100; |
uint8_t MissingMotor = 0; |
volatile uint8_t BLFlags = 0; |
MotorData_t Motor[MAX_MOTORS]; |
RedundantBl_t RedundantMotor[MAX_MOTORS]; |
// bit mask for witch BL the configuration should be sent |
volatile uint16_t BLConfig_WriteMask = 0; |
// bit mask for witch BL the configuration should be read |
volatile uint16_t BLConfig_ReadMask = 0; |
// buffer for BL Configuration |
BLConfig_t BLConfig; |
#define I2C_WriteByte(byte) {TWDR = byte; TWCR = (1<<TWINT) | (1<<TWEN) | (1<<TWIE);} |
#define I2C_ReceiveByte() {TWCR = (1<<TWINT) | (1<<TWEN) | (1<<TWIE) | (1<<TWEA);} |
#define I2C_ReceiveLastByte() {TWCR = (1<<TWINT) | (1<<TWEN) | (1<<TWIE);} |
#define SCL_CLOCK 200000L |
#define I2C_TIMEOUT 30000 |
#define TWI_BASE_ADDRESS 0x52 |
/**************************************************/ |
/* Initialize I2C (TWI) */ |
/**************************************************/ |
void I2C_Init(char clear) |
{ |
uint8_t i; |
uint8_t sreg = SREG; |
cli(); |
// SDA is INPUT |
DDRC &= ~(1<<DDC1); |
// SCL is output |
DDRC |= (1<<DDC0); |
// pull up SDA |
PORTC |= (1<<PORTC0)|(1<<PORTC1); |
// TWI Status Register |
// prescaler 1 (TWPS1 = 0, TWPS0 = 0) |
TWSR &= ~((1<<TWPS1)|(1<<TWPS0)); |
// set TWI Bit Rate Register |
TWBR = ((F_CPU/SCL_CLOCK)-16)/2; |
twi_state = TWI_STATE_MOTOR_TX; |
motor_write = 0; |
motor_read = 0; |
if(clear) for(i=0; i < MAX_MOTORS; i++) |
{ |
Motor[i].Version = 0; |
Motor[i].SetPoint = 0; |
Motor[i].SetPointLowerBits = 0; |
Motor[i].State = 0; |
Motor[i].ReadMode = BL_READMODE_STATUS; |
Motor[i].Current = 0; |
Motor[i].MaxPWM = 0; |
Motor[i].Temperature = 0; |
Motor[i].NotReadyCnt = 0; |
Motor[i].RPM = 0; |
Motor[i].reserved1 = 0; |
Motor[i].Voltage = 0; |
Motor[i].SlaveI2cError = 0; |
Motor[i].VersionMajor = 0; |
Motor[i].VersionMinor = 0; |
} |
sei(); |
SREG = sreg; |
} |
void I2C_Reset(void) |
{ |
// stop i2c bus |
I2C_Stop(TWI_STATE_MOTOR_TX); |
TWCR = (1<<TWINT); // reset to original state incl. interrupt flag reset |
TWAMR = 0; |
TWAR = 0; |
TWDR = 0; |
TWSR = 0; |
TWBR = 0; |
I2C_TransferActive = 0; |
I2C_Init(0); |
I2C_WriteByte(0); |
BLFlags |= BLFLAG_READ_VERSION; |
} |
/****************************************/ |
/* I2C ISR */ |
/****************************************/ |
ISR (TWI_vect) |
{ |
static uint8_t missing_motor = 0, motor_read_temperature = 0; |
static uint8_t *pBuff = 0; |
static uint8_t BuffLen = 0; |
static uint8_t max_packets = 0; |
switch (twi_state++) |
{ |
// Master Transmit |
case 0: // TWI_STATE_MOTOR_TX |
I2C_TransferActive = 1; |
// skip motor if not used in mixer |
while((Mixer.Motor[motor_write][MIX_GAS] <= 0) && (motor_write < MAX_MOTORS)) motor_write++; |
motor_write %= MAX_MOTORS; |
if(++max_packets > Max_I2C_Packets) // writing finished, read now |
{ |
max_packets = 0; |
BLConfig_WriteMask = 0; // reset configuration bitmask |
//motor_write = 0; // reset motor write counter for next cycle |
twi_state = TWI_STATE_MOTOR_RX; |
I2C_WriteByte(TWI_BASE_ADDRESS + TW_READ + (motor_read<<1) ); // select slave address in rx mode |
} |
else I2C_WriteByte(TWI_BASE_ADDRESS + TW_WRITE + (motor_write<<1) ); // select slave address in tx mode |
break; |
case 1: // Send Data to Slave |
I2C_WriteByte(Motor[motor_write].SetPoint); // transmit setpoint |
// if old version has been detected |
if(!(Motor[motor_write].Version & MOTOR_STATE_NEW_PROTOCOL_MASK)) |
{ |
twi_state = 4; //jump over sending more data |
} |
// the new version has been detected |
else if(!( (Motor[motor_write].SetPointLowerBits && (RequiredMotors < 7)) || BLConfig_WriteMask || BLConfig_ReadMask ) ) |
{ // or LowerBits are zero and no BlConfig should be sent (saves round trip time) |
twi_state = 4; //jump over sending more data |
} |
break; |
case 2: // lower bits of setpoint (higher resolution) |
if ((0x0001<<motor_write) & BLConfig_ReadMask) |
{ |
Motor[motor_write].ReadMode = BL_READMODE_CONFIG; // configuration request |
} |
else |
{ |
Motor[motor_write].ReadMode = BL_READMODE_STATUS; // normal status request |
} |
// send read mode and the lower bits of setpoint |
I2C_WriteByte((Motor[motor_write].ReadMode<<3)|(Motor[motor_write].SetPointLowerBits & 0x07)); |
// configuration tranmission request? |
if((0x0001<<motor_write) & BLConfig_WriteMask) |
{ // redirect tx pointer to configuration data |
pBuff = (uint8_t*)&BLConfig; // select config for motor |
BuffLen = sizeof(BLConfig_t); |
} |
else |
{ // jump to end of transmission for that motor |
twi_state = 4; |
} |
break; |
case 3: // send configuration |
I2C_WriteByte(*pBuff); |
pBuff++; |
if(--BuffLen > 0) twi_state = 3; // if there are some bytes left |
break; |
case 4: // repeat case 0-4 for all motors |
if(TWSR == TW_MT_DATA_NACK) // Data transmitted, NACK received |
{ |
if(!missing_motor) missing_motor = motor_write + 1; |
if((Motor[motor_write].State & MOTOR_STATE_ERROR_MASK) < MOTOR_STATE_ERROR_MASK) Motor[motor_write].State++; // increment error counter and handle overflow |
} |
I2C_Stop(TWI_STATE_MOTOR_TX); |
I2CTimeout = 10; |
motor_write++; // next motor |
I2C_Start(TWI_STATE_MOTOR_TX); // Repeated start -> switch slave or switch Master Transmit -> Master Receive |
break; |
// Master Receive Data |
case 5: // TWI_STATE_MOTOR_RX |
if(TWSR != TW_MR_SLA_ACK) // SLA+R transmitted but no ACK received |
{ // no response from the addressed slave received |
Motor[motor_read].State &= ~MOTOR_STATE_PRESENT_MASK; // clear present bit |
if(++motor_read >= MAX_MOTORS) |
{ // all motors read |
motor_read = 0; // restart from beginning |
BLConfig_ReadMask = 0; // reset read configuration bitmask |
if(++motor_read_temperature >= MAX_MOTORS) |
{ |
motor_read_temperature = 0; |
BLFlags &= ~BLFLAG_READ_VERSION; |
} |
} |
BLFlags |= BLFLAG_TX_COMPLETE; |
I2C_Stop(TWI_STATE_MOTOR_TX); |
I2C_TransferActive = 0; |
} |
else |
{ // motor successfully addressed |
Motor[motor_read].State |= MOTOR_STATE_PRESENT_MASK; // set present bit |
if(Motor[motor_read].Version & MOTOR_STATE_NEW_PROTOCOL_MASK) |
{ |
// new BL found |
switch(Motor[motor_read].ReadMode) |
{ |
case BL_READMODE_CONFIG: |
pBuff = (uint8_t*)&BLConfig; |
BuffLen = sizeof(BLConfig_t); |
Motor[motor_read].ReadMode = BL_READMODE_STATUS; // only once |
break; |
case BL_READMODE_STATUS: |
pBuff = (uint8_t*)&(Motor[motor_read].Current); |
if(motor_read == motor_read_temperature) BuffLen = ReadBlSize; // read Current, MaxPwm & Temp (is 3 or 9) |
else BuffLen = 1;// read Current only |
break; |
} |
} |
else // old BL version |
{ |
pBuff = (uint8_t*)&(Motor[motor_read].Current); |
if((BLFlags & BLFLAG_READ_VERSION) || (motor_read == motor_read_temperature)) BuffLen = 2; // Current & MaxPwm |
else BuffLen = 1; // read Current only |
} |
if(BuffLen == 1) |
{ |
I2C_ReceiveLastByte(); // read last byte |
} |
else |
{ |
I2C_ReceiveByte(); // read next byte |
} |
} |
MissingMotor = missing_motor; |
missing_motor = 0; |
break; |
case 6: // receive bytes |
*pBuff = TWDR; |
pBuff++; // set Pointer to next element : Motor[].Current,Motor[].Temperature |
BuffLen--; |
if(BuffLen>1) |
{ |
I2C_ReceiveByte(); // read next byte |
} |
else if (BuffLen == 1) |
{ |
I2C_ReceiveLastByte(); // read last byte |
} |
else // nothing left -> ready |
{ |
if(BLFlags & BLFLAG_READ_VERSION) |
{ |
if(!(FC_StatusFlags & FC_STATUS_MOTOR_RUN)) |
{ |
if((Motor[motor_read].MaxPWM & 252) == 248) Motor[motor_read].Version |= MOTOR_STATE_NEW_PROTOCOL_MASK; |
else Motor[motor_read].Version = 0; |
if(Motor[motor_read].MaxPWM == 248) Motor[motor_read].Version |= (MOTOR_STATE_FAST_MODE | MOTOR_STATE_BL30); |
else |
if(Motor[motor_read].MaxPWM == 249) Motor[motor_read].Version |= MOTOR_STATE_BL30; |
} |
} |
if(FC_StatusFlags & FC_STATUS_FLY) |
{ |
// Starting -> 40 |
// I2C-Setpoint is zero -> 250 |
// 255 -> Running and no Redundancy |
// 254 -> Running and active Redundancy |
if(Motor[motor_read].MaxPWM < 254) |
{ |
Motor[motor_read].NotReadyCnt++; |
#if (defined(__AVR_ATmega1284__) || defined(__AVR_ATmega1284P__)) |
SpeakHoTT = SPEAK_ERR_MOTOR; |
#endif |
} |
} |
if(++motor_read >= MAX_MOTORS) |
{ |
motor_read = 0; // restart from beginning |
BLConfig_ReadMask = 0; // reset read configuration bitmask |
if(++motor_read_temperature >= MAX_MOTORS) |
{ |
motor_read_temperature = 0; |
BLFlags &= ~BLFLAG_READ_VERSION; |
} |
} |
I2C_Stop(TWI_STATE_MOTOR_TX); |
BLFlags |= BLFLAG_TX_COMPLETE; |
I2C_TransferActive = 0; |
return; |
} |
twi_state = 6; // if there are some bytes left |
break; |
/* |
// writing Gyro-Offsets |
case 18: |
I2C_WriteByte(0x98); // Address the DAC |
break; |
case 19: |
I2C_WriteByte(0x10 + (dac_channel * 2)); // Select DAC Channel (0x10 = A, 0x12 = B, 0x14 = C) |
break; |
case 20: |
switch(dac_channel) |
{ |
case 0: |
I2C_WriteByte(AnalogOffsetNick); // 1st byte for Channel A |
break; |
case 1: |
I2C_WriteByte(AnalogOffsetRoll); // 1st byte for Channel B |
break; |
case 2: |
I2C_WriteByte(AnalogOffsetGier); // 1st byte for Channel C |
break; |
} |
break; |
case 21: |
I2C_WriteByte(0x80); // 2nd byte for all channels is 0x80 |
break; |
case 22: |
I2C_Stop(TWI_STATE_MOTOR_TX); |
I2C_TransferActive = 0; |
I2CTimeout = 10; |
// repeat case 18...22 until all DAC Channels are updated |
if(dac_channel < 2) |
{ |
dac_channel ++; // jump to next channel |
I2C_Start(TWI_STATE_GYRO_OFFSET_TX); // start transmission for next channel |
} |
else |
{ |
dac_channel = 0; // reset dac channel counter |
BLFlags |= BLFLAG_TX_COMPLETE; |
} |
break; |
*/ |
default: |
I2C_Stop(TWI_STATE_MOTOR_TX); |
BLFlags |= BLFLAG_TX_COMPLETE; |
I2CTimeout = 10; |
motor_write = 0; |
motor_read = 0; |
I2C_TransferActive = 0; |
break; |
} |
} |
uint8_t I2C_WriteBLConfig(uint8_t motor) |
{ |
uint8_t i, packets; |
uint16_t timer; |
if(MotorenEin || PC_MotortestActive) return(BLCONFIG_ERR_MOTOR_RUNNING); // not when motors are running! |
if(motor > MAX_MOTORS) return (BLCONFIG_ERR_MOTOR_NOT_EXIST); // motor does not exist! |
if(motor) |
{ |
if(!(Motor[motor-1].State & MOTOR_STATE_PRESENT_MASK)) return(BLCONFIG_ERR_MOTOR_NOT_EXIST); // motor does not exist! |
if(!(Motor[motor-1].Version & MOTOR_STATE_NEW_PROTOCOL_MASK)) return(BLCONFIG_ERR_HW_NOT_COMPATIBLE); // not a new BL! |
} |
// check BL configuration to send |
if((BLConfig.Revision & 0x0B) != BLCONFIG_REVISION) return (BLCONFIG_ERR_SW_NOT_COMPATIBLE); // bad revison |
i = RAM_Checksum((uint8_t*)&BLConfig, sizeof(BLConfig_t) - 1); |
if(i != BLConfig.crc) return(BLCONFIG_ERR_CHECKSUM); // bad checksum |
packets = Max_I2C_Packets; |
Max_I2C_Packets = MAX_MOTORS; |
I2CTimeout = 100; |
timer = SetDelay(100); |
while(!(BLFlags & BLFLAG_TX_COMPLETE) && !CheckDelay(timer)); //wait for complete transfer |
// prepare the bitmask |
if(!motor) BLConfig_WriteMask = 0x0FFF; // 0 means all -> all motors at once with the same configuration |
else BLConfig_WriteMask = 0x0001<<(motor-1); //only one specific motor |
motor_write = 0; |
motor_read = 0; |
// needs at least MAX_MOTORS loops of 2 ms (12*2ms = 24ms) |
timer = SetDelay(1000); |
do |
{ |
I2C_Start(TWI_STATE_MOTOR_TX); // start an i2c transmission |
while(!(BLFlags & BLFLAG_TX_COMPLETE) && !CheckDelay(timer)); //wait for complete transfer |
} while(BLConfig_WriteMask && !CheckDelay(timer)); // repeat until the BL config has been sent |
Max_I2C_Packets = packets; |
if(BLConfig_WriteMask) return(BLCONFIG_ERR_MOTOR_NOT_EXIST); |
return(BLCONFIG_SUCCESS); |
} |
uint8_t I2C_ReadBLConfig(uint8_t motor) |
{ |
uint8_t i; |
uint16_t timer; |
if(MotorenEin || PC_MotortestActive) return(BLCONFIG_ERR_MOTOR_RUNNING); // not when motors are running! |
if(motor > MAX_MOTORS) return (BLCONFIG_ERR_MOTOR_NOT_EXIST); // motor does not exist! |
if(motor == 0) return (BLCONFIG_ERR_READ_NOT_POSSIBLE); |
if(!(Motor[motor-1].State & MOTOR_STATE_PRESENT_MASK)) return(BLCONFIG_ERR_MOTOR_NOT_EXIST); // motor does not exist! |
if(!(Motor[motor-1].Version & MOTOR_STATE_NEW_PROTOCOL_MASK)) return(BLCONFIG_ERR_HW_NOT_COMPATIBLE); // not a new BL! |
timer = SetDelay(1000); |
while(!(BLFlags & BLFLAG_TX_COMPLETE) && !CheckDelay(timer)); //wait for complete transfer |
// prepare the bitmask |
BLConfig_ReadMask = 0x0001<<(motor-1); |
motor_write = 0; |
motor_read = 0; |
BLConfig.Revision = 0; // bad revision |
BLConfig.crc = 0; // bad checksum |
// needs at least MAX_MOTORS loops of 2 ms (12*2ms = 24ms) |
do |
{ |
I2C_Start(TWI_STATE_MOTOR_TX); // start an i2c transmission |
while(!(BLFlags & BLFLAG_TX_COMPLETE) && !CheckDelay(timer)); //wait for complete transfer |
} while(BLConfig_ReadMask && !CheckDelay(timer)); // repeat until the BL config has been received from all motors |
// validate result |
if((BLConfig.Revision & 0x0B) != BLCONFIG_REVISION) return (BLCONFIG_ERR_SW_NOT_COMPATIBLE); // bad revison |
i = RAM_Checksum((uint8_t*)&BLConfig, sizeof(BLConfig_t) - 1); |
if(i != BLConfig.crc) return(BLCONFIG_ERR_CHECKSUM); // bad checksum |
return(BLCONFIG_SUCCESS); |
} |
/tags/V2.12a/twimaster.h |
---|
0,0 → 1,126 |
#ifndef _I2C_MASTER_H |
#define _I2C_MASTER_H |
+ |
+#include <inttypes.h> |
+ |
+#define TWI_STATE_MOTOR_TX 0 |
+#define TWI_STATE_MOTOR_RX 5 |
+//#define TWI_STATE_GYRO_OFFSET_TX 18 |
+ |
+extern volatile uint8_t twi_state, ReadBlSize; |
+extern volatile uint8_t motor_write; |
+extern volatile uint8_t motor_read; |
+extern volatile uint8_t I2C_TransferActive; |
+extern uint8_t Max_I2C_Packets; |
+extern uint8_t MissingMotor; |
+ |
+#define MAX_MOTORS 16 |
+#define MOTOR_STATE_PRESENT_MASK 0x80 |
+#define MOTOR_STATE_ERROR_MASK 0x7F |
+ |
+//Motor[x].Version |
+#define MOTOR_STATE_NEW_PROTOCOL_MASK 0x01 |
+#define MOTOR_STATE_FAST_MODE 0x02 |
+#define MOTOR_STATE_BL30 0x04 // extended Current measurement -> 200 = 20A 201 = 21A 255 = 75A (20+55) |
+ |
+#define BLFLAG_TX_COMPLETE 0x01 |
+#define BLFLAG_READ_VERSION 0x02 |
+ |
+extern volatile uint8_t BLFlags; |
+ |
+#define BL_READMODE_STATUS 0 |
+#define BL_READMODE_CONFIG 16 |
+ |
+typedef struct |
+{ |
+ uint8_t Version; // the version of the BL (0 = old) |
+ uint8_t SetPoint; // written by attitude controller |
+ uint8_t SetPointLowerBits; // for higher Resolution of new BLs |
+ uint8_t State; // 7 bit for I2C error counter, highest bit indicates if motor is present |
+ uint8_t ReadMode; // select data to read |
+ // the following bytes must be exactly in that order! |
+ uint8_t Current; // in 0.1 A steps, read back from BL |
+ uint8_t MaxPWM; // read back from BL -> is less than 255 if BL is in current limit, not running (250) or starting (40) |
+ uint8_t Temperature; // old BL-Ctrl will return a 255 here, the new version the temp. in °C |
+ uint8_t RPM; // Raw value for RPM |
+ uint8_t reserved1; // Voltage (BL3) or mAh (BL2) |
+ uint8_t Voltage; // in 0.1V (BL3 is limited to 255, BL2 is only low-byte) |
+ uint8_t SlaveI2cError; // BL2 & BL3 |
+ uint8_t VersionMajor; // BL2 & BL3 |
+ uint8_t VersionMinor; // BL2 & BL3 |
+ uint8_t NotReadyCnt; // Counts up is the Motor is not ready during flight -> MotorRestart etc. |
+} __attribute__((packed)) MotorData_t; |
+ |
+extern MotorData_t Motor[MAX_MOTORS]; |
+ |
+// BitSate |
+#define BL_BIT_STATE_I2C_OK 0x01 |
+#define BL_BIT_STATE_I2C_VALUE 0x02 |
+#define BL_BIT_STATE_I2C_BAD 0x04 |
+#define BL_BIT_STATE_PPM_OK 0x08 |
+#define BL_BIT_STATE_MOTOR_RUN 0x10 |
+ |
+typedef struct |
+{ |
+ unsigned char BitSate; |
+ unsigned char Current; |
+ unsigned char State; |
+ unsigned char TemperatureInDeg; |
+ unsigned char Voltage80; |
+} __attribute__((packed)) RedundantBl_t; |
+extern RedundantBl_t RedundantMotor[MAX_MOTORS]; |
+ |
+#define BLCONFIG_REVISION 2 |
+ |
+#define MASK_SET_PWM_SCALING 0x01 |
+#define MASK_SET_CURRENT_LIMIT 0x02 |
+#define MASK_SET_TEMP_LIMIT 0x04 |
+#define MASK_SET_CURRENT_SCALING 0x08 |
+#define MASK_SET_BITCONFIG 0x10 |
+#define MASK_SET_STARTPWM 0x20 |
+#define MASK_SET_DEFAULT_PARAMS 0x40 |
+#define MASK_SET_SAVE_EEPROM 0x80 |
+ |
+#define BITCONF_REVERSE_ROTATION 0x01 |
+#define BITCONF_STARTGAS1 0x02 |
+#define BITCONF_STARTGAS2 0x04 |
+#define BITCONF_STARTGAS3 0x08 |
+#define BITCONF_RES4 0x10 |
+#define BITCONF_RES5 0x20 |
+#define BITCONF_RES6 0x40 |
+#define BITCONF_RES7 0x80 |
+ |
+typedef struct |
+{ |
+ uint8_t Revision; // must be BL_REVISION |
+ uint8_t SetMask; // settings mask |
+ uint8_t PwmScaling; // maximum value of control pwm, acts like a thrust limit |
+ uint8_t CurrentLimit; // current limit in A |
+ uint8_t TempLimit; // in °C |
+ uint8_t CurrentScaling; // scaling factor for current measurement |
+ uint8_t BitConfig; // see defines above |
+ uint8_t crc; // checksum |
+} __attribute__((packed)) BLConfig_t; |
+ |
+extern BLConfig_t BLConfig; |
+ |
+extern volatile uint16_t I2CTimeout; |
+ |
+void I2C_Init(char); // Initialize I2C |
+#define I2C_Start(start_state) {twi_state = start_state; BLFlags &= ~BLFLAG_TX_COMPLETE; TWCR = (1<<TWSTA) | (1<<TWEN) | (1<<TWINT) | (1<<TWIE);} |
+#define I2C_Stop(start_state) {twi_state = start_state; TWCR = (1<<TWEN) | (1<<TWSTO) | (1<<TWINT);} |
+void I2C_Reset(void); // Reset I2C |
+ |
+#define BLCONFIG_SUCCESS 0 |
+#define BLCONFIG_ERR_MOTOR_RUNNING 1 |
+#define BLCONFIG_ERR_MOTOR_NOT_EXIST 2 |
+#define BLCONFIG_ERR_HW_NOT_COMPATIBLE 3 |
+#define BLCONFIG_ERR_SW_NOT_COMPATIBLE 4 |
+#define BLCONFIG_ERR_CHECKSUM 5 |
+#define BLCONFIG_ERR_READ_NOT_POSSIBLE 6 |
+ |
+uint8_t I2C_WriteBLConfig(uint8_t motor); |
+uint8_t I2C_ReadBLConfig(uint8_t motor); |
+ |
+#endif |
/tags/V2.12a/uart.c |
---|
0,0 → 1,893 |
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
// + www.MikroKopter.com |
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
// + Software Nutzungsbedingungen (english version: see below) |
// + der Fa. HiSystems GmbH, Flachsmeerstrasse 2, 26802 Moormerland - nachfolgend Lizenzgeber genannt - |
// + Der Lizenzgeber räumt dem Kunden ein nicht-ausschließliches, zeitlich und räumlich* unbeschränktes Recht ein, die im den |
// + Mikrocontroller verwendete Firmware für die Hardware Flight-Ctrl, Navi-Ctrl, BL-Ctrl, MK3Mag & PC-Programm MikroKopter-Tool |
// + - nachfolgend Software genannt - nur für private Zwecke zu nutzen. |
// + Der Einsatz dieser Software ist nur auf oder mit Produkten des Lizenzgebers zulässig. |
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
// + Die vom Lizenzgeber gelieferte Software ist urheberrechtlich geschützt. Alle Rechte an der Software sowie an sonstigen im |
// + Rahmen der Vertragsanbahnung und Vertragsdurchführung überlassenen Unterlagen stehen im Verhältnis der Vertragspartner ausschließlich dem Lizenzgeber zu. |
// + Die in der Software enthaltenen Copyright-Vermerke, Markenzeichen, andere Rechtsvorbehalte, Seriennummern sowie |
// + sonstige der Programmidentifikation dienenden Merkmale dürfen vom Kunden nicht verändert oder unkenntlich gemacht werden. |
// + Der Kunde trifft angemessene Vorkehrungen für den sicheren Einsatz der Software. Er wird die Software gründlich auf deren |
// + Verwendbarkeit zu dem von ihm beabsichtigten Zweck testen, bevor er diese operativ einsetzt. |
// + Die Haftung des Lizenzgebers wird - soweit gesetzlich zulässig - begrenzt in Höhe des typischen und vorhersehbaren |
// + Schadens. Die gesetzliche Haftung bei Personenschäden und nach dem Produkthaftungsgesetz bleibt unberührt. Dem Lizenzgeber steht jedoch der Einwand |
// + des Mitverschuldens offen. |
// + Der Kunde trifft angemessene Vorkehrungen für den Fall, dass die Software ganz oder teilweise nicht ordnungsgemäß arbeitet. |
// + Er wird die Software gründlich auf deren Verwendbarkeit zu dem von ihm beabsichtigten Zweck testen, bevor er diese operativ einsetzt. |
// + Der Kunde wird er seine Daten vor Einsatz der Software nach dem Stand der Technik sichern. |
// + Der Kunde ist darüber unterrichtet, dass der Lizenzgeber seine Daten im zur Vertragsdurchführung erforderlichen Umfang |
// + und auf Grundlage der Datenschutzvorschriften erhebt, speichert, verarbeitet und, sofern notwendig, an Dritte übermittelt. |
// + *) Die räumliche Nutzung bezieht sich nur auf den Einsatzort, nicht auf die Reichweite der programmierten Software. |
// + #### ENDE DER NUTZUNGSBEDINGUNGEN ####' |
// + Hinweis: Informationen über erweiterte Nutzungsrechte (wie z.B. Nutzung für nicht-private Zwecke) sind auf Anfrage per Email an info(@)hisystems.de verfügbar. |
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
// + Software LICENSING TERMS |
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
// + of HiSystems GmbH, Flachsmeerstrasse 2, 26802 Moormerland, Germany - the Licensor - |
// + The Licensor grants the customer a non-exclusive license to use the microcontroller firmware of the Flight-Ctrl, Navi-Ctrl, BL-Ctrl, and MK3Mag hardware |
// + (the Software) exclusively for private purposes. The License is unrestricted with respect to time and territory*. |
// + The Software may only be used with the Licensor's products. |
// + The Software provided by the Licensor is protected by copyright. With respect to the relationship between the parties to this |
// + agreement, all rights pertaining to the Software and other documents provided during the preparation and execution of this |
// + agreement shall be the property of the Licensor. |
// + The information contained in the Software copyright notices, trademarks, other legal reservations, serial numbers and other |
// + features that can be used to identify the program may not be altered or defaced by the customer. |
// + The customer shall be responsible for taking reasonable precautions |
// + for the safe use of the Software. The customer shall test the Software thoroughly regarding its suitability for the |
// + intended purpose before implementing it for actual operation. The Licensor's liability shall be limited to the extent of typical and |
// + foreseeable damage to the extent permitted by law, notwithstanding statutory liability for bodily injury and product |
// + liability. However, the Licensor shall be entitled to the defense of contributory negligence. |
// + The customer will take adequate precautions in the case, that the software is not working properly. The customer will test |
// + the software for his purpose before any operational usage. The customer will backup his data before using the software. |
// + The customer understands that the Licensor collects, stores and processes, and, where required, forwards, customer data |
// + to third parties to the extent necessary for executing the agreement, subject to applicable data protection and privacy regulations. |
// + *) The territory aspect only refers to the place where the Software is used, not its programmed range. |
// + #### END OF LICENSING TERMS #### |
// + Note: For information on license extensions (e.g. commercial use), please contact us at info(@)hisystems.de. |
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
#include <stdarg.h> |
#include <string.h> |
#include <avr/pgmspace.h> |
#include "main.h" |
#include "uart.h" |
#include "libfc.h" |
#include "eeprom.h" |
#define FC_ADDRESS 1 |
#define NC_ADDRESS 2 |
#define MK3MAG_ADDRESS 3 |
#define BL_CTRL_ADDRESS 5 |
#define ABO_TIMEOUT 4000 // disable abo after 4 seconds |
#define MAX_SENDE_BUFF 220 |
#define MAX_EMPFANGS_BUFF 220 |
#define BLPARAM_REVISION 1 |
#define MASK_SET_PWM_SCALING 0x01 |
#define MASK_SET_CURRENT_LIMIT 0x02 |
#define MASK_SET_TEMP_LIMIT 0x04 |
#define MASK_SET_CURRENT_SCALING 0x08 |
#define MASK_SET_BITCONFIG 0x10 |
#define MASK_RESET_CAPCOUNTER 0x20 |
#define MASK_SET_DEFAULT_PARAMS 0x40 |
#define MASK_SET_SAVE_EEPROM 0x80 |
unsigned char GetExternalControl = 0,DebugDisplayAnforderung1 = 0, DebugDisplayAnforderung = 0,DebugDataAnforderung = 0,GetVersionAnforderung = 0, GetPPMChannelAnforderung = 0; |
unsigned char DisplayLine = 0; |
unsigned volatile char SioTmp = 0; |
unsigned volatile char NeuerDatensatzEmpfangen = 0; |
unsigned volatile char NeueKoordinateEmpfangen = 0; |
unsigned volatile char UebertragungAbgeschlossen = 1; |
unsigned volatile char CntCrcError = 0; |
unsigned volatile char AnzahlEmpfangsBytes = 0; // achtung: das ist die AscII-Buffer länge, nicht die Nettodatenlänge |
unsigned volatile char TxdBuffer[MAX_SENDE_BUFF]; |
unsigned volatile char RxdBuffer[MAX_EMPFANGS_BUFF]; |
unsigned char *pRxData = 0; |
unsigned char RxDataLen = 0; |
unsigned volatile char PC_DebugTimeout = 0; |
unsigned volatile char PC_MotortestActive = 0; |
unsigned char DebugTextAnforderung = 255; |
unsigned char PcZugriff = 100; |
unsigned char MotorTest[16]; |
unsigned char MeineSlaveAdresse = 1; // Flight-Ctrl |
unsigned char ConfirmFrame; |
unsigned char ExternalControlTimeout = 0; |
struct str_DebugOut DebugOut; |
struct str_ExternControl ExternalControl; |
struct str_VersionInfo VersionInfo; |
struct str_WinkelOut WinkelOut; |
struct str_Data3D Data3D; |
int Display_Timer, Debug_Timer,Kompass_Timer,Timer3D; |
unsigned int DebugDataIntervall = 0, Intervall3D = 0, Display_Interval = 0; |
unsigned int AboTimeOut = 0; |
unsigned volatile char ReceiverUpdateModeActive = 0; // 1 = Update 2 = JetiBox-Simulation |
const unsigned char ANALOG_TEXT[32][16] PROGMEM = |
{ |
//1234567890123456 |
"AngleNick ", //0 |
"AngleRoll ", |
"AccNick ", |
"AccRoll ", |
"YawGyro ", |
"Altitude [0.1m] ", //5 |
"AccZ ", |
"Gas ", |
"Compass Value ", |
"Voltage [0.1V] ", |
"Receiver Level ", //10 |
"Gyro Compass ", |
"Motor 1 ", |
"Motor 2 ", |
"Motor 3 ", |
"Motor 4 ", //15 |
"16 ", |
"17 ", |
"18 ", |
"19 ", |
"Servo ", //20 |
"Hovergas ", |
"Current [0.1A] ", |
"Capacity [mAh] ", |
"Height Setpoint ", |
"25 ", //25 |
"26 ", //"26 CPU OverLoad ", |
"27 ", |
"I2C-Error ", |
"BL Limit ", |
"GPS_Nick ", //30 |
"GPS_Roll " |
}; |
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
//++ Calculate checksum |
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
unsigned char CalculateDebugLableCrc(void) |
{ |
unsigned int i; |
unsigned char crc = 0; |
for(i=0;i<sizeof(ANALOG_TEXT);i++) crc += pgm_read_word(&ANALOG_TEXT[0][i]); |
return(crc); |
} |
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
//++ Sende-Part der Datenübertragung |
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
ISR(USART0_TX_vect) |
{ |
static unsigned int ptr = 0; |
unsigned char tmp_tx; |
if(!UebertragungAbgeschlossen) |
{ |
ptr++; // die [0] wurde schon gesendet |
tmp_tx = TxdBuffer[ptr]; |
if((tmp_tx == '\r') || (ptr == MAX_SENDE_BUFF)) |
{ |
//if(DebugOut.Analog[] < ptr) DebugOut.Analog[] = ptr; |
ptr = 0; |
UebertragungAbgeschlossen = 1; |
} |
UDR0 = tmp_tx; |
} |
else ptr = 0; |
} |
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
//++ Empfangs-Part der Datenübertragung, incl. CRC-Auswertung |
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
ISR(USART0_RX_vect) |
{ |
static unsigned int crc; |
static unsigned char crc1,crc2,buf_ptr; |
static unsigned char UartState = 0; |
unsigned char CrcOkay = 0; |
if (ReceiverUpdateModeActive == 1) { UDR1 = UDR0; return; } // 1 = Update |
if (ReceiverUpdateModeActive == 2) { RxdBuffer[0] = UDR0; return; } // 2 = JetiBox-Simulation |
SioTmp = UDR0; |
if(buf_ptr >= MAX_SENDE_BUFF) UartState = 0; |
if(SioTmp == '\r' && UartState == 2) |
{ |
//if(DebugOut.Analog[] < buf_ptr) DebugOut.Analog[] = buf_ptr; |
UartState = 0; |
crc -= RxdBuffer[buf_ptr-2]; |
crc -= RxdBuffer[buf_ptr-1]; |
crc %= 4096; |
crc1 = '=' + crc / 64; |
crc2 = '=' + crc % 64; |
CrcOkay = 0; |
if((crc1 == RxdBuffer[buf_ptr-2]) && (crc2 == RxdBuffer[buf_ptr-1])) CrcOkay = 1; else { CrcOkay = 0; CntCrcError++;}; |
if(!NeuerDatensatzEmpfangen && CrcOkay) // Datensatz schon verarbeitet |
{ |
NeuerDatensatzEmpfangen = 1; |
AnzahlEmpfangsBytes = buf_ptr + 1; |
RxdBuffer[buf_ptr] = '\r'; |
if(RxdBuffer[2] == 'R' && !MotorenEin) |
{ |
LcdClear(); |
wdt_enable(WDTO_250MS); // Reset-Commando |
ServoActive = 0; |
} |
} |
} |
else |
switch(UartState) |
{ |
case 0: |
if(SioTmp == '#' && !NeuerDatensatzEmpfangen) UartState = 1; // Startzeichen und Daten schon verarbeitet |
buf_ptr = 0; |
RxdBuffer[buf_ptr++] = SioTmp; |
crc = SioTmp; |
break; |
case 1: // Adresse auswerten |
UartState++; |
RxdBuffer[buf_ptr++] = SioTmp; |
crc += SioTmp; |
break; |
case 2: // Eingangsdaten sammeln |
RxdBuffer[buf_ptr] = SioTmp; |
if(buf_ptr < MAX_EMPFANGS_BUFF) buf_ptr++; |
else UartState = 0; |
//if(DebugOut.Analog[] < buf_ptr) DebugOut.Analog[] = buf_ptr; |
crc += SioTmp; |
break; |
default: |
UartState = 0; |
break; |
} |
} |
// -------------------------------------------------------------------------- |
void AddCRC(unsigned int wieviele) |
{ |
unsigned int tmpCRC = 0,i; |
for(i = 0; i < wieviele;i++) |
{ |
tmpCRC += TxdBuffer[i]; |
} |
// if(i > MAX_SENDE_BUFF - 3) tmpCRC += 11; |
tmpCRC %= 4096; |
TxdBuffer[i++] = '=' + tmpCRC / 64; |
TxdBuffer[i++] = '=' + tmpCRC % 64; |
TxdBuffer[i++] = '\r'; |
UebertragungAbgeschlossen = 0; |
UDR0 = TxdBuffer[0]; |
//if(DebugOut.Analog[] < i) DebugOut.Analog[] = i; |
} |
// -------------------------------------------------------------------------- |
void SendOutData(unsigned char cmd,unsigned char address, unsigned char BufferAnzahl, ...) //unsigned char *snd, unsigned char len) |
{ |
va_list ap; |
unsigned int pt = 0; |
unsigned char a,b,c; |
unsigned char ptr = 0; |
unsigned char *snd = 0; |
int len = 0; |
TxdBuffer[pt++] = '#'; // Startzeichen |
TxdBuffer[pt++] = 'a' + address; // Adresse (a=0; b=1,...) |
TxdBuffer[pt++] = cmd; // Commando |
va_start(ap, BufferAnzahl); |
if(BufferAnzahl) |
{ |
snd = va_arg(ap, unsigned char*); |
len = va_arg(ap, int); |
ptr = 0; |
BufferAnzahl--; |
} |
while(len) |
{ |
if(len) |
{ |
a = snd[ptr++]; |
len--; |
if((!len) && BufferAnzahl) |
{ |
snd = va_arg(ap, unsigned char*); |
len = va_arg(ap, int); |
ptr = 0; |
BufferAnzahl--; |
} |
} |
else a = 0; |
if(len) |
{ |
b = snd[ptr++]; |
len--; |
if((!len) && BufferAnzahl) |
{ |
snd = va_arg(ap, unsigned char*); |
len = va_arg(ap, int); |
ptr = 0; |
BufferAnzahl--; |
} |
} |
else b = 0; |
if(len) |
{ |
c = snd[ptr++]; |
len--; |
if((!len) && BufferAnzahl) |
{ |
snd = va_arg(ap, unsigned char*); |
len = va_arg(ap, int); |
ptr = 0; |
BufferAnzahl--; |
} |
} |
else c = 0; |
TxdBuffer[pt++] = '=' + (a >> 2); |
TxdBuffer[pt++] = '=' + (((a & 0x03) << 4) | ((b & 0xf0) >> 4)); |
TxdBuffer[pt++] = '=' + (((b & 0x0f) << 2) | ((c & 0xc0) >> 6)); |
TxdBuffer[pt++] = '=' + ( c & 0x3f); |
} |
va_end(ap); |
AddCRC(pt); |
} |
// -------------------------------------------------------------------------- |
void Decode64(void) // die daten werden im rx buffer dekodiert, das geht nur, weil aus 4 byte immer 3 gemacht werden. |
{ |
unsigned char a,b,c,d; |
unsigned char x,y,z; |
unsigned char ptrIn = 3; // start at begin of data block |
unsigned char ptrOut = 3; |
unsigned char len = AnzahlEmpfangsBytes - 6; // von der Gesamtbytezahl eines Frames gehen 3 Bytes des Headers ('#',Addr, Cmd) und 3 Bytes des Footers (CRC1, CRC2, '\r') ab. |
while(len) |
{ |
a = RxdBuffer[ptrIn++] - '='; |
b = RxdBuffer[ptrIn++] - '='; |
c = RxdBuffer[ptrIn++] - '='; |
d = RxdBuffer[ptrIn++] - '='; |
x = (a << 2) | (b >> 4); |
y = ((b & 0x0f) << 4) | (c >> 2); |
z = ((c & 0x03) << 6) | d; |
if(len--) RxdBuffer[ptrOut++] = x; else break; |
if(len--) RxdBuffer[ptrOut++] = y; else break; |
if(len--) RxdBuffer[ptrOut++] = z; else break; |
} |
pRxData = (unsigned char*)&RxdBuffer[3]; // decodierte Daten beginnen beim 4. Byte |
RxDataLen = ptrOut - 3; // wie viele Bytes wurden dekodiert? |
} |
// -------------------------------------------------------------------------- |
void BearbeiteRxDaten(void) |
{ |
if(!NeuerDatensatzEmpfangen) return; |
unsigned char tempchar1, tempchar2; |
Decode64(); // dekodiere datenblock im Empfangsbuffer |
switch(RxdBuffer[1]-'a') // check for Slave Address |
{ |
case FC_ADDRESS: // FC special commands |
switch(RxdBuffer[2]) |
{ |
case 'K':// Kompasswert |
memcpy((unsigned char *)&KompassValue , (unsigned char *)pRxData, sizeof(KompassValue)); |
break; |
case 't':// Motortest |
if(AnzahlEmpfangsBytes > 20) memcpy(&MotorTest[0], (unsigned char *)pRxData, sizeof(MotorTest)); |
else memcpy(&MotorTest[0], (unsigned char *)pRxData, 4); |
PC_MotortestActive = 240; |
//while(!UebertragungAbgeschlossen); |
//SendOutData('T', MeineSlaveAdresse, 0); |
PcZugriff = 255; |
break; |
case 'n':// "Get Mixer |
while(!UebertragungAbgeschlossen); |
SendOutData('N', FC_ADDRESS, 1, (unsigned char *) &Mixer, sizeof(Mixer) - 1); |
Debug("Mixer lesen"); |
break; |
case 'm':// "Write Mixer |
if(pRxData[0] == EEMIXER_REVISION) |
{ |
memcpy(&Mixer, (unsigned char *)pRxData, sizeof(Mixer) - 1); |
MixerTable_WriteToEEProm(); |
tempchar1 = 1; |
VersionInfo.HardwareError[1] &= ~FC_ERROR1_MIXER; |
} |
else |
{ |
tempchar1 = 0; |
} |
while(!UebertragungAbgeschlossen); |
SendOutData('M', FC_ADDRESS, 1, &tempchar1, sizeof(tempchar1)); |
break; |
case 'p': // get PPM Channels |
GetPPMChannelAnforderung = 1; |
PcZugriff = 255; |
break; |
case 'q':// "Get"-Anforderung für Settings |
// Bei Get werden die vom PC einstellbaren Werte vom PC zurückgelesen |
if(!MotorenEin) |
{ |
if((10 <= pRxData[0]) && (pRxData[0] < 20)) |
{ |
tempchar1 = pRxData[0] - 10; |
if(tempchar1< 1) tempchar1 = 1; // limit to 1 |
else if(tempchar1 > 5) tempchar1 = 5; // limit to 5 |
SetDefaultParameter(tempchar1, 1); |
} |
else if((20 <= pRxData[0]) && (pRxData[0] < 30)) |
{ |
tempchar1 = pRxData[0] - 20; |
if(tempchar1< 1) tempchar1 = 1; // limit to 1 |
else if(tempchar1 > 5) tempchar1 = 5; // limit to 5 |
SetDefaultParameter(tempchar1, 0); |
} |
else |
{ |
tempchar1 = pRxData[0]; |
if(tempchar1 == 0xFF) |
{ |
tempchar1 = GetActiveParamSet(); |
} |
if(tempchar1< 1) tempchar1 = 1; // limit to 1 |
else if(tempchar1 > 5) tempchar1 = 5; // limit to 5 |
// load requested parameter set |
ParamSet_ReadFromEEProm(tempchar1); |
} |
LipoDetection(0); |
} else tempchar1 = GetActiveParamSet(); |
while(!UebertragungAbgeschlossen); |
SendOutData('Q', FC_ADDRESS, 2, &tempchar1, sizeof(tempchar1), (unsigned char *) &EE_Parameter, sizeof(EE_Parameter) - 1); |
Debug("Lese Setting %d", tempchar1); |
break; |
case 's': // Parametersatz speichern |
if((1 <= pRxData[0]) && (pRxData[0] <= 5) && (pRxData[1] == EEPARAM_REVISION) && MotorenEin == 0) // check for setting to be in range |
{ |
memcpy(&EE_Parameter, (uint8_t*)&pRxData[1], sizeof(EE_Parameter) - 1); |
ParamSet_WriteToEEProm(pRxData[0]); |
Umschlag180Nick = (long) EE_Parameter.WinkelUmschlagNick * 2500L; |
Umschlag180Roll = (long) EE_Parameter.WinkelUmschlagRoll * 2500L; |
tempchar1 = GetActiveParamSet(); |
} |
else |
{ |
tempchar1 = 0; // mark in response an invlid setting |
} |
while(!UebertragungAbgeschlossen); |
SendOutData('S', FC_ADDRESS, 1, &tempchar1, sizeof(tempchar1)); |
if(!MotorenEin) |
{ |
Piep(tempchar1,110); |
LipoDetection(0); |
} |
LIBFC_ReceiverInit(EE_Parameter.Receiver); |
break; |
case 'f': // auf anderen Parametersatz umschalten |
if(MotorenEin) break; |
if((1 <= pRxData[0]) && (pRxData[0] <= 5)) ParamSet_ReadFromEEProm(pRxData[0]); |
tempchar1 = GetActiveParamSet(); |
while(!UebertragungAbgeschlossen); |
SendOutData('F', FC_ADDRESS, 1, &tempchar1, sizeof(tempchar1)); |
if(!MotorenEin) |
{ |
Piep(tempchar1,110); |
LipoDetection(0); |
} |
LIBFC_ReceiverInit(EE_Parameter.Receiver); |
break; |
case 'y':// serial Potis |
for(tempchar1 = 0; tempchar1 < 12; tempchar1++) PPM_in[SERIAL_POTI_START + tempchar1] = (signed char) pRxData[tempchar1]; |
break; |
case 'u': // request BL parameter |
Debug("Reading BL %d", pRxData[0]); |
// try to read BL configuration |
tempchar2 = I2C_ReadBLConfig(pRxData[0]); |
if(tempchar2 == BLCONFIG_SUCCESS) tempchar1 = 1; |
else tempchar1 = 0; |
while(!UebertragungAbgeschlossen); // wait for previous frame to be sent |
SendOutData('U', FC_ADDRESS, 4, &tempchar1, sizeof(tempchar1), &tempchar2, sizeof(tempchar2), &pRxData[0], 1, &BLConfig, sizeof(BLConfig_t)); |
break; |
case 'w': // write BL parameter |
Debug("Writing BL %d", pRxData[0]); |
if(RxDataLen >= 1+sizeof(BLConfig_t)) |
{ |
memcpy(&BLConfig, (uint8_t*)(&pRxData[1]), sizeof(BLConfig_t)); |
tempchar2 = I2C_WriteBLConfig(pRxData[0]); |
if(tempchar2 == BLCONFIG_SUCCESS) tempchar1 = 1; |
else tempchar1 = 0; // indicate error |
while(!UebertragungAbgeschlossen); // wait for previous frame to be sent |
SendOutData('W', FC_ADDRESS,2, &tempchar1, sizeof(tempchar1), &tempchar2, sizeof(tempchar2)); |
} |
break; |
case 'j': |
if(MotorenEin) break; |
tempchar1 = LIBFC_GetCPUType(); |
if((tempchar1 == CPU_ATMEGA644P) || (tempchar1 == CPU_ATMEGA1284P)) |
{ |
uint16_t ubrr = (uint16_t) ((uint32_t) F_CPU/ (8 * 38400L) - 1); |
cli(); |
// UART0 & UART1 disable RX and TX-Interrupt |
UCSR0B &= ~((1 << RXCIE0)|(1 << TXCIE0)); |
UCSR1B &= ~((1 << RXCIE1)|(1 << TXCIE1)); |
// UART0 & UART1 disable receiver and transmitter |
UCSR0B &= ~((1 << TXEN0) | (1 << RXEN0)); |
UCSR1B &= ~((1 << TXEN1) | (1 << RXEN1)); |
// UART0 & UART1 flush receive buffer explicit |
while ( UCSR1A & (1<<RXC1) ) UDR1; |
while ( UCSR0A & (1<<RXC0) ) UDR0; |
if(pRxData[0] == 1) ReceiverUpdateModeActive = 2; |
else |
{ // Jeti or HoTT update |
//#if (defined(__AVR_ATmega1284__) || defined(__AVR_ATmega1284P__)) |
if(pRxData[0] == 100) ubrr = (uint16_t) ((uint32_t) F_CPU/ (8 * 19200L) - 1); // HoTT |
//#endif |
ReceiverUpdateModeActive = 1; |
// UART0 & UART1 set baudrate |
UBRR1H = (uint8_t)(ubrr>>8); |
UBRR1L = (uint8_t)ubrr; |
UBRR0H = UBRR1H; |
UBRR0L = UBRR1L; |
// UART1 no parity |
UCSR1C &= ~(1 << UPM11); |
UCSR1C &= ~(1 << UPM10); |
// UART1 8-bit |
UCSR1B &= ~(1 << UCSZ12); |
UCSR1C |= (1 << UCSZ11); |
UCSR1C |= (1 << UCSZ10); |
} |
// UART0 & UART1 1 stop bit |
UCSR1C &= ~(1 << USBS1); |
UCSR0C &= ~(1 << USBS0); |
// UART1 clear 9th bit |
UCSR1B &= ~(1<<TXB81); |
// enable receiver and transmitter for UART0 and UART1 |
UCSR0B |= (1 << TXEN0) | (1 << RXEN0); |
UCSR1B |= (1 << TXEN1) | (1 << RXEN1); |
// enable RX-Interrupt for UART0 and UART1 |
UCSR0B |= (1 << RXCIE0); |
UCSR1B |= (1 << RXCIE1); |
// disable other Interrupts |
TIMSK0 = 0; |
TIMSK1 = 0; |
TIMSK2 = 0; |
sei(); |
} |
break; |
} // case FC_ADDRESS: |
default: // any Slave Address |
switch(RxdBuffer[2]) |
{ |
#ifdef REDUNDANT_FC_SLAVE |
static unsigned int clear_I; |
case '?':// Serielle Antwort eines BL-Reglers |
tempchar1 = RxdBuffer[1] - ('a'+11); |
if(tempchar1 >= MAX_MOTORS) break; |
memcpy((unsigned char *)&RedundantMotor[tempchar1], (unsigned char *)pRxData, sizeof(RedundantBl_t)); |
if(RedundantMotor[tempchar1].BitSate & BL_BIT_STATE_I2C_OK && clear_I) clear_I--; |
if(!(RedundantMotor[tempchar1].BitSate & BL_BIT_STATE_I2C_OK)) ROT_FLASH; |
GRN_FLASH; |
if(RedundantMotor[tempchar1].BitSate & BL_BIT_STATE_I2C_BAD) |
{ |
ROT_ON; |
if(clear_I == 0) |
{ |
SummeNick = 0; |
SummeRoll = 0; |
Mess_Integral_Gier = 0; |
} |
clear_I = 500; |
} |
Motor[tempchar1].Current = RedundantMotor[tempchar1].Current; |
Motor[tempchar1].MaxPWM = RedundantMotor[tempchar1].State; |
Motor[tempchar1].Temperature = RedundantMotor[tempchar1].TemperatureInDeg; |
//DebugOut.Analog[16] = RedundantMotor[tempchar1].BitSate; |
//DebugOut.Analog[17]++; |
//DebugOut.Analog[18] = tempchar1; |
break; |
#endif |
// 't' comand placed here only for compatibility to BL |
case 't':// Motortest |
if(AnzahlEmpfangsBytes >= sizeof(MotorTest)) memcpy(&MotorTest[0], (unsigned char *)pRxData, sizeof(MotorTest)); |
else memcpy(&MotorTest[0], (unsigned char *)pRxData, 4); |
while(!UebertragungAbgeschlossen); |
SendOutData('T', MeineSlaveAdresse, 0); |
PC_MotortestActive = 250; |
PcZugriff = 255; |
AboTimeOut = SetDelay(ABO_TIMEOUT); |
break; |
// 'K' comand placed here only for compatibility to old MK3MAG software, that does not send the right Slave Address |
case 'K':// Kompasswert |
memcpy((unsigned char *)&KompassValue , (unsigned char *)pRxData, sizeof(KompassValue)); |
break; |
case 'a':// Texte der Analogwerte |
DebugTextAnforderung = pRxData[0]; |
if (DebugTextAnforderung > 31) DebugTextAnforderung = 31; |
PcZugriff = 255; |
break; |
case 'b': |
if(AnzahlEmpfangsBytes < 20) // prevents that the old frame is valid |
{ |
memcpy((unsigned char *)&ExternalControl, (unsigned char *)pRxData, sizeof(ExternalControl)); |
ConfirmFrame = ExternalControl.Frame; |
ExternalControlTimeout = 100; // 2 seconds timeout |
} |
break; |
case 'c': // Poll the 3D-Data |
if(!Intervall3D) { if(pRxData[0]) Timer3D = SetDelay(pRxData[0] * 10);} |
Intervall3D = pRxData[0] * 10; |
AboTimeOut = SetDelay(ABO_TIMEOUT); |
break; |
case 'd': // Poll the debug data |
PcZugriff = 255; |
DebugDataIntervall = (unsigned int)pRxData[0] * 10; |
if(DebugDataIntervall > 0) DebugDataAnforderung = 1; |
AboTimeOut = SetDelay(ABO_TIMEOUT); |
break; |
case 'h':// x-1 Displayzeilen |
PcZugriff = 255; |
if((pRxData[0] & 0x80) == 0x00) // old format |
{ |
DisplayLine = 2; |
Display_Interval = 0; |
} |
else // new format |
{ |
RemoteKeys |= ~pRxData[0]; |
Display_Interval = (unsigned int)pRxData[1] * 10; |
DisplayLine = 4; |
AboTimeOut = SetDelay(ABO_TIMEOUT); |
} |
DebugDisplayAnforderung = 1; |
break; |
case 'l':// x-1 Displayzeilen |
PcZugriff = 255; |
MenuePunkt = pRxData[0]; |
DebugDisplayAnforderung1 = 1; |
break; |
case 'v': // Version-Anforderung und Ausbaustufe |
#if (defined(__AVR_ATmega1284__) || defined(__AVR_ATmega1284P__)) |
if(RxDataLen > 0 && pRxData[0] == 2) GetVersionAnforderung = 2; |
else |
#endif |
GetVersionAnforderung = 1; |
break; |
case 'g':// |
GetExternalControl = 1; |
break; |
default: |
//unsupported command received |
break; |
} |
break; // default: |
} |
NeuerDatensatzEmpfangen = 0; |
pRxData = 0; |
RxDataLen = 0; |
} |
//############################################################################ |
//Routine für die Serielle Ausgabe |
void uart_putchar (char c) |
//############################################################################ |
{ |
//Warten solange bis Zeichen gesendet wurde |
loop_until_bit_is_set(UCSR0A, UDRE0); |
//Ausgabe des Zeichens |
UDR0 = c; |
} |
//############################################################################ |
//INstallation der Seriellen Schnittstelle |
void UART_Init (void) |
//############################################################################ |
{ |
unsigned int ubrr = (unsigned int) ((unsigned long) F_CPU/(8 * USART0_BAUD) - 1); |
//Enable TXEN im Register UCR TX-Data Enable & RX Enable |
UCSR0B = (1 << TXEN0) | (1 << RXEN0); |
// UART Double Speed (U2X) |
UCSR0A |= (1 << U2X0); |
// RX-Interrupt Freigabe |
UCSR0B |= (1 << RXCIE0); |
// TX-Interrupt Freigabe |
UCSR0B |= (1 << TXCIE0); |
// USART0 Baud Rate Register |
// set clock divider |
UBRR0H = (uint8_t)(ubrr >> 8); |
UBRR0L = (uint8_t)ubrr; |
Debug_Timer = SetDelay(DebugDataIntervall); |
Kompass_Timer = SetDelay(220); |
VersionInfo.SWMajor = VERSION_MAJOR; |
VersionInfo.SWMinor = VERSION_MINOR; |
VersionInfo.SWPatch = VERSION_PATCH; |
VersionInfo.ProtoMajor = VERSION_SERIAL_MAJOR; |
VersionInfo.BL_Firmware = 255; |
VersionInfo.HWMajor = PlatinenVersion; |
VersionInfo.LabelTextCRC = CalculateDebugLableCrc(); |
pRxData = 0; |
RxDataLen = 0; |
} |
//--------------------------------------------------------------------------------------------- |
void DatenUebertragung(void) |
{ |
if(!UebertragungAbgeschlossen) return; |
if(CheckDelay(AboTimeOut)) |
{ |
Display_Interval = 0; |
DebugDataIntervall = 0; |
Intervall3D = 0; |
} |
if(((Display_Interval>0 && CheckDelay(Display_Timer)) || DebugDisplayAnforderung) && UebertragungAbgeschlossen) |
{ |
if(DisplayLine > 3)// new format |
{ |
Menu(); |
SendOutData('H', FC_ADDRESS, 1, (uint8_t *)DisplayBuff, 80); |
} |
else // old format |
{ |
LCD_printfxy(0,0,"!!! INCOMPATIBLE !!!"); |
SendOutData('H', FC_ADDRESS, 2, &DisplayLine, sizeof(DisplayLine), (uint8_t *)DisplayBuff, 20); |
if(DisplayLine++ > 3) DisplayLine = 0; |
} |
Display_Timer = SetDelay(Display_Interval); |
DebugDisplayAnforderung = 0; |
} |
if(DebugDisplayAnforderung1 && UebertragungAbgeschlossen) |
{ |
Menu(); |
SendOutData('L', FC_ADDRESS, 3, &MenuePunkt, sizeof(MenuePunkt), &MaxMenue, sizeof(MaxMenue), DisplayBuff, sizeof(DisplayBuff)); |
DebugDisplayAnforderung1 = 0; |
} |
if(GetVersionAnforderung && UebertragungAbgeschlossen) |
{ |
#if (defined(__AVR_ATmega1284__) || defined(__AVR_ATmega1284P__)) |
if(GetVersionAnforderung == 2) // poll version of NC |
{ |
struct str_VersionInfo nc; |
nc.SWMajor = NC_Version.Major; |
nc.SWMinor = NC_Version.Minor; |
nc.SWPatch = NC_Version.Patch; |
nc.HWMajor = NC_Version.Hardware; |
nc.HardwareError[0] = 0xff; |
nc.HardwareError[1] = 0xff; |
nc.ProtoMajor = VersionInfo.ProtoMajor; |
nc.BL_Firmware = VersionInfo.BL_Firmware; |
nc.Flags = VersionInfo.Flags; |
//nc.reserved1 = 0; |
SendOutData('V', FC_ADDRESS, 1, (unsigned char *) &nc, sizeof(nc)); |
} |
else |
#endif |
{ |
SendOutData('V', FC_ADDRESS, 1, (unsigned char *) &VersionInfo, sizeof(VersionInfo)); |
} |
GetVersionAnforderung = 0; |
Debug_OK("Version gesendet"); |
} |
if(GetExternalControl && UebertragungAbgeschlossen) // Bei Get werden die vom PC einstellbaren Werte vom PC zurückgelesen |
{ |
SendOutData('G',MeineSlaveAdresse, 1, (unsigned char *) &ExternalControl, sizeof(ExternalControl)); |
GetExternalControl = 0; |
} |
if(((DebugDataIntervall>0 && CheckDelay(Debug_Timer)) || DebugDataAnforderung) && UebertragungAbgeschlossen) |
{ |
CopyDebugValues(); |
SendOutData('D', FC_ADDRESS, 1, (unsigned char *) &DebugOut,sizeof(DebugOut)); |
DebugDataAnforderung = 0; |
if(DebugDataIntervall>0) Debug_Timer = SetDelay(DebugDataIntervall); |
} |
if(Intervall3D > 0 && CheckDelay(Timer3D) && UebertragungAbgeschlossen) |
{ |
Data3D.Winkel[0] = ToNaviCtrl.IntegralNick;//(int) (IntegralNick / (EE_Parameter.GyroAccFaktor * 4)); // etwa in 0.1 Grad |
Data3D.Winkel[1] = ToNaviCtrl.IntegralRoll;//(int) (IntegralRoll / (EE_Parameter.GyroAccFaktor * 4)); // etwa in 0.1 Grad |
Data3D.Winkel[2] = (int) ((10 * ErsatzKompass) / GIER_GRAD_FAKTOR); |
Data3D.Centroid[0] = SummeNick >> 9; |
Data3D.Centroid[1] = SummeRoll >> 9; |
Data3D.Centroid[2] = Mess_Integral_Gier >> 9; |
Data3D.AccZ = Aktuell_az; |
SendOutData('C', FC_ADDRESS, 1, (unsigned char *) &Data3D,sizeof(Data3D)); |
Timer3D = SetDelay(Intervall3D); |
} |
if(DebugTextAnforderung != 255) // Texte für die Analogdaten |
{ |
unsigned char label[16]; // local sram buffer |
memcpy_P(label, ANALOG_TEXT[DebugTextAnforderung], 16); // read lable from flash to sra |
SendOutData('A', FC_ADDRESS, 2, (unsigned char *)&DebugTextAnforderung, sizeof(DebugTextAnforderung),label, 16); |
DebugTextAnforderung = 255; |
} |
if(ConfirmFrame && UebertragungAbgeschlossen) // Datensatz bestätigen |
{ |
SendOutData('B', FC_ADDRESS, 1, (uint8_t*)&ConfirmFrame, sizeof(ConfirmFrame)); |
ConfirmFrame = 0; |
} |
if(GetPPMChannelAnforderung && UebertragungAbgeschlossen) |
{ |
SendOutData('P', FC_ADDRESS, 1, (unsigned char *) &PPM_in, sizeof(PPM_in)); |
GetPPMChannelAnforderung = 0; |
} |
#ifndef REDUNDANT_FC_SLAVE |
if((CheckDelay(Kompass_Timer)) && UebertragungAbgeschlossen) |
{ |
if(!NaviDataOkay) // no external compass needed |
{ |
WinkelOut.Winkel[0] = ToNaviCtrl.IntegralNick;//(int) (IntegralNick / (EE_Parameter.GyroAccFaktor * 4)); // etwa in 0.1 Grad |
WinkelOut.Winkel[1] = ToNaviCtrl.IntegralRoll;//(int) (IntegralRoll / (EE_Parameter.GyroAccFaktor * 4)); // etwa in 0.1 Grad |
WinkelOut.UserParameter[0] = Parameter_UserParam1; |
WinkelOut.UserParameter[1] = Parameter_UserParam2; |
SendOutData('k', MK3MAG_ADDRESS, 1, (unsigned char *) &WinkelOut,sizeof(WinkelOut)); |
} |
if(WinkelOut.CalcState > 4) WinkelOut.CalcState = 6; // wird dann in SPI auf Null gesetzt |
if(JustMK3MagConnected) Kompass_Timer = SetDelay(99); |
else Kompass_Timer = SetDelay(999); |
} |
#endif |
#ifdef REDUNDANT_FC_SLAVE |
//if(UebertragungAbgeschlossen || MotorenEin) |
if(UebertragungAbgeschlossen && (CheckDelay(Kompass_Timer) || MotorenEin)) |
{ |
static unsigned char who, request; |
unsigned char SendRedundantMotor[MAX_MOTORS], i; |
if(!request) { who = (who+1) % RequiredMotors; request = 1;} // nur in jedem 2. Zykus abfragen, weil die Antwort zu lang ist |
else request = 0; |
for(i=0; i<RequiredMotors; i++) |
{ |
if(request) SendRedundantMotor[0] = who+1; |
else SendRedundantMotor[0] = 0; |
if(PC_MotortestActive) SendRedundantMotor[0] |= 0x80; |
SendRedundantMotor[i+1] = Motor[i].SetPoint; |
} |
Kompass_Timer = SetDelay(25); |
SendOutData('!', FC_ADDRESS, 1, (unsigned char *) &SendRedundantMotor, RequiredMotors+1); |
} |
#endif |
#ifdef DEBUG // only include functions if DEBUG is defined |
if(SendDebugOutput && UebertragungAbgeschlossen) |
{ |
SendOutData('0', FC_ADDRESS, 1, (unsigned char *) &tDebug, sizeof(tDebug)); |
SendDebugOutput = 0; |
} |
#endif |
} |
/tags/V2.12a/uart.h |
---|
0,0 → 1,139 |
#ifndef _UART_H |
#define _UART_H |
#define printf_P(format, args...) _printf_P(&uart_putchar, format , ## args) |
#define printf(format, args...) _printf_P(&uart_putchar, PSTR(format) , ## args) |
void BearbeiteRxDaten(void); |
extern unsigned char DebugGetAnforderung; |
extern unsigned volatile char ReceiverUpdateModeActive; |
extern unsigned volatile char UebertragungAbgeschlossen; |
extern unsigned volatile char PC_DebugTimeout; |
extern unsigned volatile char NeueKoordinateEmpfangen; |
extern unsigned volatile char PC_MotortestActive; |
extern unsigned char MeineSlaveAdresse; |
extern unsigned char PcZugriff; |
extern unsigned char RemotePollDisplayLine; |
extern unsigned volatile char RxdBuffer[]; |
extern int Debug_Timer,Kompass_Timer; |
extern void UART_Init (void); |
extern void uart_putchar (char c); |
//extern void boot_program_page (uint32_t page, uint8_t *buf); |
extern void DatenUebertragung(void); |
extern void Uart1Init(void); |
extern void BearbeiteRxDaten(void); |
extern unsigned char MotorTest[16]; |
struct str_DebugOut |
{ |
unsigned char Status[2]; |
signed int Analog[32]; // Debugwerte |
}; |
extern struct str_DebugOut DebugOut; |
struct str_WinkelOut |
{ |
signed int Winkel[2]; |
unsigned char UserParameter[2]; |
unsigned char CalcState; |
unsigned char Orientation; |
}; |
extern struct str_WinkelOut WinkelOut; |
struct str_Data3D |
{ |
signed int Winkel[3]; // nick, roll, compass in 0,1° |
signed char Centroid[3]; |
// signed char reserve[5]; |
unsigned int AccZ; |
signed char reserve[3]; |
}; |
extern struct str_Data3D Data3D; |
/* |
struct str_ExternControl |
{ |
unsigned char Digital[2]; |
unsigned char RemoteTasten; |
signed char Nick; |
signed char Roll; |
signed char Gier; |
unsigned char Gas; |
signed char Hight; |
unsigned char free; |
unsigned char Frame; |
unsigned char Config; |
}; |
extern struct str_ExternControl ExternControl; |
*/ |
// defines for ExternalControl.Config |
#define EC_VALID 0x01 // only valid if this is 1 |
#define EC_GAS_ADD 0x02 // if 1 -> use the GAS Value not as MAX |
#define EC_IGNORE_RC 0x80 // if 1 -> for Flying without RC-Control |
struct str_ExternControl |
{ |
signed char Nick; |
signed char Roll; |
signed char Gier; |
signed char Gas; |
unsigned char Frame; // will return a confirm frame with this value |
unsigned char Config; |
unsigned char free; |
}; |
extern struct str_ExternControl ExternalControl; |
extern unsigned char ExternalControlTimeout; |
// FC hardware errors |
// bitmask for UART_VersionInfo_t.HardwareError[0] |
#define FC_ERROR0_GYRO_NICK 0x01 |
#define FC_ERROR0_GYRO_ROLL 0x02 |
#define FC_ERROR0_GYRO_YAW 0x04 |
#define FC_ERROR0_ACC_NICK 0x08 |
#define FC_ERROR0_ACC_ROLL 0x10 |
#define FC_ERROR0_ACC_TOP 0x20 |
#define FC_ERROR0_PRESSURE 0x40 |
#define FC_ERROR0_CAREFREE 0x80 |
// bitmask for UART_VersionInfo_t.HardwareError[1] |
#define FC_ERROR1_I2C 0x01 |
#define FC_ERROR1_BL_MISSING 0x02 |
#define FC_ERROR1_SPI_RX 0x04 |
#define FC_ERROR1_PPM 0x08 |
#define FC_ERROR1_MIXER 0x10 |
#define FC_ERROR1_RES1 0x20 |
#define FC_ERROR1_RES2 0x40 |
#define FC_ERROR1_RES3 0x80 |
// for FlightCtrl |
//VersionInfo.Flags |
#define FC_VERSION_FLAG_NC_PRESENT 0x01 |
// for NaviCtrl |
#define NC_VERSION_FLAG_MK3MAG_PRESENT 0x01 |
struct str_VersionInfo |
{ |
unsigned char SWMajor; |
unsigned char SWMinor; |
unsigned char ProtoMajor; |
unsigned char LabelTextCRC; |
unsigned char SWPatch; |
unsigned char HardwareError[2]; |
unsigned char HWMajor; |
unsigned char BL_Firmware; |
unsigned char Flags; |
}; |
extern struct str_VersionInfo VersionInfo; |
//#define USART0_BAUD 9600 |
//#define USART0_BAUD 14400 |
//#define USART0_BAUD 28800 |
//#define USART0_BAUD 38400 |
#define USART0_BAUD 57600 |
#endif //_UART_H |
/tags/V2.12a/user_receiver.c |
---|
0,0 → 1,24 |
#include "Spektrum.h" |
#include "main.h" |
//############################################################################ |
// Implement your own RC-decoding routines here |
//############################################################################ |
//############################################################################ |
// Initialize the UART here |
//############################################################################ |
void User_Receiver_Init(void) |
{ |
// SpektrumUartInit(); // or use an existing routine like this |
}; |
//############################################################################ |
// Is called by the uart RX interrupt |
// UDR contains the received byte |
//############################################################################ |
void User_RX_Parser(unsigned char udr) |
{ |
// place your code here |
}; |
/tags/V2.12a/user_receiver.h |
---|
0,0 → 1,4 |
// for own implementations |
void User_Receiver_Init(void); |
void User_RX_Parser(unsigned char); |
/tags/V2.12a/vector.h |
---|
0,0 → 1,19 |
#ifndef _VECTOR_H |
#define _VECTOR_H |
typedef struct |
{ |
int32_t x; |
int32_t y; |
int32_t z; |
} __attribute__((packed)) vector32_t; |
typedef struct |
{ |
int16_t x; |
int16_t y; |
int16_t z; |
} __attribute__((packed)) vector16_t; |
#endif //_VECTOR_H |
/tags/V2.12a/version.txt |
---|
0,0 → 1,818 |
------- |
V0.53 27.04.2007 H.Buss |
- erste öffentliche Version |
V0.53b 29.04.2007 H.Buss |
- der FAKTOR_I war versehentlich auf Null, dann liegt der MikroKopter nicht so hart in der Luft |
V0.53c 29.04.2007 H.Buss |
- es gib ein Menü, in dem die Werte der Kanäle nach Nick, Roll, Gas,... sortiert sind. |
Die angezeigten Werte waren nicht die Werte der Funke |
V0.54 01.05.2007 H.Buss |
- die Paramtersätze können jetzt vor dem Start ausgewählt werden |
Dazu wird beim Kalibrieren der Messwerte (Gashebel oben links) der Nick-Rollhebel abgefragt: |
2 3 4 |
1 x 5 |
- - - |
Bedeutet: Nick-Rollhebel Links Mitte = Setting:1 Links Oben = Setting:2 usw. |
- der Faktor_I für den Hauptregler ist hinzugekommen. Im Heading-Hold-Modus sollte er vergössert werden, was Stabilität bringt |
V0.55 14.05.2007 H.Buss |
- es können nun Servos an J3,J4,J5 mit den Kanälen 5-7 gesteuert werden |
V0.56 14.05.2007 H.Buss |
- es gab Probleme mit Funken, die mehr als 8 Kanäle haben, wenn mehrere Kanäle dann auf Null waren |
- Funken, die nicht bis +-120 aussteuern können, sollten jetzt auch gehen |
V0.57 24.05.2007 H.Buss |
- Der Höhenregler kann nun auch mittels Schalter bedient werden |
- Bug im Gier-Algorithmus behoben; Schnelles Gieren fürhrte dazu, dass der MK zu weit gedreht hat |
- Kompass-Einfluss dämpfen bei Neigung |
- Man kann zwischen Kompass FIX (Richtung beim Kalibrieren) und Variabel (einstellbar per Gier) wählen |
- Der Motortest vom Kopter-Tool geht jetzt |
- Man kann den Parametersätzen einen Namen geben |
- Das Kamerasetting ist unter Setting 2 defaultmässig integriert |
V0.58 30.05.2007 H.Buss |
- Der Höhenregler-Algorithmus wird nun umgangen, wenn der Höhenreglerschalter aus ist |
V0.60 17.08.2007 H.Buss |
- "Schwindel-Bug" behoben |
- Die Poti-Werte werden jetzt auf Unterlauf (<0) überprüft |
- Poti4 zugefügt |
- Es werden jetzt 8 Kanäle ausgewertet |
- Kamera-Servo (an J7) |
- Die Settings müssen überschrieben werden |
V0.61 - V0.63 H.Buss 27.09.2007 |
- Poti 4 und Kanal 8 werden im Menü angezeigt |
- ein paar Kleinigkeiten bei den DefaultKonstanten2 bereinigt |
- Analog.c: Aktuell_ax korrigiert |
- auf 32 Debug-Kanäle erweitert |
- Loopings sind jetzt möglich und einzeln im KopterTool freischaltbar |
- leichte Anpassungen im Gier - Geschwindigkeit und Drift |
- die Hardwareversion V1.1 wird erkannt und das Programm stellt sich auf die geänderte Gyroverstärkung und die geänderten Portpins ein |
- die Software startet nach dem Einschalten schneller, weil der Luftdruckoffset schneller gefunden wird |
- die PPM-Ausgänge liegen wieder an den Pins an |
- Details an der Sensordatenverarbeitung -> es fliegt sich geringfügig anders |
- der MK ist bei wenig Gas nicht mehr so giftig -> soll das Landen vereinfachen |
- I2C-Bus läuft jetzt sicher nach einer Störung wieder an |
- Sticksignale werden präziser ausgewertet |
- Stick-Kanäle werden ans Kopter-Tool übertragen |
- Es muss die Version V1.47 des Kopter-Tool verwendet werden |
- Die Settings werden auf Default zurückgesetzt |
- am Piepen kann man die Fehlerart unterscheiden |
1. einzelnes Piepen beim Einschalten und Kalibrieren |
2. langsames Intervall mindestens 1 Sek -> Empfangsausfall |
3. schnelleres Intervall mindestens 1 Sek -> Akku |
4. sehr schnelles Intervall mindestens 1 Sek -> Kommunikation zu den Reglern gestört |
V0.64 H.Buss 30.09.2007 |
- beim Gieren wurden die Achsen nicht hart genug geregelt |
V0.65a H.Buss 15.10.2007 |
- Integral im Mischer wieder integriert |
- Feinabstimmung im ACC/Gyro Abgleich -> 1/32 & 100 |
- ACC/Gyro Abgleich auch bei HH |
V0.66a H.Buss 3.11.2007 |
- Messwertverarbeitung aus dem Analog-Interrupt entfernt |
- Analogmessung hängt jetzt am FC-Timing |
- Looping-Stick-Hysterese eingebaut |
- Looping-180°-Umschlag einstellbar |
- Achsenkopplung: Gierbewegung verkoppelt Nick und Roll |
- Lageregelung nach ACC-Sensor verbessert |
- zusätzlicher I-Anteil in der Lageregelung verbessert die Neutrallage |
- Gyrodriftkompensation überarbeitet |
- Bug in der Gier-Stick-Berechnung behoben |
- Gyro-Messung auf 1kHz beschleunigt |
V0.67a H.Buss 16.11.2007 |
- der Hauptregler-I-Anteil wirkt jetzt nur noch auf den Winkel (ausser im HH-Mode) |
- Gyro-Acc-Abgleich jetzt wieder in jedem Zyklus |
- Feinabstimmung |
- Beim HH-Modus gab es noch Bugs |
V0.67e H.Buss 29.11.2007 |
- Parameter: Dynamic Stability und Driftfaktor eingeführt |
- Die Namen der Analogwerte werden jetzt zum Koptertool übertragen |
- Kompatibilität zum Koptertool erhöht |
V0.67f H.Buss 04.12.2007 |
- Das Integral des Hauptreglers wird jetzt linear entladen und nicht mehr proportional |
- Schub für Gier wird jetzt auf den Gaswert begrenzt, dadurch steigt der MK nicht mehr beim Gieren. Gier ist allerdings nicht mehr so agressiv |
- Die ACC-Nullwerte können jetzt dauerhaft im EEPROM gespeichert werden (Stick:Vollgas und Gier rechts) |
V0.68a I.Busker 28.12.2007 |
- SPI.c & SPI.h ins Projekt aufgenommen |
SPI-Kommuikation kann in SPI.h aktiviert/deaktivert werden |
V0.68c H.Buss 05.01.2008 |
- Stickauswertung verbessert -> träger und präziser |
- Alle Settings angepasst |
V0.69e H.Buss 05.05.2008 |
- kleinere Bugs beseitigt |
- Schneller Sinkflug jetzt möglich |
- Min- und Maxgas in den Settings geändert |
- Lagewinkel wird jetzt in 0,1 Grad an Kompass und Navi gesendet |
- Kalibrierung für MK3Mag -> Nick unten beim Kalibrieren |
- Kompassroutine um den Ersatzkompass (Gyro unterstützt Kompasswert) erweitert |
V0.69h H.Buss 21.05.2008 |
- STICK_GAIN = 4 eingeführt. Das erhöht die Auflösung der Sollwerte. Stick_P und Stick_I müssen nun um Faktor 4 erhöht werden |
- SenderOkay auch an das Naviboard übertragen |
- Bessere Parameter bei Senderausfall |
V0.69j H.Buss 30.05.2008 |
- Höhere Präzision der Achsenkopplung |
V0.69k H.Buss 31.05.2008 |
- Bug in SPI.C behoben |
- in 0.69h war ein Bug, der zu ungewollten Loopings führen konnte |
V0.69L H.Buss 14.06.2008 |
- feinere Cam-Servo-Auflösung |
V0.70a H.Buss 01.07.2008 |
- Unterstützung der V1.3-Hardware mit automatischem Hardware-Gyro-Abgleich |
V0.70b H.Buss 14.07.2008 |
- flexible Einstellungsmöglichkeit von J16 und J17 (Transistorausgänge) |
- eigene Parameter für GPS-Naviboard |
- eigener Parameter für ExternalControl (war vorher UserParameter1 bzw. 8) |
- neue Parameter im EEPROM-Datensatz: J16Bitmask, J16Timing, ExternalControl, Navi... |
- MikroKopterFlags eingeführt, damit das Navi den Status des MKs kennt |
- KopterTool-Kompatibilität auf 8 erhöht |
V0.70c H.Buss 30.07.2008 |
- Parameter der Datenfusion leicht modifiziert |
- EEPROM-Parameter für Looping-Umschlag angepasst (von 100 auf 85) |
- MaxStick wird auf 100 begrenzt |
V0.70d H.Buss 02.08.2008 |
- Transistorausgänge: das oberste Bit der Blinkmaske (im KopterTool linkes Bit) gibt nun den Zustand des Ausgangs im Schalterbetrieb an |
0.71b: H.Buss 19.10.2008 |
Kommunikation zum Navi erweitert: |
- Beeptime jetzt 32Bit |
- Datenfusion und Driftkopensation wird durch NaviBoard unterstützt |
0.71c: H.Buss 20.10.2008 |
- LoopConfig heisst jetzt BitConfig |
- 3-Fach-Schalter für Höhensteuerung möglich -> kann man mit GPS-Schalter zusammenlegen |
- bei den Settings wurde Setting[0] mit abgespeichert, welches es nicht gab. |
- in Zukunft werden bei neuen EEPROM-Settings die Kanäle von Setting 1 übernommen |
- Variablen NaviWindCorrection, NaviSpeedCompensation, NaviOperatingRadius eingeführt |
0.71f: H.Buss 15.11.2008 |
- Ausschalten der Höhenregelung per Schalter um 0,3 sek verzögert |
- bei der seriellen Übertragung hat die FC jetzt als SlaveAdresse die 1 |
- VersionInfo.NaviKompatibel eingeführt |
- wenn manuell gegiert wird, wird der GyroKompass-Wert auf den Kompasswert gesetzt |
- Luftdruckwert wird an das Navi übertragen |
- Der Baro-Offset wird jetzt nachgeführt, um den Messbereich zu erweitern. Geht nur bei Höhenregler mit Schalter |
- Debugdaten können jetzt mit 'f' gepollt werden |
0.71g: Gregor 09.12.2008 |
- Kommunikation überarbeitet |
Infos hier: http://www.mikrokopter.de/ucwiki/en/SerialCommands |
0.71h: H.Buss 15.12.2008 |
- Freigegebene Version |
- NaviAngleLimitation als Parameter zum Navi implementiert |
- Antwort auf CMD: 't' entfernt |
0.72d: H.Buss 22.01.2009 |
- OCTO als Compilerschalter |
- Unterstützung der FC 2.0 (ME) |
- GYRO_D eingeführt |
- Achsenkopplung jetzt auch auf Nick/Roll-Bewegung |
0.72e: H.Buss 27.01.2009 |
- die 0.72d hatte kein Integral im Gier |
- Parameter eingeführt: |
EE_Parameter.NaviGpsPLimit |
EE_Parameter.NaviGpsILimit |
EE_Parameter.NaviGpsDLimit |
EE_Parameter.NaviPH_LoginTime |
EE_Parameter.AchsKopplung2 |
EE_Parameter.CouplingYawCorrection |
0.72f: H.Buss 28.01.2009 |
- Bug im Ersatzkompass entfernt |
0.72h: H.Buss 05.02.2009 |
- Algorithmen beschleunigt -> Floats durch Fixkomma ersetzt |
- Achsentkopplung weiter verbessert |
- Nick- und Roll im Octo-Mischer auf jeweils vier Motoren aufgeteilt |
0.72i: H.Buss 07.02.2009 |
- Abtastrate von 1kHz auf 2kHz erhöht |
0.72j: H.Buss 09.02.2009 |
- neue Implementierung der Servoausgänge |
0.72k: H.Buss 10.02.2009 |
- Abtastrate auf 5kHz erhöht |
0.72L: H.Buss 13.02.2009 |
- Signalfilterung überarbeitet |
- OCTO2 implementiert |
0.72M: H.Buss 13.02.2009 |
- Code Cleanup |
0.72o: H.Buss 24.02.2009 |
- Abtastrate auf 2kHz |
- HW-Version an Navi |
- neuer Datensatz 'c' -> Lagedaten für 3D-Grafik |
- Auswerteroutine für Spectrum-Satteliten implementiert |
- Kanalsettings werden beim Parameterreset nicht mehr gelöscht |
- die Driftkompensation wird jetzt feiner aufgelöst --> EE_Parameter.Driftkomp muss mal 8 genommen werden |
- die Integrale und ACC-Werte werden jetzt im Scope in ca. 0,1° angezeigt (wie beim NaviBrd) |
0.72p: H.Buss 01.03.2009 |
- Octo3 erstellt |
- Analogwerte umbenannt |
0.73a-d: H.Buss 05.04.2009 |
- MixerTabelle implementiert |
- I2C-Bus auf bis zu 12 Motoren erweitert |
- die Busfehler der BL-Regler werden im Menü angezeigt |
- Revision der MixerTabelle eingeführt |
- MixerTabelle wird bei Parameterreset neu initialisiert |
- Motortest auf [12] erweitert |
- Motorschalter nicht mehr 3-Stufig |
0.74a |
- Datenfusion im Flug auch, wenn ACC-Z < 512 |
- Wert für die Luftdruck-Messbereichserweiterung abgefangen |
0.74d |
- Die Driftkompensation ist jetzt dreistufig -> 0,5% pro sekunde zusätzlich eingeführts |
0.75a G.Stobrawa 22.5.2009 |
- Extern Control also received from NC via SPI |
0.75b H.Buss 27.05.2009 |
- Spektrum-Singale schalten den PPM-Eingang aus |
- max. 2 Sekunden nach dem Start auf die BL-Regler warten |
- Automatische Zellenerkennung, wenn Spannungswarnung < 5,0V |
- Bei automatischer Zellenerkennung piept es je nach Zellenzahl |
- EE_DATENREVISION auf 76 erhöht |
- Servo: |
- Roll-Servo für FC ME implementiert |
- Update-Cmd stoppt Servos |
- Servos werden erst nach dem ersten Kalibrieren aktiviert |
0.75c G.Stobrawa 25.7.2009 |
- Übertragung der Servo-Settings zur NC |
- RSSI wird an NC gesendet, derzeit wird der Wert nicht gesetzt |
- Bugfix Messbereichsumschaltung des Luftdrucksensors springt |
- Auflösung des Luftdrucks nun bis auf 1 cm (5mal feiner) zur genaueren Berechnung des D-Anteils |
- Unterstützung von Warnings-Bitmasks für die J16, J17-Outputs bei Unterspannung |
- Unterspannung für einzelne Zelle´n von 3.2V auf 3.3V angehoben (9.6V --> 9.9V für 3S) |
0.75d H.Buss 13.8.2009 |
- RC-Routine: Empfangsausfall soll sicherer erkannt werden |
- Zellenerkennung nun auch beim Speichern der Settings |
- Warnungs-Blinkmaske auch bei Empfangsausfall |
0.75e H.Buss 18.8.2009 |
- LED-Blinken kann an die Motoren gekoppelt werden |
- Feinabstimmung des Höhenreglers |
0.75f H.Buss 27.8.2009 |
- D-Anteil des Höhenreglers jetzt mit Quadratischer Komponente |
- Lagewinkel wirkt jetzt mit 1/Cos(x) mit in den Höhenregler |
- leichte Modifikation der RC-Empfangroutine |
0.75g H.Buss 31.08.2009 |
- die Akkuspannung geht jetzt antiproportional ins Gas ein |
0.75h H.Buss 3.09.2009 |
- im Höhenregler werden jetzt die Stellwerte begrenzt --> max +- 16% vom geschätzten Schwebegas |
0.75i H.Buss 7.09.2009 |
- GpsZ vom Navi zur FC für den Höhenregler |
- "hoovergas-Variation" als Parameter |
- Kompatibilität zu NC und PC erhöht |
0.75j H.Buss 17.09.2009 |
- Laufzeitzähler eingebaut |
0.75k H.Buss 22.09.2009 |
- zweite Variante (Gregor) der Höhenregelung implementiert |
- umschaltbare RC-Routine |
0.75L H.Buss 23.09.2009 |
- SollHoehe und Gas geht nun auch an die NC |
0.75M H.Buss 29.09.2009 |
- Spektrum-Timing wird nun überwacht |
- die FC kann nun stand-Alone als Kamera-Stabilizer eingesetzt werden, weil die Servos aktiviert werden, wenn I2C fehlt |
0.75N H.Buss 29.09.2009 |
- Hoover-Stickpunkt wird bei aktivem Höhenregler nicht nachgeführt |
- Hoover-Stickpunkt kann per Parameter fest eingestellt werden |
- Baro-Messbereichserweiterung auch bei aktiviertem Höhenregler |
- Gyro_Gier_P und Gyro_Gier_I eingeführt |
- I2C_fehler-Zähler jetzt in den Analogdaten |
0.75o H.Buss 01.10.2009 |
- der Höhenregler wird jetzt nur alle 10ms bearbeitet |
- Baro-Messbereichserweiterung auch bei Poti als Sollwert |
0.76d H.Buss 10.10.2009 |
- bei aktiver Messbereichserweiterung wird die aktuelle Höhe übernommen |
0.76e H.Buss 27.10.2009 |
- es werden beim Start einmal alle BL-Regler angesprochen, damit BL-Regler#8 auch einen Selbsttest macht |
- S3D-ACT-Summensignal als Compilerschalter |
0.76f H.Buss 05.11.2009 |
- untere Spannungsgrenze der Unterspannungswarnung (9,3V) entfernt |
0.76g H.Buss 10.11.2009 |
- Casting-Fehler in der Gas-Berechnung |
0.77a H.Buss 11.11.2009 |
- Erweiterung auf 12 Kanäle |
- Bei Koptertool-Kanalabfrage kein Empfangsausfall-Piepsen |
- serielle Kanalerweiterung eingebaut -> PPM_in auf 25 erweitert |
- Servos3-5 einstellbar |
- neues Kommando "f" -> schaltet auf anderen Parametersatz um |
0.77b H.Buss 09.12.2009 |
- JetiBox: Menü wird übertragen |
- neu: FCFlags |= FCFLAG_I2CERR; |
- LED-Warn-Blinken nun mit festem Timing und abschaltbar |
0.77c H.Buss 07.01.2010 |
- zwei weitere Spektrum-Varianten implementiert |
0.77d H.Buss 25.01.2010 |
- Strom-Messung eingebaut |
0.78a H.Buss 03.02.2010 |
- Bugfix: Settingsumschaltung im Flug |
0.78b H.Buss |
- veröffentlichte Version |
0.78c H.Buss + G.Stobrawa 22.2.2010 |
- Bewegungsbegrenzung an Servo 3 to 5 der FC 2.0 |
- Theoretischer Variablenüberlauf bei Vario-Höhenregler |
- Anzeige des "SPI RX communication error" wenn GPS Option nicht aktiv |
- LED-Schwellwerte fürs Blinken waren unterschiedlich |
0.78c H.Buss + G.Stobrawa 04.3.2010 |
- Code cosmetics |
0.78f H.Buss + I.Busker 23.3.2010 |
- Unterstützung für Jeti-Expander |
- Begrenzung des Vario-Höhenreglers auf ein 10m-Fenster um Überläufe zu verhindern |
- Einführung eines Vario-Zeichens (+/-/ ) auf der Jetibox |
- BL-Timeout beim Start erhöht |
0.80a-d H. Buss + G.Stobrawa 20.5.2010 - 22.7.2010 |
- Motoren Starten nicht ohne Kalibrierung |
- Unterstützung der BL2.0-Regler |
- statt 8 nun 10 Bit Auflösung der Lageregekung |
- Unterstützung der BL2.0-Regler Konfiguration via MK-Tool |
- Parametersätze werden per I2C an die BL-Regler durchgereicht |
- "Care-Free" implementiert |
- Freie Belegung der "Vorne"-Richtung |
- nur wenn Motoren laufen: Beepen, wenn Carefree ohne Navi oder ohne gültigen MK3Mag-Wert |
- nur wenn Motoren laufen: Beepen wenn NC plötzlich ausfällt |
- #define RECEIVER_SPEKTRUM_EXP eingeführt |
- #define SWITCH_LEARNS_CAREFREE eingeführt |
- Schwerpunktanzeige in den 3D-Daten |
- Checksummen gesicherte Datenablage im EEProm |
- Fehlerdiagnose implementiert (Wiki: ErrorCodes) |
- ErrorCode aufs Jeti-Display |
- JetiMenü: bis acht Temperaturen der BL-Regler |
- GPSInfo.Speed im Jeti-Display |
- Compass-Richtung nun im Jeti-menü |
- diverse Änderungen im Höhenregler |
- P wirkt schwächer |
- D wirkt stärker |
- Anpassung der Höhenregelung auf Level des Hoovergases |
- AccZ schneller nachführen |
Parameter modifiziert: |
- EEPROM-Kompatibilität auf 84 -> Parameter werden resettet |
- EE_Parameter.Hoehe_ACC_Wirkung = 0; // war 30 |
- EE_Parameter.Hoehe_HoverBand = 8; // war 5 |
- Notgas = 45 |
- NotgasZeit = 90 |
- Beginnersetting: EE_Parameter.DynamicStability = 70; |
- Neu: GyroStability = 6 |
- GPS-Login-Time auf 2 reduziert |
0.80e H.Buss 02.08.2010 |
- MK3Mag ohne NC ging nicht |
0.80f H.Buss 04.08.2010 |
- Beim Höhenregler "Deckel" wird das Gas wieder wie in der alten Version behandelt und der D-Anteil auf das alte Verhalten (um Faktor 8) reduziert |
0.80g H.Buss 11.08.2010 |
- erweitetern Messbereich für Luftdruck bei der FC2.1 aktiviert |
0.80h H.Buss 30.08.2010 |
- bei I2C-Fehlern wurden die Counter zurück gesetzt und für einige ms die Interrupts angehalten - das ist jetzt behoben |
- Nur I2C-Daten senden, wenn das alte Paket komplett raus ist |
0.82a H.Buss 08.11.2010 |
- MotorSafetySwitch - Verriegelt das Ein/Ausschalten |
- ServoManualControlSpeed - Verlangsamt das Cam-Servo |
- CamOrientation - für verdrehte Kamera-Servos |
- Position der Status-Bits verändert |
- "Zucken" der Servos bei kurzen Empfangsausfällen behoben |
- jeti update command 'j' added |
- Poti-Auswertung nach ParameterZuordnung() verschoben -> FC-Code schneller |
- Waypont-Events z.B. zum Triggern der Kamera |
- Gyro-Sytbility: Werte bis 16 möglich |
0.82b H.Buss 08.12.2010 |
- Unterstützung von 3,3V-Referenzspannung (nur ATMEGA128) |
0.84a H.Buss 21.03.2011 (Release: 30.03.2011) |
- nur starten, wenn NC_ErrorCode = 0 |
- Beeptime von NC auch beim Kalibrieren durchlassen |
- Varible "JetiBeep" eingeführt |
- Kompass-Winkelvorgabe von NaviControl -> POI |
- Piepen beim Umschalten von CareFree |
- Compass-Routinen überarbeitet |
- Dafaultvalues Servo-Min/MAx an MKDS18 angepasst |
- Defaultreceiver ist RECEIVER_JETI |
- GPS-Operation-Radius per default auf 245m bzw. 100% |
- Höhenvorgabe im Vario-Mode durch Waypoints |
- bei laufenden Motoren keine neuen Settings annehmen |
- immer einmal Carefree Beepen nach dem Kalibrieren |
- Kanaloffset für Potis von 110 auf 127 erhöht, damit es gleich ist mit allen anderen Kanälen |
- POI-Richtung (Soll-Himmelsrichtung) bezieht sich auf den Kamera-Winkel |
0.86a H.Buss 13.09.2011 |
- Variable "JetiBeep" wird gelöscht, wenn an den Empfänger gesendet wurde |
- wenn GPS deaktiviert ist, keinen Fehler bringen, wenn GPS fehlt. Auch dann nicht piepsen |
- GPS-Sollwertverschiebung |
- Empfangs-Piepen unterdrücken -> einstellbar |
- MotorSmooth einstellbar |
- Höhenregler: keine 'harte' IstWert-Übernahme bei Bewegen des Sticks in die Hoover-Position |
- Coming Home mit Höhenvorgabe |
- Coming Home als Failsafe |
- Einführung des GPS-Characters (- / W H D P) |
- Klartext bei den Jeti-Fehlermeldungen |
- Jeti-Beep "3*kurz" bei NC-Errors |
- Jeti-LCD-Aufruf nur noch alle 300ms, weil die Werte zu unruhig waren |
- Mixer-Settings werden nicht gelöscht, wenn sich die Parameter-Revision ändert |
- GPS-Angle limit von 100 auf 140 |
- GPS-I-Limit von 75 auf 85 |
- GAS-Offset von 120 auf 127 erhöht, damit es für alle Kanäle gleich ist |
- EE_Parameter.Hoehe_StickNeutralPoint auf Werte zwischen 80 und 180 begrenzt |
- PPM_Neutral eingeführt, um den Offset bei HoTT auszugleichen; |
- LED_Update() nun nur noch alle 20ms, weil die schnellste Ausgabe (bei Potivorgabe) ohnehin nur 40ms sind |
- Jeti & HoTT: Nur beim Fehler auch JetiBeep, wenn die Motoren laufen -> sonst nervt das bei der Fehlerbehebung (Compass-Kalibrieren usw.) |
- Error-Text auch im virtuellen Display des Koptertools |
- virtuelles LCD-Menü: |
- "ExternControl" aus Platzgründen aus dem virtuellen LCD-Menü entfernt. |
- keine BL-Temperaturen und I2C-Fehler anzeigen, wenn die BL-Regler nicht verwendet werden |
- nach dem Gieren nicht den Ersatzkompass auf den Kompasswert stellen, die Umschaltung war zu hart |
- ACC Correction eingeführt |
- I2C Fehler kamen nicht bei der NC an, weil die zu kurz waren - jetzt meldet die NC die Fehler mind. 8 Sekunden |
- Fehlermeldungen stehen jetzt mind. so lange an, bis sie an die Nc ge sendet wurden |
- neue Fehlermeldungen: |
"No NC communicat", // 9 |
"GPS Fix lost ", // 21 |
"Magnet Error ", // 22 |
"Motor restart ", // 23 |
"BL Limitation " // 24 |
- LED: Schaltfläche "nur bei Motor start" bei beiden getrennt |
- Ausbau der HoTT-Telemetrie |
- Variable "KompassRichtung" entfernt |
- ErsatzKompassInGrad sinvoll genutzt |
- HoTT-Update per Uart-Durchschleifen |
- AltitudeSetpointTrimming eingeführt |
- Vario-Anzeige für HoTT |
- Verhindern eines Überlaufs im Vario |
- echter Varioton auch ohne Vario-Höhenregler |
- Flugminuten laufen jetzt bei (FC_StatusFlags & FC_STATUS_FLY) los, weil sonst die Zeit zur NC verschieden war |
- KompassFusion wird jetzt getrennt von der NC berechnet |
- Sport-Setting entfernt und ein "Easy-Setting" eingeführt (leicht reduzierte Sticks); "Beginner" ist jetzt "Normal" |
- MagnetError kann man in der Startphase ignorieren |
- BL-Temperaturen, I2C-Fehler und BL-MaxPWM zum Loggen an NC |
- Einzelströme nun auch bei HoTT angezeigt |
0.86b H.Buss 20.09.2011 |
- Höhenbegrenzung bewirkt nur, dass im Vario-Mode der Sollwert nicht weiter nach oben geschoben werden kann |
- grüne LED ging aus - gefixt |
- K1-K8 wurden im LCD mit 0-7 bezeichnet |
0.86c H.Buss 22.09.2011 |
- Neue Anzeige: Magnetfeld und Inklination bei HoTT und Jeti |
- Neuer SPI-Block 'SPI_MISC' |
- Kompass-Fusions-Dämpfung bei Neigung leicht verringert |
- '.' im Vario-Höhenregler |
0.86d H.Buss 26.09.2011 |
- Analog.c: Vario Überlauf anders verhinden |
- Poti1-6 auch im HoTT-Display |
0.88 H.Buss 12.12.2011 - 26.03.2012 |
- Failsafe-Kanal |
- Failsafe: 5 Sekunden warten & Höhe ändern (macht die NC) |
- Option: Failsafe-Sinkflug xx% Schwebegas |
- Stopp der Motoren wenn bei Failsafe ein Motor blockiert |
- von 30 auf 60 Sekunden Failsafe-Zeit verlängert |
- Höhenwert auf cm kalibriert (zeigte ca. 10% zu viel an) |
- Neue Error-Codes: "No SD-Card", "Flying range!" und "Error SD-Logging" |
- Wenn die Motoren aus sind, den Luftduckwert langsam nachführen |
- das sbus-protokoll implementiert (nur FC2.1) |
- Schaltkanal auf Servo-Ausgang |
- Filter auf den Ausgängen der Servos |
- Option: Failsafe-Sinkflug xx% Schwebegas |
- "Max Altitude" als Parameter auf der SD-Karte im Navi -> Beeinflusst "Parameter_MaximumAltitude" (das niedrigste gilt) und es gibt eine Fehlermeldung "ERR:Max Altitude" |
- SPI-Protokoll: BL.Status eingefügt und Parameter.GlobalConfig & Parameter.ExtraConfig verschoben |
- Senden der Out1 & Out2-Zustände an die NC, damit es in der OSD-Darstellung angezeigt werden kann |
- Kompassrichtung neu merken, wenn CF geschaltet wird |
- "I" aus dem Hott-Menü entfernt und durch ":" ersetzt, weil das nur auf der mx-20 gut aussah |
- Höhenregler-Settings: GPS-Z von 64 auf 20 reduziert |
0.88M H.Buss 15.05.2012 |
- HoTT V4 |
- Kamera-Servo beim Kalibrieren weiter laufen lassen. |
- Error 30: no GPS fix bei Start |
- echter MotorSchalter |
0.88n H.Buss 06.07.2012 |
- Bugfix: Der letzte angesteuerte Servo-Puls war zu kurz |
0.90 H.Buss 04.03.2013 |
- Anzeige WP x/Y in der HoTT-Telemetrie |
- Schalter und WP-Event gleichzeitig |
- Photo-Auslösung als Entfernungsintervalle |
- Jeti + |
- Kamera-Neitung als Integral |
- RC-Lost am Startpunkt macht kein Failsafe, wenn GAS auf Null für 1,5sek war |
- Auswahl:Speak-All nun in der KopterTool-Config |
0.90e H.Buss 04.03.2013 |
- Parameter_ServoRollComp jetzt auf Poti /Kompatibilität auf 93 erhöht) |
0.90f (26.04.2013) |
- disable Yawing when Gas-Stick is to Zero |
- calibration must be within 20° Tilt angle |
- Hold I-Parts of the attitude control to zero when the MK is still on the ground |
- ACC-Altitude sensor data fusion implemented to the altitude controller (HW-Update from FC2.1 to 2.2 needed) |
- MK must be within 20° tilt angle when calibrating sensors |
- Parameter Reset, if the HW-Version changes (FC2.1 to 2.2) |
0.90g (29.04.2013) |
- No ACC-Z error if the MK is tilted after switching on |
- ATMEGA644 (until FC2.0): Sensitive RC-Signal validation removed -> that was only nessecary for old 35MHz receivers |
0.90h (14.05.2013) |
- Auto Start and landing for Waypoints |
- back to old eeprom-compatiblity to remain compatible to other Tools |
- HoTT-Bugfix: no speech while vario tone |
- Bugfix: Wrong error speech in JetiEX ("Error calibration") |
0.90j (27.05.2013) |
- Changes for better EEPROM-Safety |
- variable ActiveParamSet instead of the direct EEPROM-Reading (faster) |
- Checking the ACC-Z value in flight and report ACC-Z if out of range |
- disable Altitude hold in case of ACC-Z error |
2.00a (after public Beta test 0.91) |
- show SW-Version in Hot Display |
- GPS-Parameter changed (P = 90->100; I = 90->90; D = 90->120; A = 40) |
- Move NICK/Roll Sticks for switching on / off |
- Move the Stick > 100 instead > 75 for switch on / off |
- Failsafe active if ACC-Upgarde |
- AltitudeMode, GPS_Mode & Carefree_Mode are now direct channels instead of Poti-Values (NaviGpsModeChannel,CareFreeChannel,HoeheChannel) |
- NC-SPI communication from 25Hz to 41Hz |
- MotorTemperature and GPS-Mode-Switch more often to NC |
- Auto-Start/Landing |
- JetiEX: Name set to 'MK' |
- if(CareFree) Parameter_AchsKopplung1 += 30; removed |
- StickNeutral setting per default 127 |
- UART-Buffer increased from 175 to 220 Bytes |
- show name of active parameter set in the HoTT/Jeti display |
- fixed in 0.91L: if "ServoRelative" is used, it coud happen that the servo moves a wide range in the first second after the first calibration |
- Servo3-5 Limit to 24-255 |
- no. of channels increased from 12 to 16 |
// 0 -> frei bzw. ACT rssi (or zero if unsigned) |
// 1 - 16 -> 1-16 |
// 17 - 28 -> 12 Serial channels |
// 29 -> WP-Event kanal |
// 30 Fix -> -127 |
// 31 Fix -> 0 |
// 32 Fix -> 128 |
2.00b |
- default Camera-Position after calibration changed if Inverted |
- some changes in ACC-Altitude hold to reduce climbing in fast foreward fly |
- UserParameter1 > 100 disables camera nick control (for BL-Gimbals with self-alignments) |
- Beep at motor off (1sek) |
2.00d |
- Do not start if MK is moving |
- Full Range of altitude measure expansion (3000m flight instead of 950m) |
- compensation of the atmospheric altitude error |
- Measure the exact influence of the barometric range extender |
- Reduce Nick/Roll if Gas is Zero -> avoids MK to turn over during switch-off sequence |
- Tell NC to wait at the Waypoint until Out1 Pattern is over |
- virtual menu: single BL-Currents (FC2.1) |
- per default active: NO_GPSFIX_NO_START and CFG_NO_RCOFF_BEEPING |
- Servo-Nick-Refres reduced from 4 to 3 in default setting -> makes the camera servos faster |
- No undervoltage Beeping if the FC is only supplied by MKUSB (the Voltage measurement is zero) |
- Reset I2C-Error counter when calibrating the Sensors |
- HOTT & Jeti bugfix: The temperatures were sometimes wrong |
- HoTT: |
- GPS coordiante now in Degree + Minutes.Decimalminutes (like in original Graupner-Receivers) |
- added the MK Status in Transmitter Logfile -> General->Fuel |
- added the MK Speach in Transmitter Logfile -> General->Alt3Sek |
2.02a |
- code too big for MEGA644 -> only ATMEGA1284 supported |
- Jeti:GPS-Koordinate |
- Don't accept Reset-Command if Motor running |
- 'Idle' Bit in Output-Mask |
- Option: DisableServoNick |
- Bugfix Maximum Altitude -> New: SpeakHoTT Errormessage = "MaximumAltitude" and VarioCharacter goes to '=' |
- New Error code 32 "ERR:BL Selftest" |
- prepared for current measurements up to 75A per ESC |
- reduced speed of capacity-calculation() from 10ms to 50ms - that should be fast enough |
- Timing correction for NC-Data (41Hz) |
- Autolanding if undervoltage |
- Compass offset angle |
- 0.2V hysteresis in undervoltage warning |
- Fixed: Bug in LED-Output |
- Autolanding per default at 3,1V |
2.02b |
- Bugfix: Data reading for Dodecas (12 motors) |
2.04a (12.03.2014 after public betatest 2.03) |
- No support for FC 1.x |
- Bugfix: set ChannelYaw to zero in case of RC lost |
- Bugfix: Max 6 cells in lipo-detection instead of 7 |
- Bugfix: Compass-Calibration: At the second comdass calibration, the Calibration started in step 2 and not in step 1 |
- increase the allowed band for Auto-Middele-Point of the AltitudeStick to 70-175 |
- Dodeca: reduced I2C Packet lenght to 8 |
- Auto-ComingHome at Undervoltage |
- Voltage measurement was 3% too high |
- allowed band for ACC-Z increased to: 652 - 717 |
- send 'K' command only if JustMK3MagConnected |
- Redundant operation supported |
- Loading Waypoints from SD-Card: |
- menu by HoTT and Jeti added |
- Show the name of the WP-List |
- do not load points if no stafix |
- Version for FC 2.0 with ATMEGA644 |
Not Supported in FC 2.0: |
- ACC-Upgrade for better ACC-Altitude control |
- Hott |
- Jeti-EX |
- Auto-Start & Landing |
- WP-List Name |
2.04b |
- Bugfix: Poti Values were wrong after calibration |
- Redundant Slave: LED-Binking: Green: UART Data & Red:I2C error |
- CompassCorrected (True-Compass) in HoTT- and Jeti-Display |
- "True Compass" in virtual menu |
- Jeti: Indicator "R" for redundancy |
2.04c |
- S.Bus extended to 16 Channels |
2.06a (09.04.2013 after public beta 2.05) |
- Load/Store Single Point |
- Photo-Releases on Altitudes |
- Voltage warning set to 3,2V, because the Voltage measurement was lower than before |
- new Parameter: SinglePoint Speed |
- Counter for Motor-Restarts for each single motor |
- Servo-Signals can be configured if mapped to output |
- Speak "Error_Motor" as soon as one Motor reports a restart |
- EE_Parameter.NaviDescendRange now as Parameter in EEPROM |
- EE_Parameter.NaviMaxFlyingRange now as Parameter in EEPROM |
- Maximum Altitude is also used in the NC instead of "ABSOLUTE_FLYING_ALTITUDE" from SD-Card |
2.06b (05.05.2014) |
- Change for redundant slave: Now the Status of all 8 BLs can be read |
2.06c (10.05.2014) |
- send EE_Parameter.CamOrientation to NC |
- Bugfix: if the CamOrientation was not zero, the direction in load/store Singelpoints were not correct |
2.06d (16.06.2014) |
- Starting with activated Altitudecontrol: Keep setpoint -2m until Gas-Stick rises up |
- Bugfix: Redundant slave: wait at start until BLc are configured |
2.06e (24.06.2014) |
- Bugfix: BL-Config of motors 9-12 was deactivated |
- reading the SW-Version of the BLs |
- Bugfix: Motor 1 sometimes reported "software not compatible" in BL-Settings |
- Transmit all version numbers to KopterTool |
2.06f (21.7.2014) |
- Secure function: Avoid that the Altitude setpoint can be much higher than the actual altitude |
- Use MinGas setting before while "Waiting for takeoff" instead of "AltitudeMinGas". |
2.06g |
- don't start motors when NC is in simulation mode |
- correct behaviour if CompassEffect is zero |
2.08a (10.10.2014) |
- Redundance now In Flag3 |
- Boat-Mode implemented |
- New Gyro DriftCompensation implemented |
- sending Offset values to NC for Logging |
- Menu: Neutral Values of Gyro now in full resolution |
- camera releases via automatic distances faster than 1 sec |
- clamp Altitude setpoint at +15m instead of +10m to allow faster starting |
- set all channels to zero in case of RC-Lost |
- removed: GPS_Z |
- New Parameter: Parameter_Hoehe_TiltCompensation |
- Default Failsafe-Time is 60sec (was 30sek before) |
- Sensitive_RC removed |
- Bugfix: WP-Event was sometimes triggered two times |
- transmit HoverGas to NC for logging |
2.08b (09.02.2015) |
- reduced load on UART for redundant slave when motors are not running |
2.10a (10.11.2014 - 17.04.2015) |
- New data structure of ExternalControl |
- Internal Copies of the Channel values |
- NC-Yawing rate limited to 100°/sec |
- ExpandBaro faster -> 80ms instead of 700ms |
- Altitude measurement re-calibrated (the measured value was about 5% too high) |
- transmit receiver type to NC |
- transmit stored neutral values (BOAT) to NC |
- SPI communication optimized -> some Data are faster, some are slower |
- BL-State (Current, Temperature,...) are now faster transferred for Logging |
- ComingHome: automatic Direction change |
- allows Yawing without CareFree (Yawing at Coming Home) |
- Bugfix: Output LED Blinking when RC-Lost |
- bugfix: uBat in 16Bit |
- AnalogLable CRC implemented -> KopterTool doesn't need to read them every time |
- ShutterCounter -> counts up when the output switches from low to high |
- transmit LipoCount to NC |
- Config "Disable CameraCompensation" disables also Roll-Compensation now |
- AccZ in 3D-Datastructure (for Ben) |
- new Parameter: LandingAccZ |
- 16 Motors |
- in-flight HoTT: Motortest and ACC-Calibration |
- Error Message: No Redundancy |
- Error Message: Redundancy Test |
- Redundant Slave: copy the Current, State and Temperature from the UART Data |
- in-flight ACC-Calibration with Jeti and KopterTool |
- ACC-Calibration by stick: 5 seconds delay |
- Bugfix: LED pattern was not used more often if the Hold time was longer than the pattern time |
- Servo Failsafe Positions implemented |
-> That Position is used for RC-Lost and UnderVoltage-Autolanding |
-> minimum 10 seconds active |
- MULTIPLEX servo protocol implemented (12 & 16 Channels) |
2.10b (28.04.2014) |
- small changes for the case of "NC-Communication loss" |
2.10c (11.05.2015) |
- Redundancy Master: If the I2C-Bus was switched off before flight (motors idle runnung), the Master didn't go into 'Fly'-State |
- Auto-Safe by transmitter-switch: UserParameter5 can be used in Menu "Save single position" |
- Auto-Load by transmitter-switch: UserParameter5 in Menu "Load single position" |
2.10e (13.07.2015) |
- ERR38: "GPS Update Rate" if Update Rate is lower than 5Hz |
- Parameter.FailSafeTime now in Logfile |
- Continous SPI-Transmission during calibration -> avoids different error-messages like "No FC Communication" etc. |
- Axisdecoupling can't be deactivated |
2.12a (12.10.2015) |
- SingleWpControlChannel -> 3-stage switch for store/call single point |
- MenuKeyChannel -> Key for Jeti/HoTT-Menu: Single points |
- REDUNDANT Slave doesn't report 'CareFree-Error' |
- Load Points via Switch on transmitter without using a menu |
- AxisDecoupling can't be deactivated |
- ExternalControlTimeout activated (2 seconds) |
toDo: |
- CalAthmospheare nachführen |
/tags/V2.12a |
---|
Property changes: |
Added: tsvn:logminsize |
+8 |
\ No newline at end of property |