Example #1
0
void displayScrollbar(coord_t x, coord_t y, coord_t h, uint16_t offset, uint16_t count, uint8_t visible)
{
  lcd_vlineStip(x, y, h, DOTTED);
  coord_t yofs = (h * offset) / count;
  coord_t yhgt = (h * visible) / count;
  if (yhgt + yofs > h)
    yhgt = h - yofs;
  lcd_vlineStip(x, y + yofs, yhgt, SOLID, FORCE);
}
void DrawFunction(FnFuncP fn, uint8_t offset)
{
  lcd_vlineStip(X0-offset, 0/*TODO Y0-WCHART*/, WCHART*2, 0xee);
  lcd_hlineStip(X0-WCHART-offset, Y0, WCHART*2, 0xee);

  coord_t prev_yv = (coord_t)-1;

  for (int xv=-WCHART; xv<=WCHART; xv++) {
    coord_t yv = (LCD_H-1) - (((uint16_t)RESX + fn(xv * (RESX/WCHART))) / 2 * (LCD_H-1) / RESX);
    if (prev_yv != (coord_t)-1) {
      if (abs((int8_t)yv-prev_yv) <= 1) {
        lcd_plot(X0+xv-offset-1, prev_yv, FORCE);
      }
      else {
        uint8_t tmp = (prev_yv < yv ? 0 : 1);
        lcd_vline(X0+xv-offset-1, yv+tmp, prev_yv-yv);
      }
    }
    prev_yv = yv;
  }
}
Example #3
0
void displayGaugesTelemetryScreen(FrSkyScreenData & screen)
{
  // Custom Screen with gauges
  int barHeight = 5;
  for (int i=3; i>=0; i--) {
    FrSkyBarData & bar = screen.bars[i];
    source_t source = bar.source;
    getvalue_t barMin = bar.barMin;
    getvalue_t barMax = bar.barMax;
    if (source <= MIXSRC_LAST_CH) {
      barMin = calc100toRESX(barMin);
      barMax = calc100toRESX(barMax);
    }
    if (source && barMax > barMin) {
      int y = barHeight+6+i*(barHeight+6);
      putsMixerSource(0, y+barHeight-5, source, 0);
      lcd_rect(BAR_LEFT, y, BAR_WIDTH+1, barHeight+2);
      getvalue_t value = getValue(source);
      putsChannel(BAR_LEFT+2+BAR_WIDTH, y+barHeight-5, source, LEFT);
      uint8_t thresholdX = 0;
      int width = barCoord(value, barMin, barMax);
      uint8_t barShade = SOLID;
      drawFilledRect(BAR_LEFT+1, 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+BAR_LEFT+1, y+1, barHeight);
        }
      }
      if (thresholdX) {
        lcd_vlineStip(BAR_LEFT+1+thresholdX, y-2, barHeight+3, DOTTED);
        lcd_hline(BAR_LEFT+thresholdX, y-2, 3);
      }
    }
    else {
      barHeight += 2;
    }
  }
  displayRssiLine();
}
Example #4
0
void menuTelemetryFrsky(uint8_t event)
{
  if (event == EVT_KEY_FIRST(KEY_EXIT)) {
    killEvents(event);
    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):
      telemetryReset();
      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 = convertBarTelemValue(source, bar.barMin);
        getvalue_t barMax = convertBarTelemValue(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-1);
#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 = convertBarTelemValue(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();
    }
    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();
              return;
            }
          }
          if (field) {
            fields_count++;
            getvalue_t value = getValue(MIXSRC_FIRST_TELEM+field-1);
            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;
            }
            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;
#if defined(CPUARM)
    lcd_putsiAtt(0, 2*FH, STR_VOLTSRC, g_model.frsky.voltsSource, 0);
#else
    lcd_putsiAtt(0, 2*FH, STR_AMPSRC, g_model.frsky.voltsSource+1, 0);
#endif
    switch (g_model.frsky.voltsSource) {
#if defined(CPUARM)
      case FRSKY_VOLTS_SOURCE_RXBATT:
        putsTelemetryChannel(3*FW+6*FW+4, FH+1, TELEM_RXBATT-1, frskyData.analog[TELEM_ANA_RXBATT].value, DBLSIZE);
        break;
#endif
      case FRSKY_VOLTS_SOURCE_A1:
      case FRSKY_VOLTS_SOURCE_A2:
#if defined(CPUARM)
      case FRSKY_VOLTS_SOURCE_A3:
      case FRSKY_VOLTS_SOURCE_A4:
#endif
        displayVoltageScreenLine(2*FH, g_model.frsky.voltsSource);
        analog = 1+g_model.frsky.voltsSource;
        break;
#if defined(FRSKY_HUB)
      case FRSKY_VOLTS_SOURCE_FAS:
        putsTelemetryChannel(3*FW+6*FW+4, FH+1, TELEM_VFAS-1, frskyData.hub.vfas, DBLSIZE);
        break;
      case FRSKY_VOLTS_SOURCE_CELLS:
        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_AMPSRC, g_model.frsky.currentSource, 0);
      switch(g_model.frsky.currentSource) {
        case FRSKY_CURRENT_SOURCE_A1:
        case FRSKY_CURRENT_SOURCE_A2:
#if defined(CPUARM)
        case FRSKY_CURRENT_SOURCE_A3:
        case FRSKY_CURRENT_SOURCE_A4:
#endif
          displayVoltageScreenLine(4*FH, g_model.frsky.currentSource-1);
          break;
#if defined(FRSKY_HUB)
        case FRSKY_CURRENT_SOURCE_FAS:
          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, TELEMETRY_CELL_VOLTAGE(k), attr, 4);
        y += 1*FH;
      }
#if defined(PCBTARANIS)      
      if (frskyData.hub.cellsCount > 6) {
        y = 1*FH;
        for (uint8_t k=6; k<frskyData.hub.cellsCount && k<12; 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-3*FW-2, y, TELEMETRY_CELL_VOLTAGE(k), attr, 4);
          y += 1*FH;
        }
        lcd_vline(LCD_W-6*FW-4, 8, 47);       
      } else
#endif
      lcd_vline(LCD_W-3*FW-2, 8, 47);
    }
#endif

    displayRssiLine();
  }
#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();
      line+=1*FH+1;
    }
    // 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    
}