Exemple #1
0
void pushMenu(MenuFuncP newMenu)
{
    killEvents(KEY_ENTER);

    if (g_menuStackPtr == 0) {
        if (newMenu == menuGeneralSetup)
            g_menuPos[0] = 1;
        if (newMenu == menuModelSelect)
            g_menuPos[0] = 0;
    }
    else {
        g_menuPos[g_menuStackPtr] = m_posVert;
    }

    g_menuStackPtr++;

    assert(g_menuStackPtr < DIM(g_menuStack));

    AUDIO_MENUS();
    g_menuStack[g_menuStackPtr] = newMenu;
    (*newMenu)(EVT_ENTRY);
}
void check(check_event_t event, uint8_t curr, const MenuHandlerFunc *menuTab, uint8_t menuTabSize, const pm_uint8_t *horTab, uint8_t horTabMax, vertpos_t maxrow)
{
  vertpos_t l_posVert = menuVerticalPosition;
  horzpos_t l_posHorz = menuHorizontalPosition;

  uint8_t maxcol = MAXCOL(l_posVert);

#if defined(NAVIGATION_POT1)
  // check pot 1 - if changed -> scroll values
  static int16_t p1val;
  static int16_t p1valprev;
  p1valdiff = (p1val-calibratedStick[6]) / SCROLL_POT1_TH;
  if (p1valdiff) {
    p1valdiff = (p1valprev-calibratedStick[6]) / 2;
    p1val = calibratedStick[6];
  }
  p1valprev = calibratedStick[6];
#endif

#if defined(NAVIGATION_POT2)
  // check pot 2 - if changed -> scroll menu
  static int16_t p2valprev;
  p2valdiff = (p2valprev-calibratedStick[4]) / SCROLL_TH;
  if (p2valdiff) p2valprev = calibratedStick[4];
#endif

#if defined(NAVIGATION_POT3)
  // check pot 3 if changed -> cursor down/up
  static int16_t p3valprev;
  int8_t scrollUD = (p3valprev-calibratedStick[5]) / SCROLL_TH;
  if (scrollUD) p3valprev = calibratedStick[5];
#else
  #define scrollUD 0
#endif

  if (p2valdiff || scrollUD || p1valdiff) backlightOn(); // on keypress turn the light on

  if (menuTab) {
    uint8_t attr = 0;


    if (l_posVert==0 && !calibrationState) {
      attr = INVERS;

      int8_t cc = curr;

      if (p2valdiff) {
        cc = limit((int8_t)0, (int8_t)(cc - p2valdiff), (int8_t)(menuTabSize-1));
      }

      switch(event) {
#if defined(ROTARY_ENCODER_NAVIGATION)
      case EVT_ROTARY_BREAK:
        if (s_editMode < 0 && maxrow > 0) {
          s_editMode = 0;
          // TODO ? l_posVert = (horTab && horTab[1]==0xff) ? 2 : 1;
          l_posHorz = 0;
        }
        else {
          s_editMode = -1;
        }
        event = 0;
        break;
#endif

#if defined(ROTARY_ENCODER_NAVIGATION)
      case EVT_ROTARY_LEFT:
        if (s_editMode >= 0)
        break;
#endif
      case EVT_KEY_FIRST(KEY_LEFT):
        if (curr > 0)
        cc = curr - 1;
        else
        cc = menuTabSize-1;
        break;

#if defined(ROTARY_ENCODER_NAVIGATION)
      case EVT_ROTARY_RIGHT:
        if (s_editMode >= 0)
        break;
#endif
      case EVT_KEY_FIRST(KEY_RIGHT):
        if (curr < (menuTabSize-1))
        cc = curr + 1;
        else
        cc = 0;
        break;
      }

      if (cc != curr) {
        chainMenu((MenuHandlerFunc)pgm_read_adr(&menuTab[cc]));
      }

#if defined(ROTARY_ENCODER_NAVIGATION)
      if (IS_RE_NAVIGATION_ENABLE() && s_editMode < 0)
      attr = INVERS|BLINK;
#endif
    }

    calibrationState = 0;
    displayScreenIndex(curr, menuTabSize, attr);

  }

  DISPLAY_PROGRESS_BAR(menuTab ? lcdLastPos-2*FW-((curr+1)/10*FWNUM)-2 : 20*FW+1);

  if (s_editMode<=0) {
    if (scrollUD) {
      l_posVert = limit((int8_t)0, (int8_t)(l_posVert - scrollUD), (int8_t)maxrow);
      l_posHorz = min((uint8_t)l_posHorz, MAXCOL(l_posVert));
    }

    if (p2valdiff && l_posVert>0) {
      l_posHorz = limit((int8_t)0, (int8_t)((uint8_t)l_posHorz - p2valdiff), (int8_t)maxcol);
    }
  }

  switch(event)
  {
  case EVT_ENTRY:
    l_posVert = POS_VERT_INIT;
    l_posHorz = POS_HORZ_INIT(l_posVert);
    SET_SCROLLBAR_X(LCD_W-1);
#if defined(ROTARY_ENCODER_NAVIGATION)
    if (menuTab) {
      s_editMode = EDIT_MODE_INIT;
      break;
    }
    // no break
#else
    s_editMode = EDIT_MODE_INIT;
    break;
#endif

#if defined(ROTARY_ENCODER_NAVIGATION)
  case EVT_ENTRY_UP:
    s_editMode = 0;
    SET_SCROLLBAR_X(LCD_W-1);
    break;

  case EVT_ROTARY_BREAK:
    if (s_editMode > 1) break;
#endif

  case EVT_KEY_FIRST(KEY_ENTER):
    if (!menuTab || l_posVert>0) {
      if (READ_ONLY_UNLOCKED()) {
        s_editMode = (s_editMode<=0);
      }
    }
    break;

#if defined(ROTARY_ENCODER_NAVIGATION)
  case EVT_ROTARY_LONG:
    if (s_editMode > 1) break;
    killEvents(event);
    if (l_posVert != POS_VERT_INIT) {
      l_posVert = POS_VERT_INIT;
      s_editMode = EDIT_MODE_INIT;
      break;
    }
    // no break
#endif
  case EVT_KEY_LONG(KEY_EXIT):
    s_editMode = 0; // TODO needed? we call ENTRY_UP after which does the same
    popMenu();
    break;

  case EVT_KEY_BREAK(KEY_EXIT):
#if defined(ROTARY_ENCODER_NAVIGATION)
    if (s_editMode == 0)
    s_editMode = EDIT_MODE_INIT;
    else
#endif
    if (s_editMode>0) {
      s_editMode = 0;
      break;
    }

    if (l_posVert==0 || !menuTab) {
      popMenu();  // beeps itself
    }
    else {
      AUDIO_MENUS();
      l_posVert = 0;
      l_posHorz = 0;
    }
    break;

  case EVT_KEY_REPT(KEY_RIGHT):  //inc
    if (l_posHorz==maxcol) break;
    // no break

  case EVT_KEY_FIRST(KEY_RIGHT)://inc
    if (!horTab || s_editMode>0) break;

#if defined(ROTARY_ENCODER_NAVIGATION)
    CASE_EVT_ROTARY_MOVE_RIGHT
    if (s_editMode != 0) break;
    if (l_posHorz < maxcol) {
      l_posHorz++;
      break;
    }
    else {
      l_posHorz = 0;
      if (!IS_ROTARY_MOVE_RIGHT(event))
      break;
    }
#else
    INC(l_posHorz, 0, maxcol);
    break;
#endif

  case EVT_KEY_REPT(KEY_DOWN):  //inc
    if (!IS_ROTARY_RIGHT(event) && l_posVert==maxrow) break;
    // no break

  case EVT_KEY_FIRST(KEY_DOWN): //inc
    if (s_editMode>0) break;
    do {
      INC(l_posVert, POS_VERT_INIT, maxrow);
    } while (CURSOR_NOT_ALLOWED_IN_ROW(l_posVert));

#if defined(ROTARY_ENCODER_NAVIGATION)
    s_editMode = 0; // if we go down, we must be in this mode
#endif

    l_posHorz = min(l_posHorz, MAXCOL(l_posVert));
    break;

  case EVT_KEY_REPT(KEY_LEFT):  //dec
    if (l_posHorz==0) break;
    // no break

  case EVT_KEY_FIRST(KEY_LEFT)://dec
    if (!horTab || s_editMode>0) break;

#if defined(ROTARY_ENCODER_NAVIGATION)
    CASE_EVT_ROTARY_MOVE_LEFT
    if (s_editMode != 0) break;
    if (l_posHorz > 0) {
      l_posHorz--;
      break;
    }
    else if (IS_ROTARY_MOVE_LEFT(event) && s_editMode == 0) {
      l_posHorz = 0xff;
    }
    else {
      l_posHorz = maxcol;
      break;
    }
#else
    DEC(l_posHorz, 0, maxcol);
    break;
#endif

  case EVT_KEY_REPT(KEY_UP):  //dec
    if (!IS_ROTARY_LEFT(event) && l_posVert==0) break;
    // no break
  case EVT_KEY_FIRST(KEY_UP): //dec
    if (s_editMode>0) break;

    do {
      DEC(l_posVert, POS_VERT_INIT, maxrow);
    } while (CURSOR_NOT_ALLOWED_IN_ROW(l_posVert));

#if defined(ROTARY_ENCODER_NAVIGATION)
    s_editMode = 0; // if we go up, we must be in this mode
#endif

    l_posHorz = min((uint8_t)l_posHorz, MAXCOL(l_posVert));
    break;
  }

  uint8_t maxLines = menuTab ? LCD_LINES-1 : LCD_LINES-2;

  if (l_posVert<1) {
    menuVerticalOffset=0;
  }
  else {
    if (l_posVert>maxLines+menuVerticalOffset) {
      menuVerticalOffset = l_posVert-maxLines;
    }
    else if (l_posVert<=menuVerticalOffset) {
      menuVerticalOffset = l_posVert-1;
    }
  }

  menuVerticalPosition = l_posVert;
  menuHorizontalPosition = l_posHorz;
#if !defined(CPUM64)
  // cosmetics on 9x
  if (menuVerticalOffset > 0) {
    l_posVert--;
    if (l_posVert == menuVerticalOffset && CURSOR_NOT_ALLOWED_IN_ROW(l_posVert)) {
      menuVerticalOffset = l_posVert-1;
    }
  }
#endif
}
Exemple #3
0
void menuTelemetryNMEA2(uint8_t event)
{
    static uint8_t ignore_break;


    switch(event)
    {
// Menu navigation
    case EVT_KEY_BREAK(KEY_LEFT):
        if (ignore_break==1)  {
		    ignore_break=0;
                break;}
        chainMenu(menuTelemetryNMEA1);
        return;
    case EVT_KEY_BREAK(KEY_RIGHT):
          if (ignore_break==1) {
		     ignore_break=0;
                 break;}
        chainMenu(menuTelemetryNMEA3);
        return;
    case EVT_KEY_LONG(KEY_UP):
        NMEA_DisableRXD();
        chainMenu(menuStatisticsView);
        return;
    case EVT_KEY_LONG(KEY_DOWN):
        NMEA_DisableRXD();
        chainMenu(menuMainView);
        return;

//Beep setting
    case EVT_KEY_LONG(KEY_LEFT):
	ignore_break = 1;
        beep_on=0;
        AUDIO_MENUS(); // short blip
        break;
    case EVT_KEY_LONG(KEY_RIGHT):
	  ignore_break = 1;
        beep_on=1;
        AUDIO_MENUS(); 	// short blip
        break;

//Altitude setting
	        /*      Set a home position for altitude. Normally used before starting
      	  the model when GPS has got a fix.
	        MENU[short]         		-->	alternating relative and absolute altitudes
		  MENU[long]			-->   set home altitude to current
		  EXIT[long]			-->   reset max altitude to 0

		  Switch ON / OFF short beep with positive lift
		  LEFT[long]			-->	Positive lift Beep off
		  RIGHT[long]			-->	Positive lift Beep on		*/


    case EVT_KEY_BREAK(KEY_MENU):
        if (ignore_break==1)  {
		    ignore_break=0;
                break;}

        if (!home_alt)				// umschalten zwischen absoluter und relativer H�he
            home_alt = save_alt;
        else
            home_alt=0;	

	  if (save_alt==0)			// wenn noch keine Home H�he gesetzt war, wird sie es jetzt, weil sonst
							// das Umschalten keine Wirkung zeigt
	      save_alt = home_alt = abs_alt;			// absolute altitude
        AUDIO_MENUS();				// short blip for non negative lift
        break;

    case EVT_KEY_LONG(KEY_MENU):
	ignore_break = 1;
        save_alt = home_alt = abs_alt;	// Home altitude auf aktuelle absolute H�he setzen
        AUDIO_MENUS(); 	// short blip for non negative lift
        break;

    case EVT_KEY_LONG(KEY_EXIT):		// Max Altitude auf 0 zur�cksetzen
	max_alt=0;
        AUDIO_MENUS(); 						// short blip for non negative lift
        break;

    }
    title ('2');
    
    lcd_puts         (   1*FW,   1*FH, PSTR("Altitude Sat   Max"));


    lcd_puts         (   16*FW,   3*FH, PSTR("Home"));
    lcd_puts         (   2*FW,   4*FH, PSTR("Lift") );

    lcd_puts         (   16*FW,   5*FH, PSTR("Beep") );
    if (beep_on==1)
        lcd_puts         (   18*FW,   6*FH, PSTR("ON") );
    
    else	
        lcd_puts         (   17*FW,   6*FH, PSTR("OFF") );


    lcd_outdezNAtt(  20*FW,   4*FH, home_alt, PREC1, 6);		// display home_alt, small characters 

    if (xpack[0] != PACK_GGA)
        ggareceived = 0;

    initval (LONG_BUF(0), PACK_GGA, ALT);				// -> rbuf[0]
    initval (LONG_BUF(1), PACK_GGA, GEO);				// -> rbuf[1]
    initval (SHORT_BUF(0), PACK_GGA, MTR);			// -> sbuf[0]
    initval (SHORT_BUF(1), PACK_GGA, FIX);			// -> sbuf[1]
    initval (SHORT_BUF(2), PACK_GGA, SAT);			// -> sbuf[2]

    if (ggareceived)   // at least one second has elapsed
    {
        ggareceived = 0;

        /*      ALT and GEO have one single digit following the decimal point
        e.g. ALT=359.7   GEO=47.7
        The altitude over mean sea level is to be calculated as:
        altitude minus geoidal separation  
        */

        abs_alt = binary(rbuf[0]) - binary(rbuf[1]);		// alt - geo  that is absolute altitude

	  if (abs_alt> max_alt) max_alt=abs_alt;			// hold max altitude relative to 0 m

	  rel_alt=abs_alt - home_alt;					// alt - geo - home  altitude relative to home


        lift_alt = rel_alt - prev_alt;
        prev_alt = rel_alt;

        if ((lift_alt >= 0) && (sbuf[1]>0x30) && beep_on)			// GGA record must have Fix> 0	
            AUDIO_MENUS(); 						// short blip for non negative lift

    }

    if (rbuf[0][0])	 {						
	  lcd_putcAtt   (  13*FW,   1*FH, sbuf[2], 0);				// satellites in view

	  if (sbuf[1]>0x30)	 {							// & GGA has FIX > 0


	        lcd_outdezNAtt(  10*FW,   2*FH, rel_alt, DBLSIZE|PREC1, 7);	// altitude
	
		  if (home_alt >= 0) 
			  lcd_outdezNAtt(  20*FW,   2*FH, (max_alt-home_alt), PREC1, 6);	// display small characters
		  else
			  lcd_outdezNAtt(  20*FW,   2*FH, max_alt, PREC1, 6);			// display small characters
	

	        lcd_putcAtt   (  11*FW,   3*FH, sbuf[0], 0);				// dimension [m]

      	  lcd_outdezNAtt(  10*FW,   5*FH, lift_alt, DBLSIZE|PREC1, 6);	// lift
	        lcd_putcAtt   (  11*FW,   6*FH, sbuf[0], 0);				// dimension [m/S]
      	  lcd_puts    (  12*FW,   6*FH, PSTR("/S") );
		}
    }
    else {
        lcd_putsAtt    (   2*FW,   2*FH, val_unknown, APSIZE);
        lcd_putsAtt    (   2*FW,   5*FH, val_unknown, APSIZE);
    }
}
Exemple #4
0
void chainMenu(MenuFuncP newMenu)
{
    g_menuStack[g_menuStackPtr] = newMenu;
    (*newMenu)(EVT_ENTRY);
    AUDIO_MENUS();
}
Exemple #5
0
void perMain()
{
#if defined(PCBSKY9X) && !defined(REVA)
  calcConsumption();
#endif
  checkSpeakerVolume();
  checkEeprom();
  sdMountPoll();
  writeLogs();
  handleUsbConnection();
  checkTrainerSettings();
  checkBattery();

  uint8_t evt = getEvent(false);
  if (evt && (g_eeGeneral.backlightMode & e_backlight_mode_keys)) backlightOn(); // on keypress turn the light on
  checkBacklight();
#if defined(NAVIGATION_STICKS)
  uint8_t sticks_evt = getSticksNavigationEvent();
  if (sticks_evt) evt = sticks_evt;
#endif

#if defined(USB_MASS_STORAGE)
  if (usbPlugged()) {
    // disable access to menus
    lcd_clear();
    menuMainView(0);
    lcdRefresh();
    return;
  }
#endif

#if defined(LUA)
  uint32_t t0 = get_tmr10ms();
  static uint32_t lastLuaTime = 0;
  uint16_t interval = (lastLuaTime == 0 ? 0 : (t0 - lastLuaTime));
  lastLuaTime = t0;
  if (interval > maxLuaInterval) {
    maxLuaInterval = interval;
  }

  // run Lua scripts that don't use LCD (to use CPU time while LCD DMA is running)
  luaTask(0, RUN_MIX_SCRIPT | RUN_FUNC_SCRIPT | RUN_TELEM_BG_SCRIPT, false);

  // wait for LCD DMA to finish before continuing, because code from this point 
  // is allowed to change the contents of LCD buffer
  // 
  // WARNING: make sure no code above this line does any change to the LCD display buffer!
  //
  lcdRefreshWait();

  // draw LCD from menus or from Lua script
  // run Lua scripts that use LCD

  bool standaloneScriptWasRun = luaTask(evt, RUN_STNDAL_SCRIPT, true);
  bool refreshScreen = true;
  if (!standaloneScriptWasRun) {
    refreshScreen = !luaTask(evt, RUN_TELEM_FG_SCRIPT, true);
  }

  t0 = get_tmr10ms() - t0;
  if (t0 > maxLuaDuration) {
    maxLuaDuration = t0;
  }

  if (!standaloneScriptWasRun)
#else
  lcdRefreshWait();   // WARNING: make sure no code above this line does any change to the LCD display buffer!
  const bool refreshScreen = true;
#endif
  {
    // normal GUI from menus
    const char *warn = s_warning;
    uint8_t menu = s_menu_count;
    if (refreshScreen) {
      lcd_clear();
    }
    if (menuEvent) {
      m_posVert = menuEvent == EVT_ENTRY_UP ? g_menuPos[g_menuStackPtr] : 0;
      m_posHorz = 0;
      evt = menuEvent;
      menuEvent = 0;
      AUDIO_MENUS();
    }
    g_menuStack[g_menuStackPtr]((warn || menu) ? 0 : evt);
    if (warn) DISPLAY_WARNING(evt);
    if (menu) {
      const char * result = displayMenu(evt);
      if (result) {
        menuHandler(result);
        putEvent(EVT_MENU_UP);
      }
    }
    drawStatusLine();
  }

  lcdRefresh();

#if defined(REV9E) && !defined(SIMU)
  topLcdRefreshStart();
  setTopFirstTimer(getValue(MIXSRC_FIRST_TIMER+g_model.topLcdTimer));
  setTopSecondTimer(g_eeGeneral.globalTimer + sessionTimer);
  setTopRssi(TELEMETRY_RSSI());
  setTopBatteryValue(g_vbat100mV);
  setTopBatteryState(GET_TXBATT_BARS(), IS_TXBATT_WARNING());
  topLcdRefreshEnd();
#endif

#if defined(REV9E) && !defined(SIMU)
  bluetoothWakeup();
#endif

#if defined(PCBTARANIS)
  if (requestScreenshot) {
    requestScreenshot = false;
    writeScreenshot();
  }
#endif

}