示例#1
0
void menuTelemetryFrsky(uint8_t event)
{
  if (event == EVT_KEY_FIRST(KEY_EXIT)) {
    chainMenu(menuMainView);
    return;
  }

  switch (event) {
    case EVT_KEY_BREAK(KEY_UP):
      if (s_frsky_view-- == 0)
        s_frsky_view = FRSKY_VIEW_MAX;
      break;

#if defined(PCBTARANIS)
    case EVT_KEY_BREAK(KEY_PAGE):
#endif
    case EVT_KEY_BREAK(KEY_DOWN):
      if (s_frsky_view++ == FRSKY_VIEW_MAX)
        s_frsky_view = 0;
      break;

#if defined(PCBTARANIS)
    case EVT_KEY_LONG(KEY_ENTER):
      killEvents(event);
      MENU_ADD_ITEM(STR_RESET_TELEMETRY);
      MENU_ADD_ITEM(STR_RESET_FLIGHT);
      menuHandler = onMainViewMenu;
      break;
#else
    case EVT_KEY_FIRST(KEY_ENTER):
      resetTelemetry();
	  timerReset(0);
      break;
#endif
  }

  lcdDrawTelemetryTopBar();

  if (s_frsky_view < MAX_FRSKY_SCREENS) {
    FrSkyScreenData & screen = g_model.frsky.screens[s_frsky_view];
#if defined(GAUGES)
    if (g_model.frsky.screensType & (1<<s_frsky_view)) {
      // Custom Screen with gauges
      uint8_t barHeight = 5;
      for (int8_t i=3; i>=0; i--) {
        FrSkyBarData & bar = screen.bars[i];
        uint8_t source = bar.source;
        getvalue_t barMin = convertTelemValue(source, bar.barMin);
        getvalue_t barMax = convertTelemValue(source, 255-bar.barMax);
        if (source && barMax > barMin) {
          uint8_t y = barHeight+6+i*(barHeight+6);
          lcd_putsiAtt(0, y+barHeight-5, STR_VTELEMCHNS, source, 0);
          lcd_rect(25, y, BAR_WIDTH+1, barHeight+2);
          getvalue_t value = getValue(MIXSRC_FIRST_TELEM+source-2);
#if LCD_W >= 212
          putsTelemetryChannel(27+BAR_WIDTH, y+barHeight-6, source-1, value, LEFT);
#endif
          getvalue_t threshold = 0;
          uint8_t thresholdX = 0;
          if (source <= TELEM_TM2)
            threshold = 0;
          else if (source <= TELEM_RSSI_RX)
            threshold = getRssiAlarmValue(source-TELEM_RSSI_TX);
          else if (source <= TELEM_A2)
            threshold = g_model.frsky.channels[source-TELEM_A1].alarms_value[0];
#if defined(FRSKY_HUB)
          else
            threshold = convertTelemValue(source, barsThresholds[source-TELEM_ALT]);
#endif

          if (threshold) {
            thresholdX = barCoord(threshold, barMin, barMax);
            if (thresholdX == 100)
              thresholdX = 0;
          }

          uint8_t width = barCoord(value, barMin, barMax);

          // reversed barshade for T1/T2
          uint8_t barShade = ((threshold > value) ? DOTTED : SOLID);
          if (source == TELEM_T1 || source == TELEM_T2)
            barShade = -barShade;

          lcd_filled_rect(26, y+1, width, barHeight, barShade);

          for (uint8_t j=24; j<99; j+=25)
            if (j>thresholdX || j>width) lcd_vline(j*BAR_WIDTH/100+26, y+1, barHeight);

          if (thresholdX) {
            lcd_vlineStip(26+thresholdX, y-2, barHeight+3, DOTTED);
            lcd_hline(25+thresholdX, y-2, 3);
          }
        }
        else {
          barHeight += 2;
        }
      }
      displayRssiLine();
	  lcd_status_line();
    }
    else
#endif
    {
      // Custom Screen with numbers
	    
      uint8_t fields_count = 0;
      for (uint8_t i=0; i<4; i++) {
        for (uint8_t j=0; j<NUM_LINE_ITEMS; j++) {
          uint8_t field = screen.lines[i].sources[j];
          if (i==3 && j==0) {
#if LCD_W >= 212
            lcd_vline(69, 8, 48);
            lcd_vline(141, 8, 48);
#else
            lcd_vline(63, 8, 48);
#endif
            if (TELEMETRY_STREAMING()) {
#if defined(FRSKY_HUB)
              if (field == TELEM_ACC) {
                lcd_putsLeft(STATUS_BAR_Y, STR_ACCEL);
                lcd_outdezNAtt(4*FW, STATUS_BAR_Y, frskyData.hub.accelX, LEFT|PREC2);
                lcd_outdezNAtt(10*FW, STATUS_BAR_Y, frskyData.hub.accelY, LEFT|PREC2);
                lcd_outdezNAtt(16*FW, STATUS_BAR_Y, frskyData.hub.accelZ, LEFT|PREC2);
                break;
              }
#if defined(GPS)
              else if (field == TELEM_GPS_TIME) {
                 displayGpsTime();
				 
                return;
              }
#endif
#endif
            }
            else {
              displayRssiLine();
			  lcd_status_line();
			  
              return;
            }
          }
          if (field) {
            fields_count++;
            getvalue_t value = getValue(MIXSRC_FIRST_TELEM+field-2);
            uint8_t att = (i==3 ? NO_UNIT : DBLSIZE|NO_UNIT);
#if LCD_W >= 212
            xcoord_t pos[] = {0, 71, 143, 214};
#else
            xcoord_t pos[] = {0, 65, 130};
#endif
            putsTelemetryChannel(pos[j+1]-2, 1+FH+2*FH*i, field-1, value, att);
            
            if (field >= TELEM_TM1 && field <= TELEM_TM2 && i!=3) {
              // there is not enough space on LCD for displaying "Tmr1" or "Tmr2" and still see the - sign, we write "T1" or "T2" instead
              field = field-TELEM_TM1+TELEM_T1;
            }
			
			if (field == TELEM_TX_VOLTAGE){									
            lcd_putsAtt(pos[j], 1+FH+2*FH*i,PSTR("TxBat"), 0);       // Print "TxBat" instead of TBat.
			}
			else 
			{lcd_putsiAtt(pos[j], 1+FH+2*FH*i, STR_VTELEMCHNS, field, 0);
			}
          }
        }
      }
      lcd_status_line();
      if (fields_count == 0)
        putEvent(event == EVT_KEY_BREAK(KEY_UP) ? event : EVT_KEY_BREAK(KEY_DOWN));
    }
  }
  
 
//  else if ( s_frsky_view == e_frsky_voltages ) {
//    // Volts / Amps / Watts / mAh
//    uint8_t analog = 0;
//    //lcd_putsiAtt(0, 2*FH, STR_VOLTSRC, g_model.frsky.voltsSource+1, 0);
//    switch(g_model.frsky.voltsSource) {
//      case 0:
//      case 1:
//        displayVoltageScreenLine(2*FH, g_model.frsky.voltsSource);
//        analog = 1+g_model.frsky.voltsSource;
//        break;
//#if defined(FRSKY_HUB)
//      case 2:
//        lcd_puts(0,2*FH, PSTR("Batt:"));
//		putsTelemetryChannel(3*FW+6*FW+4, FH+1, TELEM_VFAS-1, frskyData.hub.vfas, DBLSIZE);
//        break;
//      case 3:
//        putsTelemetryChannel(3*FW+6*FW+4, FH+1, TELEM_CELLS_SUM-1, frskyData.hub.cellsSum, DBLSIZE);
//        break;
//#endif
//    }

//    if (g_model.frsky.currentSource) {
//     // lcd_putsiAtt(0, 4*FH, STR_VOLTSRC, g_model.frsky.currentSource, 0);
//      switch(g_model.frsky.currentSource) {
//        case 1:
//        case 2:
//          displayVoltageScreenLine(4*FH, g_model.frsky.currentSource-1);
//          break;
//#if defined(FRSKY_HUB)
//        case 3:
//		  lcd_puts(0,4*FH, PSTR("Curr:"));
//          putsTelemetryChannel(3*FW+6*FW+4, 3*FH+1, TELEM_CURRENT-1, frskyData.hub.current, DBLSIZE);
//          break;
//#endif
//      }

//      putsTelemetryChannel(4, 5*FH+1, TELEM_POWER-1, frskyData.hub.power, LEFT|DBLSIZE);
//      putsTelemetryChannel(3*FW+4+4*FW+6*FW+FW, 5*FH+1, TELEM_CONSUMPTION-1, frskyData.hub.currentConsumption, DBLSIZE);
//    }
//    else {
//      displayVoltageScreenLine(analog > 0 ? 5*FH : 4*FH, analog ? 2-analog : 0);
//      if (analog == 0) displayVoltageScreenLine(6*FH, 1);
//    }

//#if defined(FRSKY_HUB)
//    // Cells voltage
//    if (frskyData.hub.cellsCount > 0) {
//      uint8_t y = 1*FH;
//      for (uint8_t k=0; k<frskyData.hub.cellsCount && k<6; k++) {
//#if defined(GAUGES)
//        uint8_t attr = (barsThresholds[THLD_CELL] && frskyData.hub.cellVolts[k] < barsThresholds[THLD_CELL]) ? BLINK|PREC2 : PREC2;
//#else
//        uint8_t attr = PREC2;
//#endif
//        lcd_outdezNAtt(LCD_W, y, frskyData.hub.cellVolts[k] * 2, attr, 4);
//        y += 1*FH;
//      }
//      lcd_vline(LCD_W-3*FW-2, 8, 47);
//    }
//#endif

    
//	displayRssiLine();
//	lcd_status_line();
//  }
  
  
#if defined(FRSKY_HUB)
  else if (s_frsky_view == e_frsky_after_flight) {
    uint8_t line=1*FH+1;
    if (IS_GPS_AVAILABLE()) {
      // Latitude
      lcd_putsLeft(line, STR_LATITUDE);
      displayGpsCoord(line, frskyData.hub.gpsLatitudeNS, frskyData.hub.gpsLatitude_bp, frskyData.hub.gpsLatitude_ap);
      // Longitude
      line+=1*FH+1;
      lcd_putsLeft(line, STR_LONGITUDE);
      displayGpsCoord(line, frskyData.hub.gpsLongitudeEW, frskyData.hub.gpsLongitude_bp, frskyData.hub.gpsLongitude_ap);
      // displayGpsTime();
	  //lcd_status_line();
      line+=1*FH+1;
    }
    
	 lcd_putsLeft(line, PSTR("Altitude  "));
	 putsTelemetryChannel(14*FW, line, TELEM_ALT-1, frskyData.hub.baroAltitude_bp, SMLSIZE);
	 
	 
	  displayRssiLine();
	  lcd_status_line();
	 
	
	// Rssi
	//    lcd_putsLeft(line, STR_MINRSSI);
	// #if defined(PCBTARANIS)
	//    lcd_outdezNAtt(TELEM_2ND_COLUMN, line, frskyData.rssi[0].min, LEFT|LEADING0, 2);
	//#else
	//    lcd_puts(TELEM_2ND_COLUMN, line, STR_TX);
	//    lcd_outdezNAtt(TELEM_2ND_COLUMN+3*FW, line, frskyData.rssi[1].min, LEFT|LEADING0, 2);
	//    lcd_puts(TELEM_2ND_COLUMN+6*FW, line, STR_RX);
	//    lcd_outdezNAtt(TELEM_2ND_COLUMN+9*FW, line, frskyData.rssi[0].min, LEFT|LEADING0, 2);
	//#endif
   
  }
#endif    
}
示例#2
0
void applyExpos(int16_t *anas, uint8_t mode APPLY_EXPOS_EXTRA_PARAMS)
{
#if defined(PCBTARANIS)
#if defined(HELI)
  int16_t heliAnasCopy[4];
  memcpy(heliAnasCopy, heliAnas, sizeof(heliAnasCopy));
#endif
#else
  int16_t anas2[NUM_INPUTS]; // values before expo, to ensure same expo base when multiple expo lines are used
  memcpy(anas2, anas, sizeof(anas2));
#endif

  int8_t cur_chn = -1;

  for (uint8_t i=0; i<MAX_EXPOS; i++) {
#if defined(BOLD_FONT)
    if (mode==e_perout_mode_normal) swOn[i].activeExpo = false;
#endif
    ExpoData * ed = expoAddress(i);
    if (!EXPO_VALID(ed)) break; // end of list
    if (ed->chn == cur_chn)
      continue;
    if (ed->flightModes & (1<<mixerCurrentFlightMode))
      continue;
    if (getSwitch(ed->swtch)) {
#if defined(PCBTARANIS)
      int v;
      if (ed->srcRaw == ovwrIdx)
        v = ovwrValue;
#if defined(HELI)
      else if (ed->srcRaw == MIXSRC_Ele)
        v = heliAnasCopy[ELE_STICK];
      else if (ed->srcRaw == MIXSRC_Ail)
        v = heliAnasCopy[AIL_STICK];
#endif
      else {
        v = getValue(ed->srcRaw);
        if (ed->srcRaw >= MIXSRC_FIRST_TELEM && ed->scale > 0) {
          v = (v * 1024) / convertTelemValue(ed->srcRaw-MIXSRC_FIRST_TELEM+1, ed->scale);
        }
        v = limit(-1024, v, 1024);
      }
#else
      int16_t v = anas2[ed->chn];
#endif
      if (EXPO_MODE_ENABLE(ed, v)) {
#if defined(BOLD_FONT)
        if (mode==e_perout_mode_normal) swOn[i].activeExpo = true;
#endif
        cur_chn = ed->chn;

        //========== CURVE=================
#if defined(PCBTARANIS)
        if (ed->curve.value) {
          v = applyCurve(v, ed->curve);
        }
#else
        int8_t curveParam = ed->curveParam;
        if (curveParam) {
          if (ed->curveMode == MODE_CURVE)
            v = applyCurve(v, curveParam);
          else
            v = expo(v, GET_GVAR(curveParam, -100, 100, mixerCurrentFlightMode));
        }
#endif

        //========== WEIGHT ===============
        int16_t weight = GET_GVAR(ed->weight, MIN_EXPO_WEIGHT, 100, mixerCurrentFlightMode);
        weight = calc100to256(weight);
        v = ((int32_t)v * weight) >> 8;

#if defined(PCBTARANIS)
        //========== OFFSET ===============
        int16_t offset = GET_GVAR(ed->offset, -100, 100, mixerCurrentFlightMode);
        if (offset) v += calc100toRESX(offset);

        //========== TRIMS ================
        if (ed->carryTrim < TRIM_ON)
          virtualInputsTrims[cur_chn] = -ed->carryTrim - 1;
        else if (ed->carryTrim == TRIM_ON && ed->srcRaw >= MIXSRC_Rud && ed->srcRaw <= MIXSRC_Ail)
          virtualInputsTrims[cur_chn] = ed->srcRaw - MIXSRC_Rud;
        else
          virtualInputsTrims[cur_chn] = -1;

#if defined(HELI)
        if (ed->srcRaw == MIXSRC_Ele) {
          heliAnas[ELE_STICK] = v;
          heliTrims[ELE_STICK] = virtualInputsTrims[cur_chn];
        }
        else if (ed->srcRaw == MIXSRC_Ail) {
          heliAnas[AIL_STICK] = v;
          heliTrims[AIL_STICK] = virtualInputsTrims[cur_chn];
        }
#endif
#endif

        anas[cur_chn] = v;
      }
    }
  }
void menuModelExpoOne(uint8_t event)
{
  if (event == EVT_KEY_LONG(KEY_MENU)) {
    pushMenu(menuChannelsView);
    killEvents(event);
  }

  ExpoData *ed = expoAddress(s_currIdx);
  putsMixerSource(7*FW+FW/2, 0, MIXSRC_FIRST_INPUT+ed->chn, 0);

  SUBMENU(STR_MENUINPUTS, EXPO_FIELD_MAX, {0, 0, 0, ed->srcRaw >= MIXSRC_FIRST_TELEM ? (uint8_t)0 : (uint8_t)HIDDEN_ROW, 0, 0, CASE_CURVES(CURVE_ROWS) CASE_FLIGHT_MODES((MAX_FLIGHT_MODES-1) | NAVIGATION_LINE_BY_LINE) 0 /*, ...*/});

  SET_SCROLLBAR_X(EXPO_ONE_2ND_COLUMN+10*FW);

  int8_t sub = m_posVert;

  coord_t y = MENU_HEADER_HEIGHT + 1;

  for (unsigned int k=0; k<NUM_BODY_LINES; k++) {
    int i = k + s_pgOfs;
    for (int j=0; j<=i; ++j) {
      if (j<(int)DIM(mstate_tab) && mstate_tab[j] == HIDDEN_ROW) {
        ++i;
      }
    }
    LcdFlags attr = (sub==i ? (s_editMode>0 ? BLINK|INVERS : INVERS) : 0);
    switch(i)
    {
      case EXPO_FIELD_INPUT_NAME:
        editSingleName(EXPO_ONE_2ND_COLUMN, y, STR_INPUTNAME, g_model.inputNames[ed->chn], sizeof(g_model.inputNames[ed->chn]), event, attr);
        break;

      case EXPO_FIELD_NAME:
        editSingleName(EXPO_ONE_2ND_COLUMN, y, STR_EXPONAME, ed->name, sizeof(ed->name), event, attr);
        break;

      case EXPO_FIELD_SOURCE:
        lcd_putsLeft(y, NO_INDENT(STR_SOURCE));
        putsMixerSource(EXPO_ONE_2ND_COLUMN, y, ed->srcRaw, STREXPANDED|attr);
        if (attr) ed->srcRaw = checkIncDec(event, ed->srcRaw, INPUTSRC_FIRST, INPUTSRC_LAST, EE_MODEL|INCDEC_SOURCE|NO_INCDEC_MARKS, isInputSourceAvailable);
        break;

      case EXPO_FIELD_SCALE:
        lcd_putsLeft(y, STR_SCALE);
        putsTelemetryChannelValue(EXPO_ONE_2ND_COLUMN, y, (ed->srcRaw - MIXSRC_FIRST_TELEM)/3, convertTelemValue(ed->srcRaw - MIXSRC_FIRST_TELEM + 1, ed->scale), LEFT|attr);
        if (attr) ed->scale = checkIncDec(event, ed->scale, 0, maxTelemValue(ed->srcRaw - MIXSRC_FIRST_TELEM + 1), EE_MODEL);
        break;

      case EXPO_FIELD_WEIGHT:
        lcd_putsLeft(y, STR_WEIGHT);
        ed->weight = GVAR_MENU_ITEM(EXPO_ONE_2ND_COLUMN, y, ed->weight, MIN_EXPO_WEIGHT, 100, LEFT|attr, 0, event);
        break;

      case EXPO_FIELD_OFFSET:
        lcd_putsLeft(y, NO_INDENT(STR_OFFSET));
        ed->offset = GVAR_MENU_ITEM(EXPO_ONE_2ND_COLUMN, y, ed->offset, -100, 100, LEFT|attr, 0, event);
        break;

#if defined(CURVES)
      case EXPO_FIELD_CURVE:
        lcd_putsLeft(y, STR_CURVE);
        editCurveRef(EXPO_ONE_2ND_COLUMN, y, ed->curve, event, attr);
        break;
#endif

#if defined(FLIGHT_MODES)
      case EXPO_FIELD_FLIGHT_MODES:
        ed->flightModes = editFlightModes(EXPO_ONE_2ND_COLUMN, y, event, ed->flightModes, attr);
        break;
#endif

      case EXPO_FIELD_SWITCH:
        ed->swtch = switchMenuItem(EXPO_ONE_2ND_COLUMN, y, ed->swtch, attr, event);
        break;

      case EXPO_FIELD_SIDE:
        ed->mode = 4 - selectMenuItem(EXPO_ONE_2ND_COLUMN, y, STR_SIDE, STR_VSIDE, 4-ed->mode, 1, 3, attr, event);
        break;

      case EXPO_FIELD_TRIM:
        uint8_t not_stick = (ed->srcRaw > MIXSRC_Ail);
        int8_t carryTrim = -ed->carryTrim;
        lcd_putsLeft(y, STR_TRIM);
        lcd_putsiAtt(EXPO_ONE_2ND_COLUMN, y, STR_VMIXTRIMS, (not_stick && carryTrim == 0) ? 0 : carryTrim+1, m_posHorz==0 ? attr : 0);
        if (attr) ed->carryTrim = -checkIncDecModel(event, carryTrim, not_stick ? TRIM_ON : -TRIM_OFF, -TRIM_AIL);
        break;
    }
    y += FH;
  }

  DrawFunction(expoFn);

  int x512 = getValue(ed->srcRaw);
  if (ed->srcRaw >= MIXSRC_FIRST_TELEM) {
    putsTelemetryChannelValue(LCD_W-8, 6*FH, (ed->srcRaw - MIXSRC_FIRST_TELEM) / 3, x512, 0);
    if (ed->scale > 0) x512 = (x512 * 1024) / convertTelemValue(ed->srcRaw - MIXSRC_FIRST_TELEM + 1, ed->scale);
  }
  else {
    lcd_outdezAtt(LCD_W-8, 6*FH, calcRESXto1000(x512), PREC1);
  }
  x512 = limit(-1024, x512, 1024);
  int y512 = expoFn(x512);
  y512 = limit(-1024, y512, 1024);
  lcd_outdezAtt(LCD_W-8-6*FW, 1*FH, calcRESXto1000(y512), PREC1);

  x512 = X0+x512/(RESX/WCHART);
  y512 = (LCD_H-1) - ((y512+RESX)/2) * (LCD_H-1) / RESX;

  lcd_vline(x512, y512-3, 3*2+1);
  lcd_hline(x512-3, y512, 3*2+1);
}