Custom Telemetry View

FAAST protocol (start pulses before the splash)
Templates Confirmation
Used channels cleaned before applying a template
This commit is contained in:
bsongis
2012-03-15 18:37:18 +00:00
parent ba2a9d7f34
commit 0fdb85067a
15 changed files with 435 additions and 438 deletions
+147 -115
View File
@@ -78,6 +78,7 @@ enum BarThresholdIdx {
THLD_T2,
THLD_SPEED,
THLD_CELL,
THLD_DIST,
THLD_MAX,
};
uint8_t barsThresholds[THLD_MAX];
@@ -228,6 +229,12 @@ void parseTelemHubByte(uint8_t byte)
((uint8_t*)&frskyHubData)[structPos] = lowByte;
((uint8_t*)&frskyHubData)[structPos+1] = byte;
// TODO switch here ...
if ((uint8_t)structPos == offsetof(FrskyHubData, rpm)) {
frskyHubData.rpm /= (g_model.frsky.blades+2);
}
if ((uint8_t)structPos == offsetof(FrskyHubData, baroAltitude_bp)) {
// First received altitude => Altitude offset
if (!frskyHubData.baroAltitudeOffset)
@@ -647,6 +654,7 @@ void resetTelemetry()
frskyTelemetry[0].set(120);
frskyRSSI[0].set(75);
frskyHubData.fuelLevel = 75;
frskyHubData.rpm = 12000;
frskyHubData.gpsFix = 1;
frskyHubData.gpsLatitude_bp = 4401;
@@ -669,20 +677,97 @@ void resetTelemetry()
#endif
}
enum FrskyViews {
e_frsky_bars,
e_frsky_a1a2,
#ifdef WS_HOW_HIGH
e_frsky_ws_how_high,
#endif
#ifdef FRSKY_HUB
e_frsky_hub = e_frsky_a1a2+1,
e_frsky_gps_inflight,
e_frsky_gps_position,
#endif
int16_t convertTelemValue(uint8_t channel, uint8_t value)
{
// TODO enum
int16_t result;
switch (channel) {
case 2:
// Altitude
result = value * 4;
break;
case 3:
// RPMs
result = value * 50;
break;
case 7:
case 8:
// SPEED
result = value * 2;
break;
case 9:
// DIST
result = value * 8;
break;
default:
result = value;
break;
}
return result;
}
void putsTelemetryValue(uint8_t x, uint8_t y, int16_t val, uint8_t unit, uint8_t att)
{
lcd_outdezAtt(x, (att & DBLSIZE ? y - FH : y), val, att); // TODO we could add this test inside lcd_outdezAtt!
if (~att & NO_UNIT && unit != UNIT_RAW)
lcd_putsiAtt(lcd_lastPos+1, y, STR_VTELEMUNIT, unit, 0);
}
const pm_uint8_t bchunit_ar[] = {
UNIT_VOLTS, // A1
UNIT_VOLTS, // A2
UNIT_METERS, // Alt
UNIT_RAW, // Rpm
UNIT_PERCENT, // Fuel
UNIT_DEGREES, // T1
UNIT_DEGREES, // T2
UNIT_KMH, // Speed
UNIT_VOLTS, // Cell
UNIT_METERS // Dist
};
static uint8_t s_frsky_view = e_frsky_bars;
void putsTelemetryChannel(uint8_t x, uint8_t y, uint8_t channel, int16_t val, uint8_t att)
{
switch (channel) {
case 0:
case 1:
// A1 and A2
{
// TODO optimize this, avoid int32_t
int16_t converted_value = ((int32_t)val+g_model.frsky.channels[channel].offset) * (g_model.frsky.channels[channel].ratio << g_model.frsky.channels[channel].multiplier) * 2 / 51;
if (g_model.frsky.channels[channel].type >= UNIT_RAW) {
converted_value /= 10;
}
else {
if (converted_value < 1000) {
att |= PREC2;
}
else {
converted_value /= 10;
att |= PREC1;
}
}
putsTelemetryValue(x, y, converted_value, g_model.frsky.channels[channel].type, att);
}
break;
default:
putsTelemetryValue(x, y, val, pgm_read_byte(bchunit_ar+channel), att);
break;
}
}
enum FrskyViews {
e_frsky_custom,
e_frsky_bars,
e_frsky_a1a2,
e_frsky_gps_position, // TODO rename
FRSKY_VIEW_MAX = e_frsky_gps_position
};
static uint8_t s_frsky_view = e_frsky_custom;
void displayRssiLine()
{
@@ -702,29 +787,6 @@ void displayRssiLine()
}
}
#if defined(FRSKY_HUB) || defined(WS_HOW_HIGH)
void displayAltitudeLine(uint8_t y, uint8_t gps)
{
lcd_putsLeft(y, STR_ALT);
uint16_t alt;
uint8_t att, x;
if (gps) {
alt = frskyHubData.gpsAltitude_bp;
att = DBLSIZE;
x = 10*FW+1;
}
else {
alt = frskyHubData.baroAltitude_bp;
att = LEFT|DBLSIZE;
x = 4*FW;
}
putsTelemetryValue(x, y, alt, UNIT_METERS, att);
lcd_putc(14*FW, y, '>');
putsTelemetryValue(15*FW, y, frskyHubData.maxAltitude, UNIT_METERS, LEFT);
}
#endif
#if defined(FRSKY_HUB)
void displayGpsTime()
{
@@ -739,14 +801,12 @@ void displayGpsTime()
}
#endif
#if defined(FRSKY_HUB) && defined(WS_HOW_HIGH)
#define FRSKY_VIEW_MAX (g_model.frsky.usrProto == 0 ? 1 : ((g_model.frsky.usrProto == 1 && frskyHubData.gpsFix >= 0) ? 4 : 2))
#elif defined(FRSKY_HUB)
#define FRSKY_VIEW_MAX (g_model.frsky.usrProto == 0 ? 1 : (frskyHubData.gpsFix >= 0 ? 4 : 2))
#elif defined(WS_HOW_HIGH)
#define FRSKY_VIEW_MAX (g_model.frsky.usrProto == 0 ? 1 : 2)
#endif
uint8_t getTelemCustomField(uint8_t line, uint8_t col)
{
uint8_t result = (col==0 ? (g_model.frskyLines[line] & 0x0f) : ((g_model.frskyLines[line] & 0xf0) >> 4)) << 1;
result += ((g_model.frskyLinesXtra >> (2*line+col)) & 0x01);
return result;
}
void menuProcFrsky(uint8_t event)
{
@@ -781,7 +841,42 @@ void menuProcFrsky(uint8_t event)
lcd_filled_rect(0, 0, DISPLAY_W, 8);
if (frskyStreaming >= 0) {
if (s_frsky_view == e_frsky_bars) {
if (s_frsky_view == e_frsky_custom) {
// The custom view
for (uint8_t i=0; i<4; i++) {
for (uint8_t j=0; j<2; j++) {
uint8_t field = getTelemCustomField(i, j);
if (i==3) {
lcd_vline(63, 8, 48);
if (frskyStreaming > 0) {
if (field == TELEM_ACC) {
lcd_putsLeft(7*FH+1, STR_ACCEL);
lcd_outdezNAtt(4*FW, 7*FH+1, (int32_t)frskyHubData.accelX/10, LEFT|PREC2);
lcd_outdezNAtt(10*FW, 7*FH+1, (int32_t)frskyHubData.accelY/10, LEFT|PREC2);
lcd_outdezNAtt(16*FW, 7*FH+1, (int32_t)frskyHubData.accelZ/10, LEFT|PREC2);
break;
}
else if (field == TELEM_GPS_TIME) {
displayGpsTime();
return;
}
}
else {
displayRssiLine();
return;
}
}
if (field) {
// TODO change name STR_VTELEMBARS
lcd_putsiAtt(j*65, 1+FH+2*FH*i, STR_VTELEMBARS, field, 0);
int16_t value = getValue(CSW_CHOUT_BASE+NUM_CHNOUT+MAX_TIMERS+field-1);
putsTelemetryChannel(j ? 128 : 63, i==3 ? 1+7*FH : 1+2*FH+2*FH*i, field-1, value, i==3 ? NO_UNIT : DBLSIZE|NO_UNIT);
}
}
}
lcd_filled_rect(0, 7*FH, DISPLAY_W, 8); // TODO optim function?
}
else if (s_frsky_view == e_frsky_bars) {
// The bars
uint8_t bars_height = 5;
for (int8_t i=3; i>=0; i--) {
@@ -789,17 +884,20 @@ void menuProcFrsky(uint8_t event)
lcd_putsiAtt(0, bars_height+bars_height+1+i*(bars_height+6), STR_VTELEMBARS, g_model.frsky.bars[i].source, 0);
lcd_rect(25, bars_height+6+i*(bars_height+6), 101, bars_height+2);
int16_t value = getValue(CSW_CHOUT_BASE+NUM_CHNOUT+MAX_TIMERS+g_model.frsky.bars[i].source-1);
uint8_t threshold = 0, thresholdX = 0;
uint16_t threshold = 0;
uint8_t thresholdX = 0;
if (g_model.frsky.bars[i].source <= 2)
threshold = g_model.frsky.channels[g_model.frsky.bars[i].source-1].alarms_value[0];
else
threshold = barsThresholds[g_model.frsky.bars[i].source-3];
threshold = convertTelemValue(g_model.frsky.bars[i].source-1, barsThresholds[g_model.frsky.bars[i].source-3]);
int16_t barMin = convertTelemValue(g_model.frsky.bars[i].source-1, (g_model.frsky.bars[i].barMin * 5));
int16_t barMax = convertTelemValue(g_model.frsky.bars[i].source-1, ((51 - g_model.frsky.bars[i].barMax) * 5));
if (threshold) {
thresholdX = (uint8_t)(int16_t)((int16_t)100 * (threshold - g_model.frsky.bars[i].barMin * 4) / ((51 - g_model.frsky.bars[i].barMax) * 5 - g_model.frsky.bars[i].barMin * 4));
thresholdX = (uint8_t)(int16_t)((int16_t)100 * (threshold - barMin) / (barMax - barMin));
if (thresholdX > 100)
thresholdX = 0;
}
uint8_t width = (uint8_t)limit((int16_t)0, (int16_t)((int16_t)100 * (value - g_model.frsky.bars[i].barMin * 5) / ((51 - g_model.frsky.bars[i].barMax) * 4 - g_model.frsky.bars[i].barMin * 4)), (int16_t)100);
uint8_t width = (uint8_t)limit((int16_t)0, (int16_t)(((int16_t)100 * (value - barMin)) / (barMax - barMin)), (int16_t)100);
lcd_filled_rect(26, bars_height+6+1+i*(bars_height+6), width, bars_height, (threshold > value) ? DOTTED : SOLID);
for (uint8_t j=50; j<125; j+=25)
if (j>26+thresholdX) lcd_vline(j, bars_height+6+1+i*(bars_height+6), bars_height);
@@ -814,7 +912,7 @@ void menuProcFrsky(uint8_t event)
}
if (bars_height == 13) {
// No bars at all!
s_frsky_view = ((event == EVT_KEY_BREAK(KEY_UP)) ? FRSKY_VIEW_MAX : e_frsky_a1a2);
s_frsky_view = ((event == EVT_KEY_BREAK(KEY_UP)) ? e_frsky_custom : e_frsky_a1a2);
}
displayRssiLine();
}
@@ -847,73 +945,7 @@ void menuProcFrsky(uint8_t event)
displayRssiLine();
}
#ifdef WS_HOW_HIGH
else if (g_model.frsky.usrProto == PROTO_WS_HOW_HIGH && s_frsky_view == e_frsky_ws_how_high) {
displayAltitudeLine(4*FH, 0/*baro*/);
displayRssiLine();
}
#endif
#ifdef FRSKY_HUB
else if (s_frsky_view == e_frsky_hub) {
// Temperature 1
lcd_putsLeft( 4*FH, STR_TEMP1nTEMP2);
putsTelemetryValue(4*FW, 4*FH, frskyHubData.temperature1, UNIT_DEGREES, DBLSIZE|LEFT);
// Temperature 2
putsTelemetryValue(15*FW, 4*FH, frskyHubData.temperature2, UNIT_DEGREES, DBLSIZE|LEFT);
// RPM
lcd_putsLeft(2*FH, STR_RPMnFUEL);
lcd_outdezNAtt(4*FW, 1*FH, frskyHubData.rpm/(2+g_model.frsky.blades), DBLSIZE|LEFT);
// Fuel
putsTelemetryValue(15*FW, 2*FH, frskyHubData.fuelLevel, UNIT_PERCENT, DBLSIZE|LEFT);
// Altitude (barometric)
displayAltitudeLine(6*FH, 0/*baro*/);
// Accelerometer
#define ACC_LINE (7*FH+1)
if (frskyStreaming > 0) {
lcd_putsLeft(ACC_LINE, STR_ACCEL);
// lcd_puts(4*FW, 7*FH, PSTR("x:"));
lcd_outdezNAtt(4*FW, ACC_LINE, (int32_t)frskyHubData.accelX/10, LEFT|PREC2);
// lcd_putc(lcd_lastPos, 7*FH, 'g');
// lcd_puts(11*FW, 7*FH, PSTR("y:"));
lcd_outdezNAtt(10*FW, ACC_LINE, (int32_t)frskyHubData.accelY/10, LEFT|PREC2);
// lcd_putc(lcd_lastPos, 7*FH, 'g');
// lcd_puts(18*FW, 7*FH, PSTR("z:"));
lcd_outdezNAtt(16*FW, ACC_LINE, (int32_t)frskyHubData.accelZ/10, LEFT|PREC2);
// lcd_putc(lcd_lastPos, 7*FH, 'g');
lcd_filled_rect(0, ACC_LINE-1, DISPLAY_W, 8); // TODO optim function?
}
else {
displayRssiLine();
}
}
else if (s_frsky_view == e_frsky_gps_inflight) {
// GPS speed
#define SPEED_LINE (2*FH)
lcd_putsLeft(SPEED_LINE, STR_SPD);
putsTelemetryValue(10*FW+1, SPEED_LINE, frskyHubData.gpsSpeed_bp, UNIT_KTS, DBLSIZE);
lcd_putc(14*FW, SPEED_LINE, '>');
putsTelemetryValue(15*FW, SPEED_LINE, frskyHubData.maxGpsSpeed, UNIT_KTS, LEFT);
// GPS altitude
#define ALTITUDE_LINE (4*FH)
displayAltitudeLine(ALTITUDE_LINE, 1/*gps*/);
// GPS distance
#define DISTANCE_LINE (6*FH)
lcd_putsLeft(DISTANCE_LINE, STR_DST);
putsTelemetryValue(10*FW+1, DISTANCE_LINE, frskyHubData.gpsDistance, UNIT_METERS, DBLSIZE);
lcd_putc(14*FW, DISTANCE_LINE, '>');
putsTelemetryValue(15*FW, DISTANCE_LINE, frskyHubData.maxGpsDistance, UNIT_METERS, LEFT);
displayGpsTime();
}
else if (s_frsky_view == e_frsky_gps_position) {
// Latitude
#define LAT_LINE (2*FH-4)
+5
View File
@@ -158,6 +158,11 @@ inline void FRSKY_setModelAlarms(void)
bool FRSKY_alarmRaised(uint8_t idx);
void resetTelemetry();
uint8_t getTelemCustomField(uint8_t line, uint8_t col);
int16_t convertTelemValue(uint8_t channel, uint8_t value);
void putsTelemetryChannel(uint8_t x, uint8_t y, uint8_t channel, int16_t val, uint8_t att);
void putsTelemetryValue(uint8_t x, uint8_t y, int16_t val, uint8_t unit, uint8_t att);
#endif
+8 -76
View File
@@ -250,7 +250,6 @@ void lcd_outdezNAtt(uint8_t x, uint8_t y, int16_t val, uint8_t flags, uint8_t le
uint8_t xn = 0;
uint8_t ln = 2;
char c;
if (mode != MODE(LEADING0)) {
len = 1;
@@ -283,9 +282,13 @@ void lcd_outdezNAtt(uint8_t x, uint8_t y, int16_t val, uint8_t flags, uint8_t le
x -= fw + 1;
for (uint8_t i=1; i<=len; i++) {
c = ((uint16_t)val % 10) + '0';
if (c=='1' && flags&DBLSIZE && i==len) { x+=2; flags|=CONDENSED; }
lcd_putcAtt(x, y, c, flags);
char c = ((uint16_t)val % 10) + '0';
uint8_t f = flags;
if (flags & DBLSIZE) {
if (c=='1' && i==len) { x+=2; f|=CONDENSED; }
if (val >= 1000) { x+=FWNUM; f&=~DBLSIZE; }
}
lcd_putcAtt(x, y, c, f);
if (mode==i) {
flags &= ~PREC2; // TODO not needed but removes 64bytes, could be improved for sure, check asm
if (flags & DBLSIZE) {
@@ -304,6 +307,7 @@ void lcd_outdezNAtt(uint8_t x, uint8_t y, int16_t val, uint8_t flags, uint8_t le
lcd_vline(x+1, y, 8);
}
}
if ((flags & DBLSIZE) && val >= 1000 && val < 10000) x-=2;
val = ((uint16_t)val) / 10;
x-=fw;
}
@@ -560,76 +564,6 @@ void putsTmrMode(uint8_t x, uint8_t y, int8_t mode, uint8_t att)
putsSwitches(x, y, mode-(TMR_VAROFS-1), att|SWONLY);
}
#ifdef FRSKY
// TODO move this into frsky.cpp
void putsTelemetryChannel(uint8_t x, uint8_t y, uint8_t channel, int16_t val, uint8_t att)
{
// TODO enum
switch (channel) {
case 0:
case 1:
// A1 and A2
{
// TODO optimize this, avoid int32_t
int16_t converted_value = ((int32_t)val+g_model.frsky.channels[channel].offset) * (g_model.frsky.channels[channel].ratio << g_model.frsky.channels[channel].multiplier) * 2 / 51;
if (g_model.frsky.channels[channel].type >= UNIT_RAW) {
converted_value /= 10;
}
else {
if (converted_value < 1000) {
att |= PREC2;
}
else {
converted_value /= 10;
att |= PREC1;
}
}
putsTelemetryValue(x, y, converted_value, g_model.frsky.channels[channel].type, att);
}
break;
case 2:
// Altitude
putsTelemetryValue(x, y, val * 4, UNIT_METERS, att);
break;
case 3:
// RPMs
lcd_outdezAtt(x, y, (int16_t)val * 50, att);
break;
case 4:
// FUEL
putsTelemetryValue(x, y, val, UNIT_PERCENT, att);
break;
case 5:
case 6:
// TEMPERATURE
putsTelemetryValue(x, y, val, UNIT_DEGREES, att);
break;
case 7:
// SPEED
putsTelemetryValue(x, y, val*2, UNIT_KMH, att);
break;
case 8:
// CELL
putsVolts(x, y, val*2, att);
break;
}
}
void putsTelemetryValue(uint8_t x, uint8_t y, int16_t val, uint8_t unit, uint8_t att)
{
lcd_outdezAtt(x, (att & DBLSIZE ? y - FH : y), val, att); // TODO we could add this test inside lcd_outdezAtt!
if (~att & NO_UNIT && unit != UNIT_RAW)
lcd_putsiAtt(lcd_lastPos+1, y, STR_VTELEMUNIT, unit, 0);
}
#endif
void lcdSendCtl(uint8_t val)
{
PORTC_LCD_CTRL &= ~(1<<OUT_C_LCD_CS1);
@@ -648,14 +582,12 @@ void lcdSendCtl(uint8_t val)
PORTC_LCD_CTRL |= (1<<OUT_C_LCD_CS1);
}
#define delay_1us() _delay_us(1)
void delay_1_5us(int ms)
{
for(int i=0; i<ms; i++) delay_1us();
}
void lcd_init()
{
// /home/thus/txt/datasheets/lcd/KS0713.pdf
+3 -7
View File
@@ -72,8 +72,10 @@
#define SWONLY 0x40 /* means no ON OFF, only switches */
#define SWCONDENSED 0x80 /* means that THRm will be displayed as THR */
/* other flags */
/* telemetry flags */
#define NO_UNIT UNSIGN
/* other flags */
#define TWO_DOTS LEFT
extern uint8_t displayBuf[DISPLAY_W*DISPLAY_H/8];
@@ -112,12 +114,6 @@ extern void putsVolts(uint8_t x, uint8_t y, uint16_t volts, uint8_t att);
extern void putsVBat(uint8_t x, uint8_t y, uint8_t att);
extern void putsTime(uint8_t x,uint8_t y, int16_t tme, uint8_t att, uint8_t att2);
#ifdef FRSKY
// TODO move this into frsky.h
void putsTelemetryChannel(uint8_t x, uint8_t y, uint8_t channel, int16_t val, uint8_t att);
void putsTelemetryValue(uint8_t x, uint8_t y, int16_t val, uint8_t unit, uint8_t att);
#endif
#define SOLID 0xff
#define DOTTED 0x55
+65 -35
View File
@@ -418,7 +418,7 @@ void EditName(uint8_t x, uint8_t y, char *name, uint8_t size, uint8_t event, boo
void menuProcModel(uint8_t event)
{
lcd_outdezNAtt(7*FW,0,g_eeGeneral.currModel+1,INVERS+LEADING0,2);
MENU(STR_MENUSETUP, menuTabModel, e_Model, (g_model.protocol==PROTO_PPM||g_model.protocol==PROTO_DSM2||g_model.protocol==PROTO_PXX ? 12 : 11), {0,ZCHAR|(sizeof(g_model.name)-1),2,2,0,0,0,0,0,6,2,1});
MENU(STR_MENUSETUP, menuTabModel, e_Model, (g_model.protocol==PROTO_PPM||g_model.protocol==PROTO_FAAST||g_model.protocol==PROTO_DSM2||g_model.protocol==PROTO_PXX ? 12 : 11), {0,ZCHAR|(sizeof(g_model.name)-1),2,2,0,0,0,0,0,6,2,1});
uint8_t sub = m_posVert;
uint8_t y = 1*FH;
@@ -523,7 +523,7 @@ void menuProcModel(uint8_t event)
lcd_putsLeft( y, STR_PROTO);
lcd_putsiAtt(PARAM_OFS, y, STR_VPROTOS, g_model.protocol,
(sub==subN && m_posHorz==0 ? (s_editMode>0 ? BLINK|INVERS : INVERS):0));
if (g_model.protocol == PROTO_PPM) {
if (g_model.protocol == PROTO_PPM || g_model.protocol == PROTO_FAAST) {
lcd_putsiAtt(PARAM_OFS+4*FW, y, STR_NCHANNELS, g_model.ppmNCH+2, (sub==subN && m_posHorz==1) ? ((s_editMode>0) ? BLINK|INVERS : INVERS) : 0);
lcd_puts(PARAM_OFS+11*FW, y, PSTR("u"));
lcd_outdezAtt(PARAM_OFS+11*FW, y, (g_model.ppmDelay*50)+300, ((sub==subN && m_posHorz==2) ? ((s_editMode>0) ? BLINK|INVERS : INVERS) : 0));
@@ -543,7 +543,7 @@ void menuProcModel(uint8_t event)
else if (sub==subN) {
m_posHorz = 0;
}
if (sub==subN && (s_editMode>0 || p1valdiff || (g_model.protocol!=0/*TODO constant*/ && g_model.protocol!=PROTO_DSM2))) { // TODO avoid DSM2 when not defined
if (sub==subN && (s_editMode>0 || p1valdiff || (g_model.protocol!=PROTO_PPM && g_model.protocol!=PROTO_FAAST && g_model.protocol!=PROTO_DSM2))) { // TODO avoid DSM2 when not defined
switch (m_posHorz) {
case 0:
CHECK_INCDEC_MODELVAR(event,g_model.protocol,0,PROTO_MAX-1);
@@ -565,7 +565,7 @@ void menuProcModel(uint8_t event)
}subN++;
if(s_pgOfs<subN) {
if (g_model.protocol == PROTO_PPM) {
if (g_model.protocol == PROTO_PPM || g_model.protocol == PROTO_FAAST) {
lcd_putsLeft( y, STR_PPMFRAME);
lcd_puts(PARAM_OFS+3*FW, y, STR_MS);
lcd_outdezAtt(PARAM_OFS, y, (int16_t)g_model.ppmFrameLength*5 + 225, ((sub==subN && m_posHorz==0) ? (s_editMode>0 ? BLINK|INVERS : INVERS) : 0) | PREC1|LEFT);
@@ -1686,7 +1686,7 @@ void menuProcCustomSwitches(uint8_t event)
#if defined(FRSKY)
if (cs.v1 > NUM_XCHNCSW-NUM_TELEMETRY) {
putsTelemetryChannel(20*FW, y, cs.v1 - (NUM_XCHNCSW-NUM_TELEMETRY+1), 128+cs.v2, m_posHorz==2 ? attr : 0);
putsTelemetryChannel(20*FW, y, cs.v1 - (NUM_XCHNCSW-NUM_TELEMETRY+1), convertTelemValue(cs.v1 - (NUM_XCHNCSW-NUM_TELEMETRY+1), 128+cs.v2), m_posHorz==2 ? attr : 0);
v2_min = -128; v2_max = 127;
}
else
@@ -1842,9 +1842,9 @@ void menuProcFunctionSwitches(uint8_t event)
void menuProcTelemetry(uint8_t event)
{
#if defined(FRSKY_HUB) || defined(WS_HOW_HIGH)
MENU(STR_MENUTELEMETRY, menuTabModel, e_Telemetry, 22, {0, (uint8_t)-1, 1, 0, 2, 2, (uint8_t)-1, 1, 0, 2, 2, (uint8_t)-1, 1, 1, (uint8_t)-1, 0, 0, (uint8_t)-1, 2, 2, 2, 2});
MENU(STR_MENUTELEMETRY, menuTabModel, e_Telemetry, 27, {0, (uint8_t)-1, 1, 0, 2, 2, (uint8_t)-1, 1, 0, 2, 2, (uint8_t)-1, 1, 1, (uint8_t)-1, 0, 0, (uint8_t)-1, 1, 1, 1, 1, (uint8_t)-1, 2, 2, 2, 2});
#else
MENU(STR_MENUTELEMETRY, menuTabModel, e_Telemetry, 19, {0, (uint8_t)-1, 1, 0, 2, 2, (uint8_t)-1, 1, 0, 2, 2, (uint8_t)-1, 1, 1, (uint8_t)-1, 2, 2, 2, 2});
MENU(STR_MENUTELEMETRY, menuTabModel, e_Telemetry, 24, {0, (uint8_t)-1, 1, 0, 2, 2, (uint8_t)-1, 1, 0, 2, 2, (uint8_t)-1, 1, 1, (uint8_t)-1, 1, 1, 1, 1, (uint8_t)-1, 2, 2, 2, 2});
#endif
int8_t sub = m_posVert;
@@ -1991,6 +1991,36 @@ void menuProcTelemetry(uint8_t event)
subN++;
#endif
// Display
if(s_pgOfs<subN) {
y = (subN-s_pgOfs)*FH;
lcd_putsLeft(y, STR_DISPLAY);
}
subN++;
for (uint8_t j=0; j<4; j++) {
if (s_pgOfs<subN) {
y = (subN-s_pgOfs)*FH;
for (uint8_t k=0; k<2; k++) {
uint8_t value = getTelemCustomField(j, k);
lcd_putsiAtt(k==0?4:TELEM_COL2, y, STR_VTELEMBARS, value, (sub==subN && m_posHorz==k) ? blink : 0);
if (sub==subN && m_posHorz==k && (s_editMode>0 || p1valdiff)) {
CHECK_INCDEC_MODELVAR(event, value, 0, (j==3 && k==0) ? STATUS_MAX : DISPLAY_MAX);
if (checkIncDec_Ret) {
uint8_t mask = 1 << (2*j+k);
if (value & 1)
g_model.frskyLinesXtra |= mask;
else
g_model.frskyLinesXtra &= ~mask;
value >>= 1;
g_model.frskyLines[j] = (k==0 ? ((g_model.frskyLines[j] & 0xf0) + value) : (g_model.frskyLines[j] & 0x0f) + (value << 4));
}
}
}
}
subN++;
}
// Bars
if(s_pgOfs<subN) {
y = (subN-s_pgOfs)*FH;
@@ -1998,13 +2028,13 @@ void menuProcTelemetry(uint8_t event)
}
subN++;
for (int j=0; j<4; j++) {
for (uint8_t j=0; j<4; j++) {
if (s_pgOfs<subN) {
y = (subN-s_pgOfs)*FH;
lcd_putsiAtt(4, y, STR_VTELEMBARS, g_model.frsky.bars[j].source, (sub==subN && m_posHorz==0) ? blink : 0);
if (g_model.frsky.bars[j].source) {
putsTelemetryChannel(TELEM_COL2-3*FW, y, g_model.frsky.bars[j].source-1, g_model.frsky.bars[j].barMin*5, (sub==subN && m_posHorz==1 ? blink : 0) | LEFT);
putsTelemetryChannel(14*FW-3, y, g_model.frsky.bars[j].source-1, (51-g_model.frsky.bars[j].barMax)*5, (sub==subN && m_posHorz==2 ? blink : 0) | LEFT);
putsTelemetryChannel(TELEM_COL2-3*FW, y, g_model.frsky.bars[j].source-1, convertTelemValue(g_model.frsky.bars[j].source-1, g_model.frsky.bars[j].barMin*5), (sub==subN && m_posHorz==1 ? blink : 0) | LEFT);
putsTelemetryChannel(14*FW-3, y, g_model.frsky.bars[j].source-1, convertTelemValue(g_model.frsky.bars[j].source-1, (51-g_model.frsky.bars[j].barMax)*5), (sub==subN && m_posHorz==2 ? blink : 0) | LEFT);
}
else {
if (sub == subN) m_posHorz = 0;
@@ -2012,7 +2042,7 @@ void menuProcTelemetry(uint8_t event)
if (sub==subN && (s_editMode>0 || p1valdiff)) {
switch (m_posHorz) {
case 0:
CHECK_INCDEC_MODELVAR(event, g_model.frsky.bars[j].source, 0, BAR_MAX-1);
CHECK_INCDEC_MODELVAR(event, g_model.frsky.bars[j].source, 0, BAR_MAX);
break;
case 1:
CHECK_INCDEC_MODELVAR(event, g_model.frsky.bars[j].barMin, 0, 50-g_model.frsky.bars[j].barMax);
@@ -2029,43 +2059,43 @@ void menuProcTelemetry(uint8_t event)
#endif
#ifdef TEMPLATES
void menuProcTemplates(uint8_t event)
// TODO s_noHi needed?
void menuProcTemplates(uint8_t _event)
{
SIMPLE_MENU(STR_MENUTEMPLATES, menuTabModel, e_Templates, 1+NUM_TEMPLATES+1);
uint8_t event = (s_warning ? 0 : _event);
uint8_t y = 0;
uint8_t k = 0;
int8_t sub = m_posVert - 1;
SIMPLE_MENU(STR_MENUTEMPLATES, menuTabModel, e_Templates, 1+TMPL_COUNT);
uint8_t sub = m_posVert - 1;
if (s_confirmation) {
if (sub<TMPL_COUNT)
applyTemplate(sub);
s_confirmation = 0;
AUDIO_WARNING2();
}
switch(event)
{
case EVT_KEY_LONG(KEY_MENU):
case EVT_KEY_FIRST(KEY_MENU):
s_warning = STR_VTEMPLATES+1 + (sub * LEN2_VTEMPLATES);
killEvents(event);
//apply mixes or delete
s_noHi = NO_HI_LEN;
if (sub>=0 && sub<(int8_t)NUM_TEMPLATES)
applyTemplate(sub);
if (sub==NUM_TEMPLATES)
clearMixes();
AUDIO_WARNING2();
_event = 0;
break;
}
y=1*FH;
for(uint8_t i=0; i<7; i++){
uint8_t y = 1*FH;
uint8_t k = 0;
for (uint8_t i=0; i<7 && k<TMPL_COUNT; i++) {
k=i+s_pgOfs;
if(k==NUM_TEMPLATES) break;
//write mix names here
lcd_outdezNAtt(3*FW, y, k+1, (sub==k ? INVERS : 0)|LEADING0, 2);
lcd_putsiAtt(4*FW, y, STR_VTEMPLATES, k, (s_noHi ? 0 : (sub==k ? INVERS : 0)));
lcd_outdezNAtt(3*FW, y, k, (sub==k ? INVERS : 0)|LEADING0, 2);
lcd_putsiAtt(4*FW, y, STR_VTEMPLATES, k, (sub==k ? INVERS : 0));
y+=FH;
}
if(y>7*FH) return;
uint8_t attr = s_noHi ? 0 : ((sub==NUM_TEMPLATES) ? INVERS : 0);
lcd_putsAtt( 1*FW,y,STR_CLEARMIXMENU,attr);
y+=FH;
if (s_warning) {
displayConfirmation(_event);
}
}
#endif
+80 -56
View File
@@ -147,40 +147,41 @@ PACK(typedef struct t_LimitData {
int16_t offset;
}) LimitData;
// TODO enum
#define SRC_RUD 1
#define SRC_ELE 2
#define SRC_THR 3
#define SRC_AIL 4
#define MIX_P1 5
#define MIX_P2 6
#define MIX_P3 7
#define MIX_MAX 8
#define MIX_3POS 9
#define MIX_THR 10
#define MIX_RUD 11
#define MIX_ELE 12
#define MIX_ID0 13
#define MIX_ID1 14
#define MIX_ID2 15
#define MIX_AIL 16
#define MIX_GEA 17
#define MIX_TRN 18
#define MIX_SW1 19
#define MIX_SW9 27
#define MIX_SWA 28
#define MIX_SWB 29
#define MIX_SWC 30
#define MIX_CYC1 31
#define MIX_CYC2 32
#define MIX_CYC3 33
#define MIX_PPM1 34
#define MIX_PPM8 41
#define MIX_CH1 42
#define MIX_CH9 50
#define MIX_CH10 51
#define MIX_CH11 52
#define MIX_CH16 57
enum MixSources {
MIXSRC_Rud = 1,
MIXSRC_Ele,
MIXSRC_Thr,
MIXSRC_Ail,
MIXSRC_P1,
MIXSRC_P2,
MIXSRC_P3,
MIXSRC_MAX ,
MIXSRC_3POS,
MIXSRC_THR,
MIXSRC_RUD,
MIXSRC_ELE,
MIXSRC_ID0,
MIXSRC_ID1,
MIXSRC_ID2,
MIXSRC_AIL,
MIXSRC_GEA,
MIXSRC_TRN,
MIXSRC_SW1,
MIXSRC_SW9 = MIXSRC_SW1 + 8,
MIXSRC_SWA,
MIXSRC_SWB,
MIXSRC_SWC,
MIXSRC_CYC1,
MIXSRC_CYC2,
MIXSRC_CYC3,
MIXSRC_PPM1,
MIXSRC_PPM8 = MIXSRC_PPM1 + 7,
MIXSRC_CH1,
MIXSRC_CH9 = MIXSRC_CH1 + 8,
MIXSRC_CH10,
MIXSRC_CH11,
MIXSRC_CH16 = MIXSRC_CH11 + 5
};
#define TRIM_ON 0
#define TRIM_OFF 1
@@ -266,20 +267,29 @@ PACK(typedef struct t_FrSkyChannelData {
int8_t offset;
}) FrSkyChannelData;
enum BarSource {
BAR_NONE,
BAR_A1,
BAR_A2,
BAR_ALT,
#if defined(FRSKY_HUB)
BAR_RPM,
BAR_FUEL,
BAR_T1,
BAR_T2,
BAR_SPEED,
BAR_CELL,
#endif
BAR_MAX
enum TelemetrySource {
TELEM_NONE,
TELEM_A1,
TELEM_A2,
TELEM_ALT,
TELEM_RPM,
TELEM_FUEL,
TELEM_T1,
TELEM_T2,
TELEM_SPEED,
TELEM_CELL,
TELEM_DIST,
TELEM_ACCx,
TELEM_ACCy,
TELEM_ACCz,
TELEM_TM1,
TELEM_TM2,
TELEM_ACC,
TELEM_GPS_TIME,
BAR_MAX = TELEM_DIST,
DISPLAY_MAX = TELEM_TM2,
STATUS_MAX = TELEM_GPS_TIME
};
PACK(typedef struct t_FrSkyBarData {
@@ -288,9 +298,12 @@ PACK(typedef struct t_FrSkyBarData {
uint16_t barMax:6; // ditto for max display (would usually = ratio)
}) FrSkyBarData;
#define PROTO_NONE 0
#define PROTO_FRSKY_HUB 1
#define PROTO_WS_HOW_HIGH 2
enum FrskyUsrProtocols {
PROTO_NONE,
PROTO_FRSKY_HUB,
PROTO_WS_HOW_HIGH
};
PACK(typedef struct t_FrSkyData {
FrSkyChannelData channels[2];
uint8_t usrProto:3; // Protocol in FrSky user data, 0=None, 1=FrSky hub, 2=WS HowHigh
@@ -346,11 +359,20 @@ PACK(typedef struct t_TimerData {
uint16_t val;
}) TimerData;
#ifdef DSM2
#define LPXDSM2 0
#define DSM2only 1
#define DSM2_DSMX 2
#endif
enum Protocols {
PROTO_PPM,
PROTO_PXX,
PROTO_DSM2,
PROTO_PPM16,
PROTO_FAAST,
PROTO_MAX
};
enum Dsm2Variants {
LPXDSM2,
DSM2only,
DSM2_DSMX
};
PACK(typedef struct t_ModelData {
char name[10]; // 10 must be first for eeLoadModelName
@@ -379,6 +401,8 @@ PACK(typedef struct t_ModelData {
int8_t ppmFrameLength; // 0=22.5ms (10ms-30ms) 0.5msec increments
uint8_t thrTraceSrc;
uint8_t modelId;
uint8_t frskyLines[4];
uint8_t frskyLinesXtra;
}) ModelData;
extern EEGeneral g_eeGeneral;
+1 -6
View File
@@ -149,7 +149,7 @@ const pm_char STR_ALARM[] PROGMEM = TR_ALARM;
const pm_char STR_USRDATA[] PROGMEM = TR_USRDATA;
const pm_char STR_BLADES[] PROGMEM = TR_BLADES; // TODO check that it is optimized away when no FRSKY
const pm_char STR_BARS[] PROGMEM = TR_BARS;
const pm_char STR_CLEARMIXMENU[] PROGMEM = TR_CLEARMIXMENU;
const pm_char STR_DISPLAY[] PROGMEM = TR_DISPLAY;
const pm_char STR_BEEPERMODE[] PROGMEM = TR_BEEPERMODE;
const pm_char STR_BEEPERLEN[] PROGMEM = TR_BEEPERLEN;
#if defined(AUDIO)
@@ -191,11 +191,6 @@ const pm_char STR_SETMIDPOINT[] PROGMEM = TR_SETMIDPOINT;
const pm_char STR_MOVESTICKSPOTS[] PROGMEM = TR_MOVESTICKSPOTS;
const pm_char STR_RXBATT[] PROGMEM = TR_RXBATT;
const pm_char STR_TX[] PROGMEM = TR_TXnRX;
const pm_char STR_SPD[] PROGMEM = TR_SPD;
const pm_char STR_ALT[] PROGMEM = TR_ALT;
const pm_char STR_DST[] PROGMEM = TR_DST;
const pm_char STR_TEMP1nTEMP2[] PROGMEM = TR_TEMP1nTEMP2;
const pm_char STR_RPMnFUEL[] PROGMEM = TR_RPMnFUEL;
const pm_char STR_ACCEL[] PROGMEM = TR_ACCEL;
const pm_char STR_NODATA[] PROGMEM = TR_NODATA;
const pm_char STR_TM1TM2[] PROGMEM = TR_TM1TM2;
+1 -6
View File
@@ -235,7 +235,7 @@ extern const pm_char STR_ALARM[];
extern const pm_char STR_USRDATA[];
extern const pm_char STR_BLADES[];
extern const pm_char STR_BARS[];
extern const pm_char STR_CLEARMIXMENU[];
extern const pm_char STR_DISPLAY[];
extern const pm_char STR_BEEPERMODE[];
extern const pm_char STR_BEEPERLEN[];
extern const pm_char STR_SPKRPITCH[];
@@ -272,11 +272,6 @@ extern const pm_char STR_MOVESTICKSPOTS[];
extern const pm_char STR_RXBATT[];
extern const pm_char STR_TX[];
#define STR_RX (STR_TX+OFS_RX)
extern const pm_char STR_SPD[];
extern const pm_char STR_ALT[];
extern const pm_char STR_DST[];
extern const pm_char STR_TEMP1nTEMP2[];
extern const pm_char STR_RPMnFUEL[];
extern const pm_char STR_ACCEL[];
extern const pm_char STR_NODATA[];
extern const pm_char STR_TM1TM2[];
+28 -36
View File
@@ -298,9 +298,9 @@ int16_t getValue(uint8_t i)
/*srcRaw is shifted +1!*/
if(i<NUM_STICKS+NUM_POTS) return calibratedStick[i];
else if(i<MIX_MAX) return 1024;
else if(i<MIX_3POS) return (keyState(SW_ID0) ? -1024 : (keyState(SW_ID1) ? 0 : 1024));
else if(i<MIX_3POS+3)
else if(i<MIXSRC_MAX) return 1024;
else if(i<MIXSRC_3POS) return (keyState(SW_ID0) ? -1024 : (keyState(SW_ID1) ? 0 : 1024));
else if(i<MIXSRC_3POS+3)
#ifdef HELI
return cyc_anas[i-MIX_3POS];
#else
@@ -316,12 +316,13 @@ int16_t getValue(uint8_t i)
else if(i<CSW_CHOUT_BASE+NUM_CHNOUT+MAX_TIMERS+3) return frskyHubData.baroAltitude_bp;
#endif
#if defined(FRSKY_HUB)
else if(i<CSW_CHOUT_BASE+NUM_CHNOUT+MAX_TIMERS+4) return (frskyHubData.rpm / 2);
else if(i<CSW_CHOUT_BASE+NUM_CHNOUT+MAX_TIMERS+4) return frskyHubData.rpm;
else if(i<CSW_CHOUT_BASE+NUM_CHNOUT+MAX_TIMERS+5) return frskyHubData.fuelLevel;
else if(i<CSW_CHOUT_BASE+NUM_CHNOUT+MAX_TIMERS+6) return frskyHubData.temperature1;
else if(i<CSW_CHOUT_BASE+NUM_CHNOUT+MAX_TIMERS+7) return frskyHubData.temperature2;
else if(i<CSW_CHOUT_BASE+NUM_CHNOUT+MAX_TIMERS+8) return frskyHubData.gpsSpeed_ap;
else if(i<CSW_CHOUT_BASE+NUM_CHNOUT+MAX_TIMERS+9) return frskyHubData.minCellVolts;
else if(i<CSW_CHOUT_BASE+NUM_CHNOUT+MAX_TIMERS+10) return frskyHubData.gpsDistance;
#endif
#endif
else return 0;
@@ -334,7 +335,7 @@ bool __getSwitch(int8_t swtch)
bool result;
if (swtch == 0)
return s_last_switch_used & (1<<15);
return s_last_switch_used & ((uint16_t)1<<15);
uint8_t cs_idx = abs(swtch);
@@ -381,29 +382,15 @@ bool __getSwitch(int8_t swtch)
int16_t x = getValue(cs.v1-1);
int16_t y;
if (s == CS_VOFS) {
#ifdef FRSKY
#if defined(FRSKY_HUB)
// Fill the threshold array
if (cs.v1 > CSW_CHOUT_BASE+NUM_CHNOUT+MAX_TIMERS+2)
barsThresholds[cs.v1-CSW_CHOUT_BASE-NUM_CHNOUT-MAX_TIMERS-3] = 128 + cs.v2;
// TODO CELL?
// FUEL, T1, T2, SPEED
if (cs.v1 > CSW_CHOUT_BASE+NUM_CHNOUT+MAX_TIMERS+4)
y = (128+cs.v2);
// RPMs
else if (cs.v1 > CSW_CHOUT_BASE+NUM_CHNOUT+MAX_TIMERS+3)
y = (128+cs.v2) * 25;
else
#endif
#if defined(FRSKY_HUB) || defined(WS_HOW_HIGH)
// ALT
if (cs.v1 > CSW_CHOUT_BASE+NUM_CHNOUT+MAX_TIMERS+2)
y = (128+cs.v2) * 4;
else
#endif
// Volts
if (cs.v1 > CSW_CHOUT_BASE+NUM_CHNOUT+MAX_TIMERS)
y = 128+cs.v2;
#if defined(FRSKY)
// Telemetry
if (cs.v1 > CSW_CHOUT_BASE+NUM_CHNOUT+MAX_TIMERS) {
y = convertTelemValue(cs.v1-(CSW_CHOUT_BASE+NUM_CHNOUT+MAX_TIMERS+1), 128+cs.v2);
if (cs.v1 > CSW_CHOUT_BASE+NUM_CHNOUT+MAX_TIMERS+2/*A1 and A2*/) {
// Fill the threshold array
barsThresholds[cs.v1-CSW_CHOUT_BASE-NUM_CHNOUT-MAX_TIMERS-3] = 128 + cs.v2;
}
}
else
#endif
// Timers
@@ -459,7 +446,7 @@ bool __getSwitch(int8_t swtch)
bool getSwitch(int8_t swtch, bool nc)
{
s_last_switch_used = (nc<<15);
s_last_switch_used = ((uint16_t)nc<<15);
return __getSwitch(swtch);
}
@@ -616,6 +603,8 @@ void checkTHR()
getADC_single(); // if thr is down - do not display warning at all
#endif
int16_t v = anaIn(thrchn);
if (g_eeGeneral.throttleReversed) v = - v;
if(v<=lowLim) return;
// first - display warning
@@ -631,6 +620,7 @@ void checkTHR()
getADC_single();
#endif
int16_t v = anaIn(thrchn);
if (g_eeGeneral.throttleReversed) v = - v;
if(v<=lowLim || keyDown()) {
clearKeyEvents();
@@ -828,7 +818,7 @@ void getADC_filt()
while ((ADCSRA & 0x10)==0);
ADCSRA|=0x10;
t_ana[0][adc_input] = (t_ana[0][adc_input] + ADCW ) >> 1;
t_ana[0][adc_input] = (t_ana[0][adc_input] + ADCW) >> 1;
}
}
@@ -1261,15 +1251,15 @@ void perOut(uint8_t phase)
int16_t v = 0;
if (k < NUM_STICKS)
v = anas[k]; //Switch is on. MAX=FULL=512 or value.
else if (k>=MIX_CH1-1 && k<=MIX_CH16-1 && k-MIX_CH1+1<md->destCh) // if we've already calculated the value - take it instead
v = chans[k-MIX_CH1+1] / 100;
else if (k>=MIX_THR-1 && k<=MIX_SWC-1) {
v = getSwitch(k-MIX_THR+1+1, 0) ? +1024 : -1024;
else if (k>=MIXSRC_CH1-1 && k<=MIXSRC_CH16-1 && k-MIXSRC_CH1+1<md->destCh) // if we've already calculated the value - take it instead
v = chans[k-MIXSRC_CH1+1] / 100;
else if (k>=MIXSRC_THR-1 && k<=MIXSRC_SWC-1) {
v = getSwitch(k-MIXSRC_THR+1+1, 0) ? +1024 : -1024;
if (v<0 && !md->swtch && (md->delayDown || md->delayUp))
sw = false;
}
else
v = getValue(k <= MIX_3POS ? k : k-MAX_SWITCH);
v = getValue(k <= MIXSRC_3POS ? k : k-MAX_SWITCH);
//========== DELAYS ===============
if (sw) { // switch on? (if no switch selected => on)
@@ -2217,6 +2207,8 @@ int main(void)
uint8_t cModel = g_eeGeneral.currModel;
if (g_model.protocol == PROTO_FAAST) startPulses();
#if defined (PCBV4)
if (MCUSR != (1 << PORF)) {
#else
@@ -2286,7 +2278,7 @@ int main(void)
TCCR4B = (1 << WGM42) | (3<<CS40); // CTC OCR1A, 16MHz / 64 (4us ticks)
#endif
startPulses();
if (g_model.protocol != PROTO_FAAST) startPulses();
wdt_enable(WDTO_500MS);
+3 -9
View File
@@ -336,7 +336,7 @@ enum EnumKeys {
#define NUM_STICKS 4
#define NUM_POTS 3
#define CSW_PPM_BASE (MIX_3POS+3/*CYC1-CYC3*/) // because srcRaw is shifted +1! // TODO use MIX_PPM1
#define CSW_PPM_BASE (MIXSRC_3POS+3/*CYC1-CYC3*/) // because srcRaw is shifted +1!
#define NUM_CAL_PPM 4
#define NUM_PPM 8
#define CSW_CHOUT_BASE (CSW_PPM_BASE+NUM_PPM)
@@ -396,14 +396,6 @@ enum EnumKeys {
#define MAX_ALERT_TIME 60
enum Protocols {
PROTO_PPM,
PROTO_PXX,
PROTO_DSM2,
PROTO_PPM16,
PROTO_MAX
};
extern uint8_t heartbeat;
extern uint32_t inacCounter;
@@ -665,6 +657,8 @@ extern ExpoData *expoaddress(uint8_t idx);
extern MixData *mixaddress(uint8_t idx);
extern LimitData *limitaddress(uint8_t idx);
extern void deleteExpoMix(uint8_t expo, uint8_t idx);
extern void incSubtrim(uint8_t idx, int16_t inc);
extern void instantTrim();
+66 -62
View File
@@ -54,10 +54,15 @@
#include "open9x.h"
#include "templates.h"
MixData* setDest(uint8_t dch)
MixData* setDest(uint8_t dch, bool clear=false)
{
uint8_t i = 0;
while (i<MAX_MIXERS && g_model.mixData[i].srcRaw && g_model.mixData[i].destCh <= dch) i++;
while (i<MAX_MIXERS && g_model.mixData[i].srcRaw && g_model.mixData[i].destCh <= dch) {
if (clear && g_model.mixData[i].destCh == dch)
deleteExpoMix(0, i);
else
i++;
}
if(i==MAX_MIXERS) return &g_model.mixData[0];
memmove(&g_model.mixData[i+1],&g_model.mixData[i],
@@ -99,6 +104,7 @@ const pm_int8_t heli_ar2[] PROGMEM = {90, 70, 50, 70, 90};
const pm_int8_t heli_ar3[] PROGMEM = {-20, -20, 0, 60, 100};
const pm_int8_t heli_ar4[] PROGMEM = {-100, -60, 0, 60, 100};
const pm_int8_t heli_ar5[] PROGMEM = {-100, 0, 0, 0, 100};
void applyTemplate(uint8_t idx)
{
MixData *md = &g_model.mixData[0];
@@ -110,83 +116,88 @@ void applyTemplate(uint8_t idx)
for (uint8_t i=0; i<4; i++) //generate inverse array
for(uint8_t j=0; j<4; j++) if(CC(i+1)==j+1) icc[j]=i;
switch (idx){
// Simple 4-Ch
case (0):
switch (idx) {
// Clear Mixes
case TMPL_CLEAR_MIXES:
clearMixes();
md=setDest(ICC(STK_RUD)); md->srcRaw=SRC_RUD; md->weight=100;
md=setDest(ICC(STK_ELE)); md->srcRaw=SRC_ELE; md->weight=100;
md=setDest(ICC(STK_THR)); md->srcRaw=SRC_THR; md->weight=100;
md=setDest(ICC(STK_AIL)); md->srcRaw=SRC_AIL; md->weight=100;
break;
// Simple 4-Ch
case TMPL_SIMPLE_4CH:
clearMixes();
md=setDest(ICC(STK_RUD)); md->srcRaw=MIXSRC_RUD; md->weight=100;
md=setDest(ICC(STK_ELE)); md->srcRaw=MIXSRC_ELE; md->weight=100;
md=setDest(ICC(STK_THR)); md->srcRaw=MIXSRC_THR; md->weight=100;
md=setDest(ICC(STK_AIL)); md->srcRaw=MIXSRC_AIL; md->weight=100;
break;
// T-Cut
case (1):
md=setDest(ICC(STK_THR)); md->srcRaw=MIX_MAX; md->weight=-100; md->swtch=DSW_THR; md->mltpx=MLTPX_REP;
case TMPL_THR_CUT:
md=setDest(ICC(STK_THR)); md->srcRaw=MIXSRC_MAX; md->weight=-100; md->swtch=DSW_THR; md->mltpx=MLTPX_REP;
break;
// V-Tail
case (2):
md=setDest(ICC(STK_RUD)); md->srcRaw=SRC_RUD; md->weight= 100;
md=setDest(ICC(STK_RUD)); md->srcRaw=SRC_ELE; md->weight=-100;
md=setDest(ICC(STK_ELE)); md->srcRaw=SRC_RUD; md->weight= 100;
md=setDest(ICC(STK_ELE)); md->srcRaw=SRC_ELE; md->weight= 100;
case TMPL_V_TAIL:
md=setDest(ICC(STK_RUD), true); md->srcRaw=MIXSRC_RUD; md->weight= 100;
md=setDest(ICC(STK_RUD)); md->srcRaw=MIXSRC_ELE; md->weight=-100;
md=setDest(ICC(STK_ELE), true); md->srcRaw=MIXSRC_RUD; md->weight= 100;
md=setDest(ICC(STK_ELE)); md->srcRaw=MIXSRC_ELE; md->weight= 100;
break;
// Elevon\\Delta
case (3):
md=setDest(ICC(STK_ELE)); md->srcRaw=SRC_ELE; md->weight= 100;
md=setDest(ICC(STK_ELE)); md->srcRaw=SRC_AIL; md->weight= 100;
md=setDest(ICC(STK_AIL)); md->srcRaw=SRC_ELE; md->weight= 100;
md=setDest(ICC(STK_AIL)); md->srcRaw=SRC_AIL; md->weight=-100;
case TMPL_ELEVON_DELTA:
md=setDest(ICC(STK_ELE), true); md->srcRaw=MIXSRC_ELE; md->weight= 100;
md=setDest(ICC(STK_ELE)); md->srcRaw=MIXSRC_AIL; md->weight= 100;
md=setDest(ICC(STK_AIL), true); md->srcRaw=MIXSRC_ELE; md->weight= 100;
md=setDest(ICC(STK_AIL)); md->srcRaw=MIXSRC_AIL; md->weight=-100;
break;
// eCCPM
case (4):
md=setDest(ICC(STK_ELE)); md->srcRaw=SRC_ELE; md->weight= 72;
md=setDest(ICC(STK_ELE)); md->srcRaw=SRC_THR; md->weight= 55;
md=setDest(ICC(STK_AIL)); md->srcRaw=SRC_ELE; md->weight=-36;
md=setDest(ICC(STK_AIL)); md->srcRaw=SRC_AIL; md->weight= 62;
md=setDest(ICC(STK_AIL)); md->srcRaw=SRC_THR; md->weight= 55;
md=setDest(5); md->srcRaw=SRC_ELE; md->weight=-36;
md=setDest(5); md->srcRaw=SRC_AIL; md->weight=-62;
md=setDest(5); md->srcRaw=SRC_THR; md->weight= 55;
case TMPL_ECCPM:
md=setDest(ICC(STK_ELE), true); md->srcRaw=MIXSRC_ELE; md->weight= 72;
md=setDest(ICC(STK_ELE)); md->srcRaw=MIXSRC_THR; md->weight= 55;
md=setDest(ICC(STK_AIL), true); md->srcRaw=MIXSRC_ELE; md->weight=-36;
md=setDest(ICC(STK_AIL)); md->srcRaw=MIXSRC_AIL; md->weight= 62;
md=setDest(ICC(STK_AIL)); md->srcRaw=MIXSRC_THR; md->weight= 55;
md=setDest(5, true); md->srcRaw=MIXSRC_ELE; md->weight=-36;
md=setDest(5); md->srcRaw=MIXSRC_AIL; md->weight=-62;
md=setDest(5); md->srcRaw=MIXSRC_THR; md->weight= 55;
break;
// Heli Setup
case (5):
case TMPL_HELI_SETUP:
clearMixes(); //This time we want a clean slate
clearCurves();
//Set up Mixes
md=setDest(ICC(STK_AIL)); md->srcRaw=MIX_CH9; md->weight= 50;
md=setDest(ICC(STK_AIL)); md->srcRaw=MIX_CH10; md->weight=-100;
md=setDest(ICC(STK_AIL)); md->srcRaw=MIX_CH11; md->weight= 100; md->carryTrim=TRIM_OFF;
md=setDest(ICC(STK_AIL)); md->srcRaw=MIXSRC_CH9; md->weight= 50;
md=setDest(ICC(STK_AIL)); md->srcRaw=MIXSRC_CH10; md->weight=-100;
md=setDest(ICC(STK_AIL)); md->srcRaw=MIXSRC_CH11; md->weight= 100; md->carryTrim=TRIM_OFF;
md=setDest(ICC(STK_ELE)); md->srcRaw=MIX_CH9; md->weight=-100;
md=setDest(ICC(STK_ELE)); md->srcRaw=MIX_CH11; md->weight= 100; md->carryTrim=TRIM_OFF;
md=setDest(ICC(STK_ELE)); md->srcRaw=MIXSRC_CH9; md->weight=-100;
md=setDest(ICC(STK_ELE)); md->srcRaw=MIXSRC_CH11; md->weight= 100; md->carryTrim=TRIM_OFF;
md=setDest(ICC(STK_THR)); md->srcRaw=SRC_THR; md->weight= 100; md->swtch=DSW_ID0; md->curve=CV(1); md->carryTrim=TRIM_OFF;
md=setDest(ICC(STK_THR)); md->srcRaw=SRC_THR; md->weight= 100; md->swtch=DSW_ID1; md->curve=CV(2); md->carryTrim=TRIM_OFF;
md=setDest(ICC(STK_THR)); md->srcRaw=SRC_THR; md->weight= 110; md->swtch=DSW_ID2; md->curve=CV(2); md->carryTrim=TRIM_OFF;
md=setDest(ICC(STK_THR)); md->srcRaw=MIX_MAX; md->weight=-125; md->swtch=DSW_THR; md->mltpx=MLTPX_REP; md->carryTrim=TRIM_OFF;
md=setDest(ICC(STK_THR)); md->srcRaw=MIXSRC_THR; md->weight= 100; md->swtch=DSW_ID0; md->curve=CV(1); md->carryTrim=TRIM_OFF;
md=setDest(ICC(STK_THR)); md->srcRaw=MIXSRC_THR; md->weight= 100; md->swtch=DSW_ID1; md->curve=CV(2); md->carryTrim=TRIM_OFF;
md=setDest(ICC(STK_THR)); md->srcRaw=MIXSRC_THR; md->weight= 110; md->swtch=DSW_ID2; md->curve=CV(2); md->carryTrim=TRIM_OFF;
md=setDest(ICC(STK_THR)); md->srcRaw=MIXSRC_MAX; md->weight=-125; md->swtch=DSW_THR; md->mltpx=MLTPX_REP; md->carryTrim=TRIM_OFF;
md=setDest(ICC(STK_RUD)); md->srcRaw=SRC_RUD; md->weight=100;
md=setDest(ICC(STK_RUD)); md->srcRaw=MIXSRC_RUD; md->weight=100;
md=setDest(4); md->srcRaw=MIX_MAX; md->weight= 50; md->swtch=-DSW_GEA; md->carryTrim=TRIM_OFF;
md=setDest(4); md->srcRaw=MIX_MAX; md->weight=-50; md->swtch= DSW_GEA; md->carryTrim=TRIM_OFF;
md=setDest(4); md->srcRaw=MIXSRC_MAX; md->weight= 50; md->swtch=-DSW_GEA; md->carryTrim=TRIM_OFF;
md=setDest(4); md->srcRaw=MIXSRC_MAX; md->weight=-50; md->swtch= DSW_GEA; md->carryTrim=TRIM_OFF;
md=setDest(4); md->srcRaw=STK_P3; md->weight= 40; md->carryTrim=TRIM_OFF;
md=setDest(5); md->srcRaw=MIX_CH9; md->weight= -50;
md=setDest(5); md->srcRaw=MIX_CH10; md->weight=-100;
md=setDest(5); md->srcRaw=MIX_CH11; md->weight=-100; md->carryTrim=TRIM_OFF;
md=setDest(5); md->srcRaw=MIXSRC_CH9; md->weight= -50;
md=setDest(5); md->srcRaw=MIXSRC_CH10; md->weight=-100;
md=setDest(5); md->srcRaw=MIXSRC_CH11; md->weight=-100; md->carryTrim=TRIM_OFF;
md=setDest(8); md->srcRaw=SRC_ELE; md->weight= 60;
md=setDest(9); md->srcRaw=SRC_AIL; md->weight=-52;
md=setDest(10); md->srcRaw=SRC_THR; md->weight= 70; md->swtch=DSW_ID0; md->curve=CV(3); md->carryTrim=TRIM_OFF;
md=setDest(10); md->srcRaw=SRC_THR; md->weight= 70; md->swtch=DSW_ID1; md->curve=CV(4); md->carryTrim=TRIM_OFF;
md=setDest(10); md->srcRaw=SRC_THR; md->weight= 70; md->swtch=DSW_ID2; md->curve=CV(4); md->carryTrim=TRIM_OFF;
md=setDest(10); md->srcRaw=SRC_THR; md->weight=100; md->swtch=DSW_THR; md->curve=CV(5); md->carryTrim=TRIM_OFF; md->mltpx=MLTPX_REP;
md=setDest(8); md->srcRaw=MIXSRC_ELE; md->weight= 60;
md=setDest(9); md->srcRaw=MIXSRC_AIL; md->weight=-52;
md=setDest(10); md->srcRaw=MIXSRC_THR; md->weight= 70; md->swtch=DSW_ID0; md->curve=CV(3); md->carryTrim=TRIM_OFF;
md=setDest(10); md->srcRaw=MIXSRC_THR; md->weight= 70; md->swtch=DSW_ID1; md->curve=CV(4); md->carryTrim=TRIM_OFF;
md=setDest(10); md->srcRaw=MIXSRC_THR; md->weight= 70; md->swtch=DSW_ID2; md->curve=CV(4); md->carryTrim=TRIM_OFF;
md=setDest(10); md->srcRaw=MIXSRC_THR; md->weight=100; md->swtch=DSW_THR; md->curve=CV(5); md->carryTrim=TRIM_OFF; md->mltpx=MLTPX_REP;
//Set up Curves
setCurve(CURVE5(1), heli_ar1);
@@ -197,18 +208,11 @@ void applyTemplate(uint8_t idx)
break;
// Servo Test
case (6):
md=setDest(14); md->srcRaw=MIX_CH16; md->weight= 100; md->speedUp = 8; md->speedDown = 8;
md=setDest(15); md->srcRaw=MIX_SW1; md->weight= 110;
md=setDest(15); md->srcRaw=MIX_MAX; md->weight=-110; md->swtch=DSW_SW2; md->mltpx=MLTPX_REP;
md=setDest(15); md->srcRaw=MIX_MAX; md->weight= 110; md->swtch=DSW_SW3; md->mltpx=MLTPX_REP;
setSwitch(1, CS_LESS, CSW_CHOUT_BASE+15, CSW_CHOUT_BASE+16);
setSwitch(2, CS_VPOS, CSW_CHOUT_BASE+15, 105);
setSwitch(3, CS_VNEG, CSW_CHOUT_BASE+15, -105);
case TMPL_SERVO_TEST:
md=setDest(15, true); md->srcRaw=MIXSRC_SW1; md->weight=110; md->mltpx=MLTPX_REP; md->delayUp = 6; md->delayDown = 6; md->speedUp = 8; md->speedDown = 8;
setSwitch(1, CS_VNEG, CSW_CHOUT_BASE+16, 0);
break;
default:
break;
+11 -1
View File
@@ -70,7 +70,17 @@
#define CURVE5(x) ((x)-1)
#define CURVE9(x) (MAX_CURVE5+(x)-1)
#define NUM_TEMPLATES 7
enum Templates {
TMPL_CLEAR_MIXES,
TMPL_SIMPLE_4CH,
TMPL_THR_CUT,
TMPL_V_TAIL,
TMPL_ELEVON_DELTA,
TMPL_ECCPM,
TMPL_HELI_SETUP,
TMPL_SERVO_TEST,
TMPL_COUNT
};
void clearMixes();
void clearCurves();
+6 -10
View File
@@ -36,7 +36,7 @@
#define TR_RETA123 "RETA123"
#define LEN_VPROTOS "\005"
#define TR_VPROTOS "PPM ""PXX ""DSM2 ""PPM16"
#define TR_VPROTOS "PPM\0 ""PXX\0 ""DSM2\0""PPM16""FUT\0 "
#define LEN_POSNEG "\003"
#define TR_POSNEG "POS""NEG"
@@ -92,7 +92,7 @@
#define TR_FUNCSOUNDS "Warn1 ""Warn2 ""Cheep ""Ring ""SciFi ""Robot ""Chirp ""Tada ""Crickt""Siren ""AlmClk""Ratata""Tick ""Haptc1""Haptc2""Haptc3"
#define LEN_VTELEMBARS "\004"
#define TR_VTELEMBARS "---\0""A1\0 ""A2\0 ""ALT\0""RPM\0""FUEL""T1\0 ""T2\0 ""SPD\0""CELL"
#define TR_VTELEMBARS "---\0""A1\0 ""A2\0 ""Alt\0""Rpm\0""Fuel""T1\0 ""T2\0 ""Spd\0""Cell""Dist""ACCx""ACCy""ACCz""TMR1""TMR2""ACC\0""Time"
#define LEN_VTELEMUNIT "\003"
#define TR_VTELEMUNIT "v\0 ""A\0 ""-\0 ""kts""kmh""M/h""m\0 ""@\0 ""%\0"
@@ -112,8 +112,9 @@
#define TR_VTELPROTO "NoneHub "
#endif
#define LEN_VTEMPLATES "\014"
#define TR_VTEMPLATES "Simple 4-CH ""T-Cut ""V-Tail ""Elevon\\Delta""eCCPM ""Heli Setup ""Servo Test "
#define LEN2_VTEMPLATES 13
#define LEN_VTEMPLATES "\015"
#define TR_VTEMPLATES "Clear Mixes\0\0""Simple 4-CH \0""T-Cut \0""V-Tail \0""Elevon\\Delta\0""eCCPM \0""Heli Setup \0""Servo Test \0"
#define LEN_VSWASHTYPE "\004"
#define TR_VSWASHTYPE "--- ""120 ""120X""140 ""90 "
@@ -212,7 +213,7 @@
#define TR_USRDATA "UsrData"
#define TR_BLADES "Blades"
#define TR_BARS "Bars"
#define TR_CLEARMIXMENU "CLEAR MIXES [MENU]"
#define TR_DISPLAY "Display"
#ifdef AUDIO
#define TR_BEEPERMODE "Speaker Mode"
#define TR_BEEPERLEN "Speaker Length"
@@ -254,11 +255,6 @@
#define TR_RXBATT "Rx Batt:"
#define TR_TXnRX "Tx:\0Rx:"
#define OFS_RX 4
#define TR_SPD "Spd:"
#define TR_ALT "Alt:"
#define TR_DST "Dst:"
#define TR_TEMP1nTEMP2 "T@1:\007T@2:"
#define TR_RPMnFUEL "RPM:\006Fuel:"
#define TR_ACCEL "Acc:"
#define TR_NODATA "NO DATA"
#define TR_TM1TM2 "TM1\015TM2"
+5 -9
View File
@@ -36,7 +36,7 @@
#define TR_RETA123 "RETA123"
#define LEN_VPROTOS "\005"
#define TR_VPROTOS "PPM ""PXX ""DSM2 ""PPM16"
#define TR_VPROTOS "PPM\0 ""PXX\0 ""DSM2\0""PPM16""FUT\0 "
#define LEN_POSNEG "\003"
#define TR_POSNEG "POS""NEG"
@@ -92,7 +92,7 @@
#define TR_FUNCSOUNDS "Warn1 ""Warn2 ""Cheep ""Ring ""SciFi ""Robot ""Chirp ""Tada ""Crickt""Siren ""AlmClk""Ratata""Tick ""Haptc1""Haptc2""Haptc3"
#define LEN_VTELEMBARS "\004"
#define TR_VTELEMBARS "---\0""A1\0 ""A2\0 ""ALT\0""RPM\0""FUEL""T1\0 ""T2\0 ""SPD\0""CELL"
#define TR_VTELEMBARS "---\0""A1\0 ""A2\0 ""Alt\0""Rpm\0""Fuel""T1\0 ""T2\0 ""Spd\0""Cell""Dist""ACCx""ACCy""ACCz""TMR1""TMR2""ACC\0""Time"
#define LEN_VTELEMUNIT "\003"
#define TR_VTELEMUNIT "v\0 ""A\0 ""-\0 ""kts""kmh""M/h""m\0 ""@\0 ""%\0"
@@ -112,8 +112,9 @@
#define TR_VTELPROTO "NoneHub "
#endif
#define LEN2_VTEMPLATES 14
#define LEN_VTEMPLATES "\016"
#define TR_VTEMPLATES "4 Voies simple""Coupure Gaz ""Empennage V ""Elevon\\Delta ""eCCPM ""Conf.Helico ""Servo Test "
#define TR_VTEMPLATES "Suppr Mixages\0""4 Voies simple\0""Coupure Gaz \0""Empennage V \0""Elevon\\Delta \0""eCCPM \0""Conf. Helico \0""Servo Test \0"
#define LEN_VSWASHTYPE "\004"
#define TR_VSWASHTYPE "--- ""120 ""120X""140 ""90 "
@@ -211,7 +212,7 @@
#define TR_USRDATA "UsrData"
#define TR_BLADES "Blades"
#define TR_BARS "Gauges"
#define TR_CLEARMIXMENU "EFFACER MIXAGES[MENU]"
#define TR_DISPLAY "Display"
#ifdef AUDIO
#define TR_BEEPERMODE "Speaker Mode"
#define TR_BEEPERLEN "Speaker Length"
@@ -254,11 +255,6 @@
#define TR_RXBATT "Rx Batt:"
#define TR_TXnRX "Tx:\0Rx:"
#define OFS_RX 4
#define TR_SPD "Spd:"
#define TR_ALT "Alt:"
#define TR_DST "Dst:"
#define TR_TEMP1nTEMP2 "T@1:\007T@2:"
#define TR_RPMnFUEL "RPM:\006Fuel:"
#define TR_ACCEL "Acc:"
#define TR_NODATA "NO DATA"
#define TR_TM1TM2 "TM1\015TM2"
+6 -10
View File
@@ -36,7 +36,7 @@
#define TR_RETA123 "RETA123"
#define LEN_VPROTOS "\005"
#define TR_VPROTOS "PPM ""PXX ""DSM2 ""PPM16"
#define TR_VPROTOS "PPM\0 ""PXX\0 ""DSM2\0""PPM16""FUT\0 "
#define LEN_POSNEG "\003"
#define TR_POSNEG "POS""NEG"
@@ -92,7 +92,7 @@
#define TR_FUNCSOUNDS "Varn1 ""Varn2 ""F\200r ""Ring ""SciFi ""Robot ""Pip ""Tada ""Syrsa ""Siren ""Alarm ""Ratata""Tick ""Vibr1 ""Vibr2 ""Vibr3 "
#define LEN_VTELEMBARS "\004"
#define TR_VTELEMBARS "---\0""A1\0 ""A2\0 ""H\205JD""VARV""TANK""T1\0 ""T2\0 ""FART""BATT"
#define TR_VTELEMBARS "---\0""A1\0 ""A2\0 ""Alt\0""Rpm\0""Fuel""T1\0 ""T2\0 ""Spd\0""Cell""Dist""ACCx""ACCy""ACCz""TMR1""TMR2""ACC\0""Time"
#define LEN_VTELEMUNIT "\003"
#define TR_VTELEMUNIT "v\0 ""A\0 ""-\0 ""kts""kmh""M/h""m\0 ""@\0 ""%\0"
@@ -112,8 +112,9 @@
#define TR_VTELPROTO "--- Hub "
#endif
#define LEN_VTEMPLATES "\014"
#define TR_VTEMPLATES "Enkel 4kanal""Gasklippning""V-Stj\201rt ""Deltavinge ""eCCPM ""Helikopter ""Servotest "
#define LEN2_VTEMPLATES 13
#define LEN_VTEMPLATES "\015"
#define TR_VTEMPLATES "Nolla Mixar\0\0""Enkel 4kanal\0""Gasklippning\0""V-Stj\201rt \0""Deltavinge \0""eCCPM \0""Helikopter \0""Servotest \0"
#define LEN_VSWASHTYPE "\004"
#define TR_VSWASHTYPE "--- ""120 ""120X""140 ""90 "
@@ -212,7 +213,7 @@
#define TR_USRDATA "Anv\201ndardata"
#define TR_BLADES "Blad"
#define TR_BARS "Staplar som visas"
#define TR_CLEARMIXMENU "NOLLA MIXAR [MENU]"
#define TR_DISPLAY "Display"
#ifdef AUDIO
#define TR_BEEPERMODE "H\202gtalare l\201ge"
#define TR_BEEPERLEN "H\202gtalare tid"
@@ -254,11 +255,6 @@
#define TR_RXBATT "Rx Batt:"
#define TR_TXnRX "Tx:\0Rx:"
#define OFS_RX 4
#define TR_SPD "Spd:"
#define TR_ALT "Alt:"
#define TR_DST "Dst:"
#define TR_TEMP1nTEMP2 "T@1:\007T@2:"
#define TR_RPMnFUEL "RMP:\006Tank:"
#define TR_ACCEL "Acc:"
#define TR_NODATA "NO DATA"
#define TR_TM1TM2 "TM1\015TM2"