1
0
Fork 0
mirror of https://github.com/opentx/opentx.git synced 2025-07-20 14:55:13 +03:00

Backup before extended trims function merge

This commit is contained in:
bsongis 2011-09-13 18:11:01 +00:00
parent 4788ea632e
commit f0fca34b7e
53 changed files with 18727 additions and 0 deletions

514
src/menus.cpp Normal file
View file

@ -0,0 +1,514 @@
/*
* Authors (alphabetical order)
* - Bertrand Songis <bsongis@gmail.com>
* - Bryan J. Rentoul (Gruvin) <gruvin@gmail.com>
*
* gruvin9x is based on code named er9x by
* Author - Erez Raviv <erezraviv@gmail.com>, 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.
*
*/
#include "gruvin9x.h"
#include "templates.h"
#include "menus.h"
int16_t calibratedStick[NUM_STICKS+NUM_POTS];
int16_t ex_chans[NUM_CHNOUT]; // Outputs + intermidiates
uint8_t s_pgOfs;
uint8_t s_editMode;
uint8_t s_noHi;
int16_t g_chans512[NUM_CHNOUT];
void menu_lcd_onoff( uint8_t x,uint8_t y, uint8_t value, uint8_t mode )
{
lcd_putsnAtt( x, y, PSTR("OFFON ")+3*value,3,mode ? INVERS:0) ;
}
void menu_lcd_HYPHINV( uint8_t x,uint8_t y, uint8_t value, uint8_t mode )
{
lcd_putsnAtt( x, y, PSTR("---INV")+3*value,3,mode ? INVERS:0) ;
}
void DisplayScreenIndex(uint8_t index, uint8_t count, uint8_t attr)
{
lcd_outdezAtt(128,0,count,attr);
lcd_putcAtt(1+128-FW*(count>9 ? 3 : 2),0,'/',attr);
lcd_outdezAtt(1+128-FW*(count>9 ? 3 : 2),0,index+1,attr);
}
int16_t p1valdiff;
int8_t checkIncDec_Ret;
int16_t checkIncDec(uint8_t event, int16_t val, int16_t i_min, int16_t i_max, uint8_t i_flags)
{
int16_t newval = val;
uint8_t kpl=KEY_RIGHT, kmi=KEY_LEFT, kother = -1;
if(event & _MSK_KEY_DBL){
uint8_t hlp=kpl;
kpl=kmi;
kmi=hlp;
event=EVT_KEY_FIRST(EVT_KEY_MASK & event);
}
if(event==EVT_KEY_FIRST(kpl) || event== EVT_KEY_REPT(kpl) || (s_editMode && (event==EVT_KEY_FIRST(KEY_UP) || event== EVT_KEY_REPT(KEY_UP))) ) {
newval++;
#if defined (BEEPSPKR)
beepKeySpkr(BEEP_KEY_UP_FREQ);
#else
beepKey();
#endif
kother=kmi;
}else if(event==EVT_KEY_FIRST(kmi) || event== EVT_KEY_REPT(kmi) || (s_editMode && (event==EVT_KEY_FIRST(KEY_DOWN) || event== EVT_KEY_REPT(KEY_DOWN))) ) {
newval--;
#if defined (BEEPSPKR)
beepKeySpkr(BEEP_KEY_DOWN_FREQ);
#else
beepKey();
#endif
kother=kpl;
}
if((kother != (uint8_t)-1) && keyState((EnumKeys)kother)){
newval=-val;
killEvents(kmi);
killEvents(kpl);
}
if(i_min==0 && i_max==1 && event==EVT_KEY_FIRST(KEY_MENU)) {
s_editMode = false;
newval=!val;
killEvents(event);
}
//change values based on P1
newval -= p1valdiff;
if(newval > i_max)
{
newval = i_max;
killEvents(event);
#if defined (BEEPSPKR)
beepWarn2Spkr(BEEP_KEY_UP_FREQ);
#else
beepWarn2();
#endif
}
if(newval < i_min)
{
newval = i_min;
killEvents(event);
#if defined (BEEPSPKR)
beepWarn2Spkr(BEEP_KEY_DOWN_FREQ);
#else
beepWarn2();
#endif
}
if(newval != val){
if(newval==0) {
pauseEvents(event); // delay before auto-repeat continues
#if defined (BEEPSPKR)
if (newval>val)
beepWarn2Spkr(BEEP_KEY_UP_FREQ);
else
beepWarn2Spkr(BEEP_KEY_DOWN_FREQ);
#else
beepKey();
#endif
}
eeDirty(i_flags & (EE_GENERAL|EE_MODEL));
checkIncDec_Ret = (newval > val ? 1 : -1);
}
else {
checkIncDec_Ret = 0;
}
return newval;
}
int8_t checkIncDecModel(uint8_t event, int8_t i_val, int8_t i_min, int8_t i_max)
{
return checkIncDec(event,i_val,i_min,i_max,EE_MODEL);
}
int8_t checkIncDecGen(uint8_t event, int8_t i_val, int8_t i_min, int8_t i_max)
{
return checkIncDec(event,i_val,i_min,i_max,EE_GENERAL);
}
bool check_simple(uint8_t event, uint8_t curr, MenuFuncP *menuTab, uint8_t menuTabSize, uint8_t maxrow)
{
return check(event, curr, menuTab, menuTabSize, 0, 0, maxrow);
}
bool check_submenu_simple(uint8_t event, uint8_t maxrow)
{
return check_simple(event, 0, 0, 0, maxrow);
}
#define MAXCOL(row) (horTab ? pgm_read_byte(horTab+min(row, horTabMax)) : (const uint8_t)0)
#define INC(val,max) if(val<max) {val++;} else {val=0;}
#define DEC(val,max) if(val>0 ) {val--;} else {val=max;}
bool check(uint8_t event, uint8_t curr, MenuFuncP *menuTab, uint8_t menuTabSize, prog_uint8_t *horTab, uint8_t horTabMax, uint8_t maxrow)
{
if (menuTab) {
uint8_t attr = m_posVert==0 ? INVERS : 0;
if (m_posVert==0) {
switch(event)
{
case EVT_KEY_FIRST(KEY_LEFT):
if(curr>0)
chainMenu((MenuFuncP)pgm_read_adr(&menuTab[curr-1]));
else
chainMenu((MenuFuncP)pgm_read_adr(&menuTab[menuTabSize-1]));
return false;
case EVT_KEY_FIRST(KEY_RIGHT):
if(curr < (menuTabSize-1))
chainMenu((MenuFuncP)pgm_read_adr(&menuTab[curr+1]));
else
chainMenu((MenuFuncP)pgm_read_adr(&menuTab[0]));
return false;
}
}
DisplayScreenIndex(curr, menuTabSize, attr);
}
uint8_t maxcol = MAXCOL(m_posVert);
switch(event)
{
case EVT_ENTRY:
minit();
s_editMode = false;
break;
case EVT_KEY_FIRST(KEY_MENU):
if (maxcol > 0)
s_editMode = !s_editMode;
break;
case EVT_KEY_LONG(KEY_EXIT):
s_editMode = false;
popMenu(false);
break;
case EVT_KEY_BREAK(KEY_EXIT):
if(s_editMode) {
s_editMode = false;
break;
}
if(m_posVert==0 || !menuTab) {
popMenu(); //beeps itself
}
else {
beepKey();
minit();BLINK_SYNC;
}
break;
case EVT_KEY_REPT(KEY_RIGHT): //inc
if(m_posHorz==maxcol) break;
case EVT_KEY_FIRST(KEY_RIGHT)://inc
if(!horTab || s_editMode)break;
INC(m_posHorz,maxcol);
BLINK_SYNC;
break;
case EVT_KEY_REPT(KEY_LEFT): //dec
if(m_posHorz==0) break;
case EVT_KEY_FIRST(KEY_LEFT)://dec
if(!horTab || s_editMode)break;
DEC(m_posHorz,maxcol);
BLINK_SYNC;
break;
case EVT_KEY_REPT(KEY_DOWN): //inc
if(m_posVert==maxrow) break;
case EVT_KEY_FIRST(KEY_DOWN): //inc
if(s_editMode)break;
do {
INC(m_posVert,maxrow);
} while(MAXCOL(m_posVert) == (uint8_t)-1);
m_posHorz = min(m_posHorz, MAXCOL(m_posVert));
BLINK_SYNC;
break;
case EVT_KEY_REPT(KEY_UP): //dec
if(m_posVert==0) break;
case EVT_KEY_FIRST(KEY_UP): //dec
if(s_editMode)break;
do {
DEC(m_posVert,maxrow);
} while(MAXCOL(m_posVert) == (uint8_t)-1);
m_posHorz = min(m_posHorz, MAXCOL(m_posVert));
BLINK_SYNC;
break;
}
uint8_t max = menuTab ? 7 : 6;
if(m_posVert<1) s_pgOfs=0;
else if(m_posVert-s_pgOfs>max) s_pgOfs = m_posVert-max;
else if(m_posVert-s_pgOfs<1) s_pgOfs = m_posVert-1;
return true;
}
MenuFuncP g_menuStack[5];
uint8_t g_menuPos[4];
uint8_t g_menuStackPtr = 0;
uint8_t m_posVert;
uint8_t m_posHorz;
void popMenu(bool uppermost)
{
if (g_menuStackPtr>0) {
g_menuStackPtr = uppermost ? 0 : g_menuStackPtr-1;
beepKey();
m_posHorz = g_menuPos[g_menuStackPtr] & 0x0F;
m_posVert = g_menuPos[g_menuStackPtr] >> 4;
(*g_menuStack[g_menuStackPtr])(EVT_ENTRY_UP);
}
else {
alert(PSTR("menuStack underflow"));
}
}
void chainMenu(MenuFuncP newMenu)
{
g_menuStack[g_menuStackPtr] = newMenu;
(*newMenu)(EVT_ENTRY);
beepKey();
}
void pushMenu(MenuFuncP newMenu)
{
g_menuPos[g_menuStackPtr] = (m_posVert << 4) + m_posHorz;
g_menuStackPtr++;
if(g_menuStackPtr >= DIM(g_menuStack))
{
g_menuStackPtr--;
alert(PSTR("menuStack overflow"));
return;
}
beepKey();
g_menuStack[g_menuStackPtr] = newMenu;
(*newMenu)(EVT_ENTRY);
}
/******************************************************************************
the functions below are from int-level
the functions below are from int-level
the functions below are from int-level
******************************************************************************/
void setupPulses()
{
switch(g_model.protocol)
{
case PROTO_PPM:
setupPulsesPPM();
break;
case PROTO_SILV_A:
case PROTO_SILV_B:
case PROTO_SILV_C:
setupPulsesSilver();
break;
case PROTO_TRACER_CTP1009:
setupPulsesTracerCtp1009();
break;
}
}
//inline int16_t reduceRange(int16_t x) // for in case we want to have room for subtrims
//{
// return x-(x/4); //512+128 =? 640, 640 - 640/4 == 640 * 3/4 => 480 (just below 500msec - it can still reach 500 with offset)
//}
void setupPulsesPPM() // changed 10/05/2010 by dino Issue 128
{
#define PPM_CENTER 1200*2
int16_t PPM_range = g_model.extendedLimits ? 640*2 : 512*2; //range of 0.7..1.7msec
//Total frame length = 22.5msec
//each pulse is 0.7..1.7ms long with a 0.3ms stop tail
//The pulse ISR is 2mhz so everything is multiplied by 2
// G: Found the following reference at th9x. The below code does not seem
// to produce quite exactly this, to my eye. *shrug*
// http://www.aerodesign.de/peter/2000/PCM/frame_ppm.gif
uint8_t j=0;
uint8_t p=8+g_model.ppmNCH*2; //Channels *2
uint16_t q=(g_model.ppmDelay*50+300)*2; //Stoplen *2
uint16_t rest=22500u*2-q; //Minimum Framelen=22.5 ms
if(p>9) rest=p*(1720u*2 + q) + 4000u*2; //for more than 9 channels, frame must be longer
for(uint8_t i=0;i<p;i++){ //NUM_CHNOUT
int16_t v = max(min(g_chans512[i],(int16_t)PPM_range),(int16_t)-PPM_range) + (int16_t)PPM_CENTER;
rest-=(v+q);
pulses2MHz[j++] = q;
pulses2MHz[j++] = v - q + 600; /* as Pat MacKenzie suggests */
}
pulses2MHz[j++]=q;
pulses2MHz[j++]=rest;
pulses2MHz[j++]=0;
}
uint16_t *pulses2MHzPtr;
#define BITLEN (600u*2)
void _send_hilo(uint16_t hi,uint16_t lo)
{
*pulses2MHzPtr++=hi; *pulses2MHzPtr++=lo;
}
#define send_hilo_silv( hi, lo) _send_hilo( (hi)*BITLEN,(lo)*BITLEN )
void sendBitSilv(uint8_t val)
{
send_hilo_silv((val)?2:1,(val)?2:1);
}
void send2BitsSilv(uint8_t val)
{
sendBitSilv(val&2);sendBitSilv(val&1);
}
// _ oder - je 0.6ms (gemessen 0.7ms)
//
//____-----_-_-_--_--_ -_--__ -_-_-_-_ -_-_-_-_ --__--__-_______
// trailer chan m1 m2
//
//see /home/thus/txt/silverlit/thus.txt
//m1, m2 most significant bit first |m1-m2| <= 9
//chan: 01=C 10=B
//chk = 0 - chan -m1>>2 -m1 -m2>>2 -m2
//<= 500us Probleme
//>= 650us Probleme
//periode orig: 450ms
void setupPulsesSilver()
{
int8_t chan=1; //chan 1=C 2=B 0=A?
switch(g_model.protocol)
{
case PROTO_SILV_A: chan=0; break;
case PROTO_SILV_B: chan=2; break;
case PROTO_SILV_C: chan=1; break;
}
int8_t m1 = (uint16_t)(g_chans512[0]+1024)*2 / 256;
int8_t m2 = (uint16_t)(g_chans512[1]+1024)*2 / 256;
if (m1 < 0) m1=0;
if (m2 < 0) m2=0;
if (m1 > 15) m1=15;
if (m2 > 15) m2=15;
if (m2 > m1+9) m1=m2-9;
if (m1 > m2+9) m2=m1-9;
//uint8_t i=0;
pulses2MHzPtr=pulses2MHz;
send_hilo_silv(5,1); //idx 0 erzeugt pegel=0 am Ausgang, wird als high gesendet
send2BitsSilv(0);
send_hilo_silv(2,1);
send_hilo_silv(2,1);
send2BitsSilv(chan); //chan 1=C 2=B 0=A?
uint8_t sum = 0 - chan;
send2BitsSilv(m1>>2); //m1
sum-=m1>>2;
send2BitsSilv(m1);
sum-=m1;
send2BitsSilv(m2>>2); //m2
sum-=m2>>2;
send2BitsSilv(m2);
sum-=m2;
send2BitsSilv(sum); //chk
sendBitSilv(0);
pulses2MHzPtr--;
send_hilo_silv(50,0); //low-impuls (pegel=1) ueberschreiben
}
/*
TRACE CTP-1009
- = send 45MHz
_ = send nix
start1 0 1 start2
-------__ --_ -__ -----__
7ms 2 .8 .4 .4 .8 5 2
frame:
start1 24Bits_1 start2 24_Bits2
24Bits_1:
7 x Bits Throttle lsb first
1 x 0
6 x Bits rotate lsb first
1 x Bit 1=rechts
1 x 0
4 x Bits chk5 = nib2 ^ nib4
4 x Bits chk6 = nib1 ^ nib3
24Bits_2:
7 x Bits Vorwaets lsb first 0x3f = mid
1 x 1
7 x Bits 0x0e lsb first
1 x 1
4 x Bits chk5 = nib2 ^ nib4
4 x Bits chk6 = nib1 ^ nib3
*/
#define BIT_TRA (400u*2)
void sendBitTra(uint8_t val)
{
if(val) _send_hilo( BIT_TRA*1 , BIT_TRA*2 );
else _send_hilo( BIT_TRA*2 , BIT_TRA*1 );
}
void sendByteTra(uint8_t val)
{
for(uint8_t i=0; i<8; i++, val>>=1) sendBitTra(val&1);
}
void setupPulsesTracerCtp1009()
{
pulses2MHzPtr=pulses2MHz;
static bool phase;
if( (phase=!phase) ){
uint8_t thr = min(127u,(uint16_t)(g_chans512[0]+1024+8) / 16u);
uint8_t rot;
if (g_chans512[1] >= 0)
{
rot = min(63u,(uint16_t)( g_chans512[1]+16) / 32u) | 0x40;
}else{
rot = min(63u,(uint16_t)(-g_chans512[1]+16) / 32u);
}
sendByteTra(thr);
sendByteTra(rot);
uint8_t chk=thr^rot;
sendByteTra( (chk>>4) | (chk<<4) );
_send_hilo( 5000*2, 2000*2 );
}else{
uint8_t fwd = min(127u,(uint16_t)(g_chans512[2]+1024) / 16u) | 0x80;
sendByteTra(fwd);
sendByteTra(0x8e);
uint8_t chk=fwd^0x8e;
sendByteTra( (chk>>4) | (chk<<4) );
_send_hilo( 7000*2, 2000*2 );
}
*pulses2MHzPtr++=0;
if((pulses2MHzPtr-pulses2MHz) >= (signed)DIM(pulses2MHz)) alert(PSTR("pulse tab overflow"));
}