From c67ba218fad9033cf5965489e65cbd66b0b7ea15 Mon Sep 17 00:00:00 2001 From: bsongis Date: Thu, 19 Jan 2012 11:10:02 +0000 Subject: [PATCH] Port for DSM2 pulses, Port for SOMO module, ModelMatch function switch, French translations. --- src/Makefile | 8 +- src/frsky.cpp | 13 -- src/frsky.h | 2 + src/myeeprom.h | 3 + src/o9xstrings.cpp | 7 -- src/o9xstrings.h | 7 +- src/open9x.cpp | 82 +++++++++---- src/open9x.h | 62 ++++++---- src/pers.cpp | 33 ++++- src/pulses.cpp | 271 +++++++++++++++++++++++----------------- src/somo14d.cpp | 142 +++++++++++++++++++++ src/somo14d.h | 21 ++++ src/translations/en.h | 7 +- src/translations/fr.h | 279 ++++++++++++++++++++++++++++++++++++++++++ 14 files changed, 745 insertions(+), 192 deletions(-) create mode 100644 src/somo14d.cpp create mode 100644 src/somo14d.h create mode 100644 src/translations/fr.h diff --git a/src/Makefile b/src/Makefile index f26b46226..7086cf5c8 100644 --- a/src/Makefile +++ b/src/Makefile @@ -346,8 +346,12 @@ ifeq ($(PXX), YES) CPPDEFS += -DPXX endif -ifeq ($(DSM2), YES) - CPPDEFS += -DDSM2 +ifeq ($(DSM2), SERIAL) + CPPDEFS += -DDSM2 -DDSM2_SERIAL +endif + +ifeq ($(DSM2), PPM) + CPPDEFS += -DDSM2 -DDSM2_PPM endif ifeq ($(SILVER), YES) diff --git a/src/frsky.cpp b/src/frsky.cpp index 226c8e0cb..6f92138b2 100644 --- a/src/frsky.cpp +++ b/src/frsky.cpp @@ -339,19 +339,6 @@ ISR(USART0_RX_vect) UCSR0B |= (1 << RXCIE0); // enable Interrupt } -/* - USART0 Transmit Data Register Emtpy ISR - Used to transmit FrSky data packets -*/ -ISR(USART0_UDRE_vect) -{ - if (frskyTxBufferCount > 0) { - UDR0 = frskyTxBuffer[--frskyTxBufferCount]; - } - else { - UCSR0B &= ~(1 << UDRIE0); // disable UDRE0 interrupt - } -} #endif /******************************************/ diff --git a/src/frsky.h b/src/frsky.h index fe4eca039..a199dcec7 100644 --- a/src/frsky.h +++ b/src/frsky.h @@ -100,6 +100,8 @@ extern uint8_t FrskyAlarmSendState; extern FrskyData frskyTelemetry[2]; extern FrskyData frskyRSSI[2]; +extern uint8_t frskyTxBuffer[FRSKY_TX_PACKET_SIZE]; +extern uint8_t frskyTxBufferCount; void FRSKY_Init(void); void FRSKY10mspoll(void); diff --git a/src/myeeprom.h b/src/myeeprom.h index 868429e22..6492edbc2 100644 --- a/src/myeeprom.h +++ b/src/myeeprom.h @@ -171,6 +171,9 @@ enum Functions { FUNC_TRAINER_AIL, FUNC_INSTANT_TRIM, FUNC_TRIMS_2_OFS, +#if defined(DSM2) + FUNC_MODELMATCH, +#endif #ifdef LOGS FUNC_LOGS, #endif diff --git a/src/o9xstrings.cpp b/src/o9xstrings.cpp index 704823fb8..e6a054d62 100644 --- a/src/o9xstrings.cpp +++ b/src/o9xstrings.cpp @@ -1,12 +1,5 @@ #include "open9x.h" -#ifdef TRANSLATIONS_FR -#include "translations/fr.h" -#else -#endif - -#include "translations/en.h" - // The non-0-terminated-strings const prog_char APM STR_OPEN9X[] = TR_OFFON diff --git a/src/o9xstrings.h b/src/o9xstrings.h index 399d2d805..0fc58bc66 100644 --- a/src/o9xstrings.h +++ b/src/o9xstrings.h @@ -1,12 +1,13 @@ #ifndef o9xstrings_h #define o9xstrings_h -#ifdef TRANSLATIONS_FR +#if defined(TRANSLATIONS_FR) #include "translations/fr.h" +#elif defined(TRANSLATIONS_IT) +#include "translations/it.h" #else -#endif - #include "translations/en.h" +#endif #define PSIZE(x) ( sizeof(x) - 1 ) diff --git a/src/open9x.cpp b/src/open9x.cpp index 346d161d1..ee78d4be9 100644 --- a/src/open9x.cpp +++ b/src/open9x.cpp @@ -2026,6 +2026,54 @@ uint16_t DEBUG2 = 0; #endif +/* + USART0 Transmit Data Register Emtpy ISR + Used to transmit FrSky data packets and DSM2 protocol +*/ + +#if defined (FRSKY) +FORCEINLINE void FRSKY_USART0_vect() +{ + if (frskyTxBufferCount > 0) { + UDR0 = frskyTxBuffer[--frskyTxBufferCount]; + } + else { + UCSR0B &= ~(1 << UDRIE0); // disable UDRE0 interrupt + } +} +#endif + +#if defined (DSM2_SERIAL) +FORCEINLINE void DSM2_USART0_vect() +{ + UDR0 = *pulses2MHzRPtr; + + if (++pulses2MHzRPtr == pulses2MHzWPtr) { + UCSR0B &= ~(1 << UDRIE0); // disable UDRE0 interrupt + } +} +#endif + +#ifndef SIMU +#if defined (FRSKY) or defined(DSM2_SERIAL) +ISR(USART0_UDRE_vect) +{ +#if defined (FRSKY) and defined (DSM2_SERIAL) + if (g_model.protocol == PROTO_DSM2) { + DSM2_USART0_vect(); + } + else { + FRSKY_USART0_vect(); + } +#elif defined (FRSKY) + FRSKY_USART0_vect(); +#else + DSM2_USART0_vect(); +#endif +} +#endif +#endif + #if defined (PCBV3) /*---------------------------------------------------------*/ /* User Provided Date/Time Function for FatFs module */ @@ -2159,10 +2207,10 @@ int main(void) DDRE = 0b00001010; PORTE = 0b11110101; // 7:PPM_IN, 6: RENC1_B, 5:RENC1_A, 4:USB_DNEG, 3:BUZZER, 2:USB_DPOS, 1:TELEM_TX, 0:TELEM_RX DDRF = 0x00; PORTF = 0x00; // 7-4:JTAG, 3:ADC_REF_1.2V input, 2-0:ADC_SPARE_2-0 DDRG = 0b00010000; PORTG = 0xff; // 7-6:N/A, 5:GearSW, 4: Sim_Ctrl[out], 3:IDL1_Sw, 2:TCut_Sw, 1:RF_Power[in], 0: RudDr_Sw - DDRH = 0x00; PORTH = 0xff; // 7:0 Spare port -- all inputs for now [Bit 2:VIB_OPTION -- setting to input for now] + DDRH = 0b00110000; PORTH = 0b11011111; // 7:0 Spare port [6:SOMO14D-BUSY 5:SOMO14D-DATA 4:SOMO14D-CLK] [2:VIB_OPTION -- setting to input for now] DDRJ = 0x00; PORTJ = 0xff; // 7-0:Trim switch inputs DDRK = 0x00; PORTK = 0x00; // anain. No pull-ups! - DDRL = 0x00; PORTL = 0xff; // 7-6:Spare6/5 (inputs), 5-0: User Button inputs + DDRL = 0x80; PORTL = 0x7f; // 7: Hold_PWR_On (1=On, default Off), 6:Jack_Presence_TTL, 5-0: User Button inputs #else # if defined (PCBV3) DDRB = 0x97; PORTB = 0x1e; // 7:AUDIO, SD_CARD[6:SDA 5:SCL 4:CS 3:MISO 2:MOSI 1:SCK], 0:PPM_OUT @@ -2265,10 +2313,14 @@ int main(void) sei(); // interrupts needed for FRSKY_Init and eeReadAll. -#if defined (FRSKY) +#if defined (FRSKY) and !defined (DSM2_SERIAL) FRSKY_Init(); #endif +#if defined (DSM2_SERIAL) and !defined (FRSKY) + DSM2_Init(); +#endif + #ifdef JETI JETI_Init(); #endif @@ -2340,29 +2392,7 @@ int main(void) /***************************************************/ #endif -/***********************************************************/ -/*** Keep this code block directly before the main loop ****/ - - setupPulses(); - -#if defined (PCBV4) - OCR1B = 0xffff; /* Prevent any PPM_PUT pin toggle before the TCNT1 interrupt - fires for the first time and sets up the pulse period. */ - // TCCR1A |= (1< FORCEINLINE t abs(t a){ return a>0?a:-a; } +template FORCEINLINE t abs(t a) { return a>0?a:-a; } /// liefert das Minimum der Argumente -template FORCEINLINE t min(t a, t b){ return a FORCEINLINE t min(t a, t b) { return a FORCEINLINE t max(t a, t b){ return a>b?a:b; } -template FORCEINLINE t sgn(t a){ return a>0 ? 1 : (a < 0 ? -1 : 0); } -template FORCEINLINE t limit(t mi, t x, t ma){ return min(max(mi,x),ma); } +template FORCEINLINE t max(t a, t b) { return a>b?a:b; } +template FORCEINLINE t sgn(t a) { return a>0 ? 1 : (a < 0 ? -1 : 0); } +template FORCEINLINE t limit(t mi, t x, t ma) { return min(max(mi,x),ma); } /// Markiert einen EEPROM-Bereich als dirty. der Bereich wird dann in /// eeCheck ins EEPROM zurueckgeschrieben. @@ -600,31 +611,27 @@ extern inline uint16_t get_tmr10ms() #define TMR_VAROFS 5 +void startPulses(); void setupPulses(); +void DSM2_Init(); +void DSM2_Done(); +void resetProto(); #ifdef LOGS extern void startLogs(); extern void doLogs(); #endif -#include "lcd.h" +// TODO needed? +extern uint16_t *pulses2MHzRPtr; +extern uint16_t *pulses2MHzWPtr; + extern const char stamp1[]; extern const char stamp2[]; extern const char stamp3[]; extern const char stamp4[]; extern const char stamp5[]; -#include "myeeprom.h" - -#ifdef JETI -// Jeti-DUPLEX Telemetry -extern uint16_t jeti_keys; -#include "jeti.h" -#endif - -#if defined (FRSKY) -// FrSky Telemetry -#include "frsky.h" -#endif +extern const char stamp6[]; #ifndef BATT_UNSTABLE_BANDGAP extern uint16_t abRunningAvg; @@ -636,6 +643,7 @@ extern volatile uint16_t g_tmr10ms; extern volatile uint8_t g_blinkTmr10ms; extern uint8_t g_beepCnt; extern uint8_t g_beepVal[5]; +// TODO needed? extern const PROGMEM char modi12x3[]; #include "o9xstrings.h" diff --git a/src/pers.cpp b/src/pers.cpp index c2fcad32e..d84df890e 100644 --- a/src/pers.cpp +++ b/src/pers.cpp @@ -123,16 +123,41 @@ void eeLoadModel(uint8_t id) // TODO optim: resetAll() resetTimer(0); resetTimer(1); -#ifdef FRSKY - resetTelemetry(); - FRSKY_setModelAlarms(); -#endif + resetProto(); #ifdef LOGS startLogs(); #endif } } +void resetProto() // TODO inline this if !DSM2_SERIAL +{ +#if defined(DSM2_SERIAL) + if (g_model.protocol == PROTO_DSM2) { + cli(); +#if defined(FRSKY) + DSM2_Init(); +#endif + sei(); + } + else { + cli(); +#if defined(FRSKY) + FRSKY_Init(); +#else + DSM2_Done(); +#endif + sei(); +#if defined(FRSKY) + FRSKY_setModelAlarms(); +#endif + } +#elif defined(FRSKY) + resetTelemetry(); + FRSKY_setModelAlarms(); +#endif +} + int8_t eeFindEmptyModel(uint8_t id, bool down) { int8_t i = id; diff --git a/src/pulses.cpp b/src/pulses.cpp index 74a703cf7..1ea6c6c2f 100644 --- a/src/pulses.cpp +++ b/src/pulses.cpp @@ -21,6 +21,48 @@ #include "open9x.h" +#ifdef DSM2_SERIAL +inline void DSM2_EnableTXD(void) +{ + UCSR0B |= (1 << TXEN0); // enable TX + UCSR0B |= (1 << UDRIE0); // enable UDRE0 interrupt +} +#endif + +void startPulses() +{ +#ifndef SIMU + setupPulses(); + +#ifdef DSM2_SERIAL + if (g_model.protocol == PROTO_DSM2) { + DSM2_EnableTXD(); + OCR1A = 40000; + } + else +#endif + + { +#if defined (PCBV4) + OCR1B = 0xffff; /* Prevent any PPM_PUT pin toggle before the TCNT1 interrupt + fires for the first time and sets up the pulse period. */ + // TCCR1A |= (1< g_tmr1Latency_max) g_tmr1Latency_max = dt; - if (dt < g_tmr1Latency_min) g_tmr1Latency_min = dt; - - ++pulses2MHzRPtr; - - if (pulses2MHzRPtr == pulses2MHzWPtr) { - //currpulse=0; - pulsePol = g_model.pulsePol;//0; - // channel = 0 ; - // PulseTotal = 0 ; - -#if defined (PCBV3) - TIMSK1 &= ~(1< g_tmr1Latency_max) g_tmr1Latency_max = dt; + if (dt < g_tmr1Latency_min) g_tmr1Latency_min = dt; + heartbeat |= HEART_TIMER2Mhz; } @@ -167,7 +220,7 @@ inline void __attribute__ ((always_inline)) setupPulsesPXX() #endif -#ifdef DSM2 +#ifdef DSM2_SERIAL // DSM2 protocol pulled from th9x - Thanks thus!!! @@ -199,55 +252,56 @@ normal: */ -inline void __attribute__ ((always_inline)) _send_1(uint16_t v) +#define DSM2_CHANS 6 + +inline void __attribute__ ((always_inline)) setupPulsesDsm2() { - *pulses2MHzWPtr++ = v; + if (isFunctionActive(FUNC_LOGS)) {*pulses2MHzWPtr++ = 0x80;} + //elseif (somerangetestvariable) {*pulses2MHzWPtr++ = 0x20;} + else *pulses2MHzWPtr++ = 0x00; + *pulses2MHzWPtr++ = g_eeGeneral.currModel; + for (uint8_t i=0; i>1)+512, 1023); + *pulses2MHzWPtr++ = (i<<2) | ((pulse>>8)&0x03); + *pulses2MHzWPtr++ = pulse & 0xff; + } } -#define BITLEN_DSM2 (8*2) //125000 Baud -inline void __attribute__ ((always_inline)) sendByteDsm2(uint8_t b) //max 10changes 0 10 10 10 10 1 +void DSM2_Done() { - bool lev = 0; - uint8_t len = BITLEN_DSM2; //max val: 9*16 < 256 - for( uint8_t i=0; i<=8; i++){ //8Bits + Stop=1 - bool nlev = b & 1; //lsb first - if(lev == nlev){ - len += BITLEN_DSM2; - }else{ - _send_1(len-1); - len = BITLEN_DSM2; - lev = nlev; - } - b = (b>>1) | 0x80; //shift in stop bit - } - _send_1(len + 10*BITLEN_DSM2 -1); //some more space-time for security + UCSR0B &= ~((1 << TXEN0) | (1 << UDRIE0)); // disable TX pin and interrupt } - -inline void __attribute__ ((always_inline)) setupPulsesDsm2(uint8_t chns) +void DSM2_Init(void) { - static uint8_t dsmDat[2+6*2]={0x80,0, 0x00,0xAA, 0x05,0xFF, 0x09,0xFF, 0x0D,0xFF, 0x13,0x54, 0x14,0xAA}; +#ifndef SIMU - static uint8_t state = 0; + DDRE &= ~(1 << DDE0); // set RXD0 pin as input + PORTE &= ~(1 << PORTE0); // disable pullup on RXD0 pin - if(state==0){ +#undef BAUD +#define BAUD 125000 - if((dsmDat[0] == 0) || ! keyState(SW_Trainer) ){ //init - bind! - dsmDat[0]=0; dsmDat[1]=0; //DSM2_Header = 0,0; - for(uint8_t i=0; i>8)&0x03); - dsmDat[3+2*i] = pulse & 0xff; - } - } - } - sendByteDsm2(dsmDat[state++]); - sendByteDsm2(dsmDat[state++]); - if(state >= 2+chns*2){ - pulses2MHzWPtr--; //remove last stopbits and - _send_1(20000u*2 -1); //prolong them - state=0; - } +#include + + UBRR0H = UBRRH_VALUE; + UBRR0L = UBRRL_VALUE; + UCSR0A &= ~(1 << U2X0); // disable double speed operation. + + // set 8N1 + UCSR0B = 0 | (0 << RXCIE0) | (0 << TXCIE0) | (0 << UDRIE0) | (0 << RXEN0) | (0 << TXEN0) | (0 << UCSZ02); + UCSR0C = 0 | (1 << UCSZ01) | (1 << UCSZ00); + + while (UCSR0A & (1 << RXC0)) UDR0; // flush receive buffer + + pulses2MHzWPtr = pulses2MHz; + pulses2MHzRPtr = pulses2MHz; + setupPulsesDsm2(); + + // These should be running right from power up on a FrSky enabled '9X. + DSM2_EnableTXD(); // enable FrSky-Telemetry reception + +#endif // SIMU } #endif @@ -416,9 +470,6 @@ void setupPulses() pulses2MHzRPtr = pulses2MHz; switch(g_model.protocol) { - case PROTO_PPM: - setupPulsesPPM(); - break; #ifdef SILVER case PROTO_SILV_A: case PROTO_SILV_B: @@ -436,11 +487,13 @@ void setupPulses() setupPulsesPXX(); break; #endif -#ifdef DSM2 +#ifdef DSM2_SERIAL case PROTO_DSM2: - setupPulsesDsm2(6); + setupPulsesDsm2(); break; #endif + default: + setupPulsesPPM(); + break; } } - diff --git a/src/somo14d.cpp b/src/somo14d.cpp new file mode 100644 index 000000000..40b4325cd --- /dev/null +++ b/src/somo14d.cpp @@ -0,0 +1,142 @@ +/* + * Authors (alphabetical order) + * - Cameron Weeks + * + * gruvin9x is based on code named er9x by + * Author - Erez Raviv , which is in turn + * was based on the original (and ongoing) project by Thomas Husterer, + * th9x -- http://code.google.com/p/th9x/ + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * This program 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. + * + */ + +/* + I did think about implimenting this with an array for the timing durations + like the original bit bang DSM2 code was done but that meant another array + on top of the playlist one, therefore more memory waisted, and because + the playlist must be executed one after another it would mean putting + the code to fill the array in the interrupt (This would be unlike the + old DSM2 code) which seemed to much for the interrupt. + */ + +#include "open9x.h" + +// Start and stop bits need to be 2ms in duration. Start bit is low, stop bit is high +#define SOMOSSBIT 4 //The 2ms of a stop/start bit +#define SOMOSTOP 48 //This is the needed 2ms (4) + 20ms (40) to allow for the + //point at which the busy flag is checkable + 2ms for saftey (4) +#define SOMOSTART 60 //This is the needed 2ms (4) + 2ms (4) for safety + 26ms (52) for the + //undocumented delay that must exist between playbacks. +#define SOMOBUSY (PINH & 0x40) /* SOMO14D Busy flag */ +#define SOMOCLK (PINH & 0x10) /* SOMO14D CLK */ + +#define QUEUE_LENGTH 10 +uint16_t somo14playlist[QUEUE_LENGTH] = {0}; +uint16_t somo14command = 0; +uint8_t somo14RIdx = 0; +volatile uint8_t somo14WIdx = 0; + +#ifdef SIMU +#define BUSY busy +bool TIMER4_COMPA_vect() +#else +#define BUSY +ISR(TIMER4_COMPA_vect) //Every 0.5ms +#endif +{ + static uint16_t somo14_current; + static uint8_t i=0; + static uint8_t busy=0; // debugging make BOOL when done + static uint8_t startstop=SOMOSSBIT; // Only the first playback can have this short delay + + OCR4A = 0x7d; //another 0.5ms + + // printf("startstop=%d i=%d\n", startstop, i); fflush(stdout); + + // Send no data unless we are either not busy or it's a command + + // Only when stop bit is sent do we increment read pointer + // This will happen before the SOMO14D busy flag gets set + // Busy flag happens 20ms after the last data is clocked in + if (i==0 && !busy) { + if(somo14command) { // Allow a command to be send even if the SOMO is busy, i.e. STOP or PAUSE + somo14_current=somo14command; + } + else if (!SOMOBUSY) { + if (somo14RIdx == somo14WIdx) { + // TODO disable the interrupt (and re-enable when a new prompt is pushed)? + return BUSY; + } + somo14_current = somo14playlist[somo14RIdx]; + somo14RIdx = (somo14RIdx + 1) % QUEUE_LENGTH; + } + busy = 1; + } + + // Start and stop bits + if (busy && startstop) { + // Start bit + if (i==0) { + if (startstop < SOMOSSBIT) { // This stretches the time before we start sending data to allow for the + // undocumented delay that must exist between playbacks. Unfortunately the + // device isn't ready even though the busy flag says it is. + PORTH &= ~(1< + * + * gruvin9x is based on code named er9x by + * Author - Erez Raviv , which is in turn + * was based on the original (and ongoing) project by Thomas Husterer, + * th9x -- http://code.google.com/p/th9x/ + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * This program 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. + * + */ + +extern void somoPushPrompt(uint16_t prompt); diff --git a/src/translations/en.h b/src/translations/en.h index 6c9c0c8c8..9e4ef9025 100644 --- a/src/translations/en.h +++ b/src/translations/en.h @@ -57,12 +57,17 @@ #define TR_VCSWFUNC "---- ""v>ofs ""vofs""|v|v2 ""v1=v2 ""v1<=v2 " #define LEN_VFSWFUNC 14 +#if defined(DSM2) +#define TR_MODELMATCH "ModelMatch " +#else +#define TR_MODELMATCH +#endif #ifdef LOGS #define TR_SDCLOGGS "SDCARD Logs " #else #define TR_SDCLOGGS #endif -#define TR_VFSWFUNC "---- ""Trainer ""Trainer RUD ""Trainer ELE ""Trainer THR ""Trainer AIL ""Instant Trim ""Trims2Offsets "TR_SDCLOGGS +#define TR_VFSWFUNC "---- ""Trainer ""Trainer RUD ""Trainer ELE ""Trainer THR ""Trainer AIL ""Instant Trim ""Trims2Offsets "TR_MODELMATCH TR_SDCLOGGS #define LEN_VTELEMUNIT 1 #define TR_VTELEMUNIT "v""-" diff --git a/src/translations/fr.h b/src/translations/fr.h new file mode 100644 index 000000000..e0bd4920c --- /dev/null +++ b/src/translations/fr.h @@ -0,0 +1,279 @@ +// NON ZERO TERMINATED STRINGS +#define LEN_OFFON 3 +#define TR_OFFON "OFF""ON " + +#define LEN_MMMINV 3 +#define TR_MMMINV "---""INV" + +#define LEN_NCHANNELS 4 +#define TR_NCHANNELS "4CH 6CH 8CH 10CH12CH14CH16CH" + +#define LEN_VBEEPER 5 +#define TR_VBEEPER "Quiet""NoKey""Norm ""Long ""xLong" + +#define LEN_ADCFILTER 4 +#define TR_ADCFILTER "SING""OSMP""FILT" + +#define LEN_WARNSW 4 +#define TR_WARNSW "Bas ""OFF ""Haut" + +#define LEN_TRNMODE 3 +#define TR_TRNMODE "off"" +="" :=" + +#define LEN_TRNCHN 3 +#define TR_TRNCHN "ch1ch2ch3ch4" + +#define LEN_DATETIME 5 +#define TR_DATETIME "DATE:""TIME:" + +#define LEN_VTRIMINC 6 +#define TR_VTRIMINC "Exp ""ExFine""Fine ""Medium""Coarse" + +#define LEN_RETA123 1 +#define TR_RETA123 "RETA123" + +#define LEN_VPROTOS 6 +#define TR_VPROTOS "PPM ""PXX ""DSM2 ""SILV_A""SILV_B""SILV_C""TRAC09" + +#define LEN_POSNEG 3 +#define TR_POSNEG "POS""NEG" + +#define LEN_VCURVEFUNC 3 +#define TR_VCURVEFUNC "---""x>0""x<0""|x|""f>0""f<0""|f|" + +#define LEN_CURVMODES 5 +#define TR_CURVMODES "EDIT ""PRSET""A.GAZ" + +#define LEN_EXPLABELS 6 +#define TR_EXPLABELS "Weight""Expo ""Phase ""Inter ""When ""Courbe"" " + +#define LEN_VMLTPX 8 +#define TR_VMLTPX "Add ""Multiply""Replace " + +#define LEN_VMLTPX2 2 +#define TR_VMLTPX2 "+=""*="":=" + +#define LEN_VCSWFUNC 7 +#define TR_VCSWFUNC "---- ""v>ofs ""vofs""|v|v2 ""v1=v2 ""v1<=v2 " + +#define LEN_VFSWFUNC 14 +#if defined(DSM2) +#define TR_MODELMATCH "ModelMatch " +#else +#define TR_MODELMATCH +#endif +#ifdef LOGS +#define TR_SDCLOGGS "SDCARD Logs " +#else +#define TR_SDCLOGGS +#endif +#define TR_VFSWFUNC "---- ""Ecolage ""Ecolage DER ""Ecolage PRF ""Ecolage GAZ ""Ecolage AIL ""Instant Trim ""Trims2Offsets "TR_MODELMATCH TR_SDCLOGGS + +#define LEN_VTELEMUNIT 1 +#define TR_VTELEMUNIT "v""-" + +#define LEN_VALARM 3 +#define TR_VALARM "---""Yel""Org""Red" + +#define LEN_VALARMFN 1 +#define TR_VALARMFN "<>" + +#define LEN_VTELPROTO 4 +#if defined(WS_HOW_HIGH) +#define TR_VTELPROTO "NoneHub WSHH" +#elif defined(FRSKY_HUB) +#define TR_VTELPROTO "NoneHub " +#endif + +#define LEN_VTEMPLATES 12 +#define TR_VTEMPLATES "Simple 4-CH ""T-Cut ""V-Tail ""Elevon\\Delta""eCCPM ""Heli Setup ""Servo Test " + +#define LEN_VSWASHTYPE 6 +#define TR_VSWASHTYPE "--- ""120 ""120X ""140 ""90 " + +#define LEN_VKEYS 5 +#define TR_VKEYS " Menu"" Exit"" Down"" Up""Right"" Left" + +#define LEN_RE1RE2 3 +#define TR_RE1RE2 "RE1""RE2" + +#define LEN_VSWITCHES 3 +#define TR_VSWITCHES "GAZ""DER""PRF""ID0""ID1""ID2""AIL""GEA""TRN""SW1""SW2""SW3""SW4""SW5""SW6""SW7""SW8""SW9""SWA""SWB""SWC" + +#define LEN_VSRCRAW 4 +#define TR_VSRCRAW "DER ""PRF ""GAZ ""AIL ""P1 ""P2 ""P3 ""MAX ""FULL""CYC1""CYC2""CYC3" + +#define LEN_VTMRMODES 3 +#define TR_VTMRMODES "OFF""ABS""GZs""GZ%""GZt" + +#define LEN_TELEMCHNS 3 +#if defined(FRSKY_HUB) +#define TR_TELEMCHNS "AD1AD2ALTRPM" +#elif defined(WS_HOW_HIGH) +#define TR_TELEMCHNS "AD1AD2ALT" +#elif defined(FRSKY) +#define TR_TELEMCHNS "AD1AD2" +#endif + +// ZERO TERMINATED STRINGS +#define TR_POPUPS "[MENU] [EXIT]" +#define TR_MENUWHENDONE " [MENU] WHEN DONE" +#define TR_FREE "libre" +#define TR_DELETEMODEL "SUPPRIMER MODELE" +#define TR_COPYINGMODEL "Copying model..." +#define TR_MOVINGMODEL "Moving model..." +#define TR_LOADINGMODEL " Chargement..." +#define TR_NAME "Nom" +#define TR_TIMER "Timer" +#define TR_ELIMITS "E.Limits" +#define TR_ETRIMS "E.Trims" +#define TR_TRIMINC "Trim Inc" +#define TR_TTRACE "T-Trace" +#define TR_TTRIM "T-Trim" +#define TR_BEEPCTR "Beep Ctr" +#define TR_PROTO "Proto" +#define TR_PPMFRAME "PPM frame" +#define TR_MS "ms" +#define TR_SWITCH "Inter" +#define TR_TRIMS "Trims" +#define TR_FADEIN "Fade In" +#define TR_FADEOUT "Fade Out" +#define TR_DEFAULT "(default)" +#define TR_CHECKTRIMS "Check Trims" +#define TR_SWASHTYPE "Swash Type" +#define TR_COLLECTIVE "Collective" +#define TR_SWASHRING "Swash Ring" +#define TR_ELEDIRECTION "PRF Direction" +#define TR_AILDIRECTION "AIL Direction" +#define TR_COLDIRECTION "COL Direction" +#define TR_MODE "MODE" +#define TR_NOFREEEXPO "No free expo!" +#define TR_NOFREEMIXER "No free mixer!" +#define TR_INSERTMIX "INSERT MIX " +#define TR_EDITMIX "EDIT MIX " +#define TR_SOURCE "Source" +#define TR_WEIGHT "Weight" +#define TR_OFFSET "Offset" +#define TR_TRIM "Trim" +#define TR_CURVES "Courbe" +#define TR_FPHASE "P.Vol" +#define TR_WARNING "Warning" +#define TR_OFF "OFF" +#define TR_MULTPX "Multpx" +#define TR_DELAYDOWN "Delay Down" +#define TR_DELAYUP "Delay Up" +#define TR_SLOWDOWN "Slow Down" +#define TR_SLOWUP "Slow Up" +#define TR_DREXPO "DR/EXPO" +#define TR_MIXER "MIXER" +#define TR_COPYTRIMMENU "COPY TRIM [MENU]" +#define TR_CV "CV" +#define TR_SW "SW" +#define TR_ACHANNEL "A channel" +#define TR_MAX "Max" +#define TR_CALIB "Calib" +#define TR_BAR "Bar" +#define TR_ALARM "Alarm" +#define TR_USRPROTO "UsrProto" +#define TR_CLEARMIXMENU "CLEAR MIXES [MENU]" +#define TR_BEEPER "Beeper" +#define TR_CONTRAST "Contrast" +#define TR_BATTERYWARNING "Battery warning" +#define TR_INACTIVITYALARM "Inactivity alarm" +#define TR_FILTERADC "Filter ADC" +#define TR_THROTTLEREVERSE "Throttle reverse" +#define TR_MINUTEBEEP "Minute beep" +#define TR_BEEPCOUNTDOWN "Beep countdown" +#define TR_FLASHONBEEP "Flash on beep" +#define TR_LIGHTSWITCH "Light switch" +#define TR_LIGHTOFFAFTER "Light off after" +#define TR_SPLASHSCREEN "Splash screen" +#define TR_THROTTLEWARNING "Throttle Warning" +#define TR_SWITCHWARNING "Switch Warning" +#define TR_MEMORYWARNING "Memory Warning" +#define TR_ALARMWARNING "Alarm Warning" +#define TR_NODATAALARM "NO DATA Alarm" +#define TR_RXCHANNELORD "Rx Channel Ord" +#define TR_MODE2 "Mode" +#define TR_SLAVE "Esclave" +#define TR_MODESRC "mode % src" +#define TR_MULTIPLIER "Multiplier" +#define TR_CAL "Cal" +#define TR_EEPROMV "EEPROM v" +#define TR_VTRIM "Trim- +" +#define TR_BG "BG" +#define TR_MENUTOSTART " [MENU] TO START " +#define TR_SETMIDPOINT " SET MIDPOINT " +#define TR_MOVESTICKSPOTS " MOVE STICKS/POTS " +#define TR_ALT "Alt:" +#define TR_RXBATT "Rx Batt:" +#define TR_RX "Rx:" +#define TR_TX "Tx:" +#define TR_HDG "Hdg:" +#define TR_SPD "Spd:" +#define TR_TEMP1 "Temp1:" +#define TR_TEMP2 "Temp2:" +#define TR_RPM "RPM:" +#define TR_FUEL "Fuel:" +#define TR_VOLTS "Volts:" +#define TR_ACCEL "Accel" +#define TR_TELE "Tele:" +#define TR_RSSI "RSSI:" +#define TR_NODATA "NO DATA" +#define TR_TM1 "TM1" +#define TR_TM2 "TM2" +#define TR_THR "GAZ" +#define TR_TH "TH%" +#define TR_TOT "TOT" +#define TR_TMR1LATMAXUS "tmr1Lat max us" +#define TR_TMR1LATMINUS "tmr1Lat min us" +#define TR_TMR1JITTERUS "tmr1 Jitter us" +#define TR_TMAINMAXMS "tmain max ms" +#define TR_T10MSUS "t10ms us" +#define TR_FREESTACKMINB "Free Stack min b" +#define TR_MENUTORESET "[MENU] to reset" +#define TR_PPM "PPM" +#define TR_CH "CH" +#define TR_TMR "TMR" +#define TR_MODEL "MODEL" +#define TR_FP "PV" +#define TR_EEPROMLOWMEM "EEPROM low mem" +#define TR_ALERT "ALERT" +#define TR_PRESSANYKEYTOSKIP "Appuyez sur une touche" +#define TR_THROTTLENOTIDLE "Throttle not idle" +#define TR_RESETTHROTTLE "Reset throttle" +#define TR_ALARMSDISABLED "Alarmes Desactivees" +#define TR_SWITCHESNOTOFF "Switches not off" +#define TR_PLEASERESETTHEM "Please reset them" +#define TR_MESSAGE "MESSAGE" +#define TR_PRESSANYKEY "press any Key" +#define TR_BADEEPROMDATA "Bad EEprom Data" +#define TR_EEPROMFORMATTING "EEPROM Formatting" +#define TR_EEPROMOVERFLOW "EEPROM overflow" +#define TR_PULSETABOVERFLOW "PULSES OVERFLOW" + +#define TR_MENURADIOSETUP "RADIO SETUP" +#define TR_MENUDATEANDTIME "DATE ET HEURE" +#define TR_MENUTRAINER "ECOLAGE" +#define TR_MENUVERSION "VERSION" +#define TR_MENUDIAG "DIAG" +#define TR_MENUANA "ANA" +#define TR_MENUCALIBRATION "CALIBRATION" +#define TR_MENUSERROR "MENUS OVERFLOW" +#define TR_MENUMODELSEL "MODELSEL" +#define TR_MENUSETUP "SETUP" +#define TR_MENUFLIGHTPHASE "PHASE DE VOL" +#define TR_MENUFLIGHTPHASES "PHASES DE VOL" +#define TR_MENUHELISETUP "HELI SETUP" +#define TR_MENUDREXPO "DR/EXPO" +#define TR_MENULIMITS "LIMITES" +#define TR_MENUCURVES "COURBES" +#define TR_MENUCURVE "COURBE" +#define TR_MENUCUSTOMSWITCHES "INTERS PERS" +#define TR_MENUFUNCSWITCHES "FUNC SWITCHES" +#define TR_MENUSAFETYSWITCHES "INTERS SECURITE" +#define TR_MENUTELEMETRY "TELEMETRIE" +#define TR_MENUTEMPLATES "GABARITS" +#define TR_MENUSTAT "STAT" +#define TR_MENUDEBUG "DEBUG" +