void updateProgressBar(int num, int den) { if (num > 0 && den > 0) { int width = (200*num)/den; lcd_hline(5, 6*FH+6, width, FORCE); lcd_hline(5, 6*FH+7, width, FORCE); lcd_hline(5, 6*FH+8, width, FORCE); lcdRefresh(); } }
/* Draw a rectangular box */ void lcd_drawrect(int x, int y, int width, int height) { if ((width <= 0) || (height <= 0)) return; int x2 = x + width - 1; int y2 = y + height - 1; lcd_vline(x, y, y2); lcd_vline(x2, y, y2); lcd_hline(x, x2, y); lcd_hline(x, x2, y2); }
void menuStatisticsView(uint8_t event) { TITLE(STR_MENUSTAT); switch(event) { case EVT_KEY_FIRST(KEY_UP): chainMenu(menuStatisticsDebug); break; case EVT_KEY_LONG(KEY_MENU): g_eeGeneral.globalTimer = 0; eeDirty(EE_GENERAL); sessionTimer = 0; break; case EVT_KEY_FIRST(KEY_EXIT): chainMenu(menuMainView); break; } // Session and Total timers lcd_putsAtt(STATS_1ST_COLUMN, FH*1+1, "SES", BOLD); putsTimer(STATS_1ST_COLUMN + STATS_LABEL_WIDTH, FH*1+1, sessionTimer, 0, 0); lcd_putsAtt(STATS_1ST_COLUMN, FH*2+1, "TOT", BOLD); putsTimer(STATS_1ST_COLUMN + STATS_LABEL_WIDTH, FH*2+1, g_eeGeneral.globalTimer + sessionTimer, TIMEHOUR, 0); // Throttle special timers lcd_putsAtt(STATS_2ND_COLUMN, FH*0+1, "THR", BOLD); putsTimer(STATS_2ND_COLUMN + STATS_LABEL_WIDTH, FH*0+1, s_timeCumThr, 0, 0); lcd_putsAtt(STATS_2ND_COLUMN, FH*1+1, "TH%", BOLD); putsTimer(STATS_2ND_COLUMN + STATS_LABEL_WIDTH, FH*1+1, s_timeCum16ThrP/16, 0, 0); // Timers for (int i=0; i<TIMERS; i++) { putsStrIdx(STATS_3RD_COLUMN, FH*i+1, "TM", i+1, BOLD); if (timersStates[i].val > 3600) putsTimer(STATS_3RD_COLUMN + STATS_LABEL_WIDTH, FH*i+1, timersStates[i].val, TIMEHOUR, 0); else putsTimer(STATS_3RD_COLUMN + STATS_LABEL_WIDTH, FH*i+1, timersStates[i].val, 0, 0); } #if defined(THRTRACE) coord_t traceRd = (s_traceCnt < 0 ? s_traceWr : 0); const coord_t x = 5; const coord_t y = 60; lcd_hline(x-3, y, MAXTRACE+3+3); lcd_vline(x, y-32, 32+3); for (coord_t i=0; i<MAXTRACE; i+=6) { lcd_vline(x+i+6, y-1, 3); } for (coord_t i=1; i<=MAXTRACE; i++) { lcd_vline(x+i, y-s_traceBuf[traceRd], s_traceBuf[traceRd]); traceRd++; if (traceRd>=MAXTRACE) traceRd = 0; if (traceRd==s_traceWr) break; } #endif }
void lcd_gradient_fillrect(int x, int y, int width, int height, unsigned start_rgb, unsigned end_rgb) { int old_pattern = current_vp->fg_pattern; int step_mul, i; int x1, x2; x1 = x; x2 = x + width; if (height == 0) return; step_mul = (1 << 16) / height; int h_r = RGB_UNPACK_RED(start_rgb); int h_g = RGB_UNPACK_GREEN(start_rgb); int h_b = RGB_UNPACK_BLUE(start_rgb); int rstep = (h_r - RGB_UNPACK_RED(end_rgb)) * step_mul; int gstep = (h_g - RGB_UNPACK_GREEN(end_rgb)) * step_mul; int bstep = (h_b - RGB_UNPACK_BLUE(end_rgb)) * step_mul; h_r = (h_r << 16) + (1 << 15); h_g = (h_g << 16) + (1 << 15); h_b = (h_b << 16) + (1 << 15); for(i = y; i < y + height; i++) { current_vp->fg_pattern = LCD_RGBPACK(h_r >> 16, h_g >> 16, h_b >> 16); lcd_hline(x1, x2, i); h_r -= rstep; h_g -= gstep; h_b -= bstep; } current_vp->fg_pattern = old_pattern; }
/*luadoc @function lcd.drawCombobox(x, y, w, list, idx [, flags]) Draws a combo box @param x,y (positive numbers) top left corner position @param w (number) width of combo box in pixels @param list (table) combo box elements, each element is a string @param idx (integer) index of entry to highlight @param page (number) page number @param flags (unsigned number) drawing flags, the flags can not be combined: * `BLINK` combo box is expanded * `INVERS` combo box collapsed, text inversed * `0 or not present` combo box collapsed, text normal @status current Introduced in 2.0.0 */ static int luaLcdDrawCombobox(lua_State *L) { if (!luaLcdAllowed) return 0; int x = luaL_checkinteger(L, 1); int y = luaL_checkinteger(L, 2); int w = luaL_checkinteger(L, 3); luaL_checktype(L, 4, LUA_TTABLE); int count = luaL_len(L, 4); /* get size of table */ int idx = luaL_checkinteger(L, 5); unsigned int flags = luaL_optunsigned(L, 6, 0); if (idx >= count) { // TODO error } if (flags & BLINK) { drawFilledRect(x, y, w-9, count*9+2, SOLID, ERASE); lcd_rect(x, y, w-9, count*9+2); for (int i=0; i<count; i++) { lua_rawgeti(L, 4, i+1); const char * item = luaL_checkstring(L, -1); lcd_putsAtt(x+2, y+2+9*i, item, 0); } drawFilledRect(x+1, y+1+9*idx, w-11, 9); drawFilledRect(x+w-10, y, 10, 11, SOLID, ERASE); lcd_rect(x+w-10, y, 10, 11); } else if (flags & INVERS) { drawFilledRect(x, y, w, 11); drawFilledRect(x+w-9, y+1, 8, 9, SOLID, ERASE); lua_rawgeti(L, 4, idx+1); const char * item = luaL_checkstring(L, -1); lcd_putsAtt(x+2, y+2, item, INVERS); } else { drawFilledRect(x, y, w, 11, SOLID, ERASE); lcd_rect(x, y, w, 11); drawFilledRect(x+w-10, y+1, 9, 9, SOLID); lua_rawgeti(L, 4, idx+1); const char * item = luaL_checkstring(L, -1); lcd_putsAtt(x+2, y+2, item, 0); } lcd_hline(x+w-8, y+3, 6); lcd_hline(x+w-8, y+5, 6); lcd_hline(x+w-8, y+7, 6); return 0; }
void drawGauge(coord_t x, coord_t y, coord_t w, coord_t h, int32_t val, int32_t max) { lcd_rect(x, y, w+1, h); drawFilledRect(x+1, y+1, w-1, 4, SOLID, ERASE); coord_t len = limit((uint8_t)1, uint8_t((abs(val) * w/2 + max/2) / max), uint8_t(w/2)); coord_t x0 = (val>0) ? x+w/2 : x+1+w/2-len; for (coord_t i=h-2; i>0; i--) { lcd_hline(x0, y+i, len); } }
void drawStick(coord_t centrex, int16_t xval, int16_t yval) { #define BOX_CENTERY (LCD_H-BOX_WIDTH/2-10) #define MARKER_WIDTH 5 lcd_square(centrex-BOX_WIDTH/2, BOX_CENTERY-BOX_WIDTH/2, BOX_WIDTH); lcd_vline(centrex, BOX_CENTERY-1, 3); lcd_hline(centrex-1, BOX_CENTERY, 3); lcd_square(centrex + (xval/((2*RESX)/(BOX_WIDTH-MARKER_WIDTH))) - MARKER_WIDTH/2, BOX_CENTERY - (yval/((2*RESX)/(BOX_WIDTH-MARKER_WIDTH))) - MARKER_WIDTH/2, MARKER_WIDTH, ROUND); #undef BOX_CENTERY #undef MARKER_WIDTH }
void menuStatisticsView(uint8_t event) { TITLE(STR_MENUSTAT); switch(event) { case EVT_KEY_FIRST(KEY_UP): chainMenu(menuStatisticsDebug); return; #if defined(CPUARM) case EVT_KEY_LONG(KEY_MENU): g_eeGeneral.globalTimer = 0; eeDirty(EE_GENERAL); sessionTimer = 0; break; #endif case EVT_KEY_FIRST(KEY_EXIT): chainMenu(menuMainView); return; } lcd_puts( 1*FW, FH*0, STR_TOTTM1TM2THRTHP); putsTimer( 5*FW+5*FWNUM+1, FH*1, timersStates[0].val, 0, 0); putsTimer( 12*FW+5*FWNUM+1, FH*1, timersStates[1].val, 0, 0); putsTimer( 5*FW+5*FWNUM+1, FH*2, s_timeCumThr, 0, 0); putsTimer( 12*FW+5*FWNUM+1, FH*2, s_timeCum16ThrP/16, 0, 0); putsTimer( 12*FW+5*FWNUM+1, FH*0, sessionTimer, 0, 0); #if defined(CPUARM) putsTimer(21*FW+5*FWNUM+1, 0*FH, g_eeGeneral.globalTimer + sessionTimer, TIMEHOUR, 0); #endif #if defined(THRTRACE) uint8_t traceRd = (s_traceCnt < 0 ? s_traceWr : 0); const uint8_t x=5; const uint8_t y=60; lcd_hline(x-3,y,MAXTRACE+3+3); lcd_vline(x,y-32,32+3); for (uint8_t i=0; i<MAXTRACE; i+=6) { lcd_vline(x+i+6,y-1,3); } for (uint8_t i=1; i<=MAXTRACE; i++) { lcd_vline(x+i, y-s_traceBuf[traceRd], s_traceBuf[traceRd]); traceRd++; if (traceRd>=MAXTRACE) traceRd = 0; if (traceRd==s_traceWr) break; } #endif }
void displayRssiLine() { if (TELEMETRY_STREAMING()) { lcd_hline(0, 55, 212, 0); // separator uint8_t rssi = min((uint8_t)99, frskyData.rssi[0].value); lcd_putsn(0, STATUS_BAR_Y, STR_RX, 2); lcd_outdezNAtt(4*FW, STATUS_BAR_Y, rssi, LEADING0, 2); lcd_rect(25, 57, 78, 7); lcd_filled_rect(26, 58, 19*rssi/25, 5, (rssi < getRssiAlarmValue(0)) ? DOTTED : SOLID); } else { lcd_putsAtt(7*FW, STATUS_BAR_Y, STR_NODATA, BLINK); lcd_status_line(); } }
/*luadoc @function lcd.drawGauge(x, y, w, h, fill, maxfill) Draws a simple gauge that is filled based upon fill value @param x,y (positive numbers) top left corner position @param w (number) width in pixels @param h (number) height in pixels @param fill (number) amount of fill to apply @param maxfill (number) total value of fill @param flags (unsigned number) drawing flags @status current Introduced in 2.0.0 */ static int luaLcdDrawGauge(lua_State *L) { if (!luaLcdAllowed) return 0; int x = luaL_checkinteger(L, 1); int y = luaL_checkinteger(L, 2); int w = luaL_checkinteger(L, 3); int h = luaL_checkinteger(L, 4); int num = luaL_checkinteger(L, 5); int den = luaL_checkinteger(L, 6); // int flags = luaL_checkinteger(L, 7); lcd_rect(x, y, w, h); uint8_t len = limit((uint8_t)1, uint8_t(w*num/den), uint8_t(w)); for (int i=1; i<h-1; i++) { lcd_hline(x+1, y+i, len); } return 0; }
void menuProcStatistic(uint8_t event) { TITLE("STAT"); switch(event) { case EVT_KEY_FIRST(KEY_UP): chainMenu(menuProcStatistic2); break; case EVT_KEY_FIRST(KEY_DOWN): case EVT_KEY_FIRST(KEY_EXIT): chainMenu(menuMainView); break; } lcd_puts_P( 1*FW, FH*1, PSTR("TME")); putsTime( 5*FW, FH*1, s_timeCumAbs, 0, 0); lcd_puts_P( 17*FW, FH*1, PSTR("TSW")); putsTime( 11*FW, FH*1, s_timeCumSw, 0, 0); lcd_puts_P( 1*FW, FH*2, PSTR("STK")); putsTime( 5*FW, FH*2, s_timeCumThr, 0, 0); lcd_puts_P( 17*FW, FH*2, PSTR("ST%")); putsTime( 11*FW, FH*2, s_timeCum16ThrP/16, 0, 0); lcd_puts_P( 17*FW, FH*0, PSTR("TOT")); putsTime( 11*FW, FH*0, s_timeCumTot, 0, 0); uint16_t traceRd = s_traceCnt>MAXTRACE ? s_traceWr : 0; uint8_t x=5; uint8_t y=60; lcd_hline(x-3,y,120+3+3); lcd_vline(x,y-32,32+3); for(uint8_t i=0; i<120; i+=6) { lcd_vline(x+i+6,y-1,3); } for(uint8_t i=1; i<=120; i++) { lcd_vline(x+i,y-s_traceBuf[traceRd],s_traceBuf[traceRd]); traceRd++; if(traceRd>=MAXTRACE) traceRd=0; if(traceRd==s_traceWr) break; } }
void displayRssiLine() { if (TELEMETRY_STREAMING()) { lcd_hline(0, 55, 128, 0); // separator uint8_t rssi = min((uint8_t)99, frskyData.rssi[1].value); lcd_putsLeft(STATUS_BAR_Y, STR_TX); lcd_outdezNAtt(4*FW+1, STATUS_BAR_Y, rssi, LEADING0, 2); lcd_rect(25, 57, 38, 7); lcd_filled_rect(26, 58, 4*rssi/11, 5, (rssi < getRssiAlarmValue(0)) ? DOTTED : SOLID); rssi = min((uint8_t)99, frskyData.rssi[0].value); lcd_puts(104, STATUS_BAR_Y, STR_RX); lcd_outdezNAtt(105+4*FW, STATUS_BAR_Y, rssi, LEADING0, 2); lcd_rect(65, 57, 38, 7); uint8_t v = 4*rssi/11; lcd_filled_rect(66+36-v, 58, v, 5, (rssi < getRssiAlarmValue(0)) ? DOTTED : SOLID); } else { lcd_putsAtt(7*FW, STATUS_BAR_Y, STR_NODATA, BLINK); lcd_status_line(); } }
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(); }
void lcd_hbar( uint8_t x, uint8_t y, uint8_t w, uint8_t h, uint8_t percent ) { uint8_t solid ; if ( percent > 100 ) { percent = 100 ; } solid = (w-2) * percent / 100 ; lcd_rect( x, y, w, h ) ; if ( solid ) { w = y + h - 1 ; y += 1 ; x += 1 ; while ( y < w ) { lcd_hline(x, y, solid ) ; y += 1 ; } } }
/* Fill a rectangle with a gradient */ static void lcd_gradient_rect(int x1, int x2, int y, unsigned h, int num_lines, int cur_line) { int old_pattern = current_vp->fg_pattern; int step_mul; if (h == 0) return; num_lines *= h; cur_line *= h; step_mul = (1 << 16) / (num_lines); int h_r = RGB_UNPACK_RED(current_vp->lss_pattern); int h_g = RGB_UNPACK_GREEN(current_vp->lss_pattern); int h_b = RGB_UNPACK_BLUE(current_vp->lss_pattern); int rstep = (h_r - RGB_UNPACK_RED(current_vp->lse_pattern)) * step_mul; int gstep = (h_g - RGB_UNPACK_GREEN(current_vp->lse_pattern)) * step_mul; int bstep = (h_b - RGB_UNPACK_BLUE(current_vp->lse_pattern)) * step_mul; h_r = (h_r << 16) + (1 << 15); h_g = (h_g << 16) + (1 << 15); h_b = (h_b << 16) + (1 << 15); if (cur_line) { h_r -= cur_line * rstep; h_g -= cur_line * gstep; h_b -= cur_line * bstep; } unsigned count; for(count = 0; count < h; count++) { current_vp->fg_pattern = LCD_RGBPACK(h_r >> 16, h_g >> 16, h_b >> 16); lcd_hline(x1, x2, y + count); h_r -= rstep; h_g -= gstep; h_b -= bstep; } current_vp->fg_pattern = old_pattern; }
void menuMainView(uint8_t event) { STICK_SCROLL_DISABLE(); uint8_t view = g_eeGeneral.view; uint8_t view_base = view & 0x0f; switch(event) { case EVT_ENTRY: killEvents(KEY_EXIT); killEvents(KEY_UP); killEvents(KEY_DOWN); break; /* TODO if timer2 is OFF, it's possible to use this timer2 as in er9x... case EVT_KEY_BREAK(KEY_MENU): if (view_base == VIEW_TIMER2) { Timer2_running = !Timer2_running; AUDIO_KEYPAD_UP(); } break; */ case EVT_KEY_BREAK(KEY_RIGHT): case EVT_KEY_BREAK(KEY_LEFT): if (view_base <= VIEW_INPUTS) { #if defined(PCBSKY9X) if (view_base == VIEW_INPUTS) g_eeGeneral.view ^= ALTERNATE_VIEW; else g_eeGeneral.view = (g_eeGeneral.view + (4*ALTERNATE_VIEW) + ((event==EVT_KEY_BREAK(KEY_LEFT)) ? -ALTERNATE_VIEW : ALTERNATE_VIEW)) % (4*ALTERNATE_VIEW); #else g_eeGeneral.view ^= ALTERNATE_VIEW; #endif eeDirty(EE_GENERAL); AUDIO_KEYPAD_UP(); } break; #if defined(NAVIGATION_MENUS) case EVT_KEY_CONTEXT_MENU: killEvents(event); #if defined(CPUARM) if (modelHasNotes()) { MENU_ADD_ITEM(STR_VIEW_NOTES); } #endif #if defined(CPUARM) MENU_ADD_ITEM(STR_RESET_SUBMENU); #else MENU_ADD_ITEM(STR_RESET_TIMER1); MENU_ADD_ITEM(STR_RESET_TIMER2); #if defined(FRSKY) MENU_ADD_ITEM(STR_RESET_TELEMETRY); #endif MENU_ADD_ITEM(STR_RESET_FLIGHT); #endif MENU_ADD_ITEM(STR_STATISTICS); #if defined(CPUARM) MENU_ADD_ITEM(STR_ABOUT_US); #endif menuHandler = onMainViewMenu; break; #endif #if MENUS_LOCK != 2 /*no menus*/ case EVT_KEY_LONG(KEY_MENU):// go to last menu pushMenu(lastPopMenu()); killEvents(event); break; CASE_EVT_ROTARY_BREAK case EVT_KEY_MODEL_MENU: pushMenu(menuModelSelect); killEvents(event); break; CASE_EVT_ROTARY_LONG case EVT_KEY_GENERAL_MENU: pushMenu(menuGeneralSetup); killEvents(event); break; #endif case EVT_KEY_BREAK(KEY_UP): case EVT_KEY_BREAK(KEY_DOWN): g_eeGeneral.view = (event == EVT_KEY_BREAK(KEY_UP) ? (view_base == VIEW_COUNT-1 ? 0 : view_base+1) : (view_base == 0 ? VIEW_COUNT-1 : view_base-1)); eeDirty(EE_GENERAL); AUDIO_KEYPAD_UP(); break; case EVT_KEY_STATISTICS: chainMenu(menuStatisticsView); killEvents(event); break; case EVT_KEY_TELEMETRY: #if defined(FRSKY) if (!IS_FAI_ENABLED()) chainMenu(menuTelemetryFrsky); #elif defined(JETI) JETI_EnableRXD(); // enable JETI-Telemetry reception chainMenu(menuTelemetryJeti); #elif defined(ARDUPILOT) ARDUPILOT_EnableRXD(); // enable ArduPilot-Telemetry reception chainMenu(menuTelemetryArduPilot); #elif defined(NMEA) NMEA_EnableRXD(); // enable NMEA-Telemetry reception chainMenu(menuTelemetryNMEA); #elif defined(MAVLINK) chainMenu(menuTelemetryMavlink); #else chainMenu(menuStatisticsDebug); #endif killEvents(event); break; case EVT_KEY_FIRST(KEY_EXIT): #if defined(GVARS) && !defined(PCBSTD) if (s_gvar_timer > 0) { s_gvar_timer = 0; } #endif if (view == VIEW_TIMER2) { timerReset(1); } AUDIO_KEYPAD_UP(); break; #if !defined(NAVIGATION_MENUS) case EVT_KEY_LONG(KEY_EXIT): flightReset(); AUDIO_KEYPAD_UP(); break; #endif } { // Flight Mode Name uint8_t mode = mixerCurrentFlightMode; lcd_putsnAtt(PHASE_X, PHASE_Y, g_model.flightModeData[mode].name, sizeof(g_model.flightModeData[mode].name), ZCHAR|PHASE_FLAGS); // Model Name putsModelName(MODELNAME_X, MODELNAME_Y, g_model.header.name, g_eeGeneral.currModel, BIGSIZE); // Main Voltage (or alarm if any) displayVoltageOrAlarm(); // Timers displayTimers(); // Trims sliders displayTrims(mode); } if (view_base < VIEW_INPUTS) { // scroll bar lcd_hlineStip(38, 34, 54, DOTTED); #if defined(PCBSKY9X) lcd_hline(38 + (g_eeGeneral.view / ALTERNATE_VIEW) * 13, 34, 13, SOLID); #else lcd_hline((g_eeGeneral.view & ALTERNATE_VIEW) ? 64 : 38, 34, 26, SOLID); #endif for (uint8_t i=0; i<8; i++) { uint8_t x0,y0; #if defined(PCBSKY9X) uint8_t chan = 8*(g_eeGeneral.view / ALTERNATE_VIEW) + i; #else uint8_t chan = (g_eeGeneral.view & ALTERNATE_VIEW) ? 8+i : i; #endif int16_t val = channelOutputs[chan]; switch(view_base) { case VIEW_OUTPUTS_VALUES: x0 = (i%4*9+3)*FW/2; y0 = i/4*FH+40; #if defined(PPM_UNIT_US) lcd_outdezAtt(x0+4*FW , y0, PPM_CH_CENTER(chan)+val/2, 0); #elif defined(PPM_UNIT_PERCENT_PREC1) lcd_outdezAtt(x0+4*FW , y0, calcRESXto1000(val), PREC1); #else lcd_outdezAtt(x0+4*FW , y0, calcRESXto1000(val)/10, 0); // G: Don't like the decimal part* #endif break; case VIEW_OUTPUTS_BARS: #define WBAR2 (50/2) x0 = i<4 ? LCD_W/4+2 : LCD_W*3/4-2; y0 = 38+(i%4)*5; uint16_t lim = g_model.extendedLimits ? 640*2 : 512*2; int8_t len = (abs(val) * WBAR2 + lim/2) / lim; if(len>WBAR2) len = WBAR2; // prevent bars from going over the end - comment for debugging lcd_hlineStip(x0-WBAR2, y0, WBAR2*2+1, DOTTED); lcd_vline(x0,y0-2,5); if (val>0) x0+=1; else x0-=len; lcd_hline(x0,y0+1,len); lcd_hline(x0,y0-1,len); break; } } } else if (view_base == VIEW_INPUTS) { if (view == VIEW_INPUTS) { // Sticks + Pots doMainScreenGraphics(); // Switches for (uint8_t i=SWSRC_THR; i<=SWSRC_TRN; i++) { int8_t sw = (i == SWSRC_TRN ? (switchState(SW_ID0) ? SWSRC_ID0 : (switchState(SW_ID1) ? SWSRC_ID1 : SWSRC_ID2)) : i); uint8_t x = 2*FW-2, y = i*FH+1; if (i>=SWSRC_AIL) { x = 17*FW-1; y -= 3*FH; } putsSwitches(x, y, sw, getSwitch(i) ? INVERS : 0); } } else { #if defined(PCBMEGA2560) && defined(ROTARY_ENCODERS) for (uint8_t i=0; i<NUM_ROTARY_ENCODERS; i++) { int16_t val = getRotaryEncoder(i); int8_t len = limit((int16_t)0, (int16_t)(((val+1024) * BAR_HEIGHT) / 2048), (int16_t)BAR_HEIGHT); #if ROTARY_ENCODERS > 2 #define V_BAR_W 5 V_BAR(LCD_W/2-8+V_BAR_W*i, LCD_H-8, len); #else #define V_BAR_W 5 V_BAR(LCD_W/2-3+V_BAR_W*i, LCD_H-8, len); #endif } #endif // PCBGRUVIN9X && ROTARY_ENCODERS // Logical Switches #if defined(PCBSKY9X) for (uint8_t i=0; i<NUM_LOGICAL_SWITCH; i++) { int8_t len = getSwitch(SWSRC_SW1+i) ? BAR_HEIGHT : 1; uint8_t x = VSWITCH_X(i); lcd_vline(x-1, VSWITCH_Y-len, len); lcd_vline(x, VSWITCH_Y-len, len); } #elif defined(CPUM2560) for (uint8_t i=0; i<NUM_LOGICAL_SWITCH; i++) putsSwitches(2*FW-3 + (i/3)*(i/3>2 ? 3*FW+2 : (3*FW-1)) + (i/3>2 ? 2*FW : 0), 4*FH+1 + (i%3)*FH, SWSRC_SW1+i, getSwitch(SWSRC_SW1+i) ? INVERS : 0); #elif !defined(PCBSTD) for (uint8_t i=0; i<NUM_LOGICAL_SWITCH; i++) putsSwitches(2*FW-2 + (i/3)*(4*FW-1), 4*FH+1 + (i%3)*FH, SWSRC_SW1+i, getSwitch(SWSRC_SW1+i) ? INVERS : 0); #else for (uint8_t i=0; i<NUM_LOGICAL_SWITCH; i++) putsSwitches(2*FW-3 + (i/3)*(4*FW), 4*FH+1 + (i%3)*FH, SWSRC_SW1+i, getSwitch(SWSRC_SW1+i) ? INVERS : 0); #endif } } else { // timer2 #if defined(TRANSLATIONS_CZ) #define TMR2_LBL_COL (20-FW/2+1) #else #define TMR2_LBL_COL (20-FW/2+5) #endif putsTimer(33+FW+2+10*FWNUM-4, FH*5, timersStates[1].val, DBLSIZE, DBLSIZE); putsTimerMode(timersStates[1].val >= 0 ? TMR2_LBL_COL : TMR2_LBL_COL-7, FH*6, g_model.timers[1].mode); // lcd_outdezNAtt(33+11*FW, FH*6, s_timerVal_10ms[1], LEADING0, 2); // 1/100s } // And ! in case of unexpected shutdown if (unexpectedShutdown) { lcd_putcAtt(REBOOT_X, 0*FH, '!', INVERS); } #if defined(GVARS) && !defined(PCBSTD) if (s_gvar_timer > 0) { s_gvar_timer--; s_warning = STR_GLOBAL_VAR; displayBox(); lcd_putsnAtt(16, 5*FH, g_model.gvars[s_gvar_last].name, LEN_GVAR_NAME, ZCHAR); lcd_putsAtt(16+7*FW, 5*FH, PSTR("[\010]"), BOLD); lcd_outdezAtt(16+7*FW+4*FW+FW/2, 5*FH, GVAR_VALUE(s_gvar_last, getGVarFlightPhase(mixerCurrentFlightMode, s_gvar_last)), BOLD); s_warning = NULL; } #endif #if defined(DSM2) if (moduleFlag[0] == MODULE_BIND) { // Issue 98 lcd_putsAtt(15*FW, 0, PSTR("BIND"), 0); } #endif }
uint8_t lcd_outdezNAtt( uint8_t x, uint8_t y, int32_t val, uint8_t mode, int8_t len ) { uint8_t fw = FWNUM; uint8_t prec = PREC(mode); uint8_t negative = 0 ; uint8_t xn = 0; uint8_t ln = 2; char c; uint8_t xinc ; uint8_t fullwidth = 0 ; mode &= ~NO_UNIT ; if ( len < 0 ) { fullwidth = 1 ; len = -len ; } if ( val < 0 ) { val = -val ; negative = 1 ; } if (mode & DBLSIZE) { fw += FWNUM ; xinc = 2*FWNUM; lcd_lastPos = 2*FW; } else { xinc = FWNUM ; lcd_lastPos = FW; } if (mode & LEFT) { // if (val >= 10000) // x += fw; if(negative) { x += fw; } if (val >= 1000) x += fw; if (val >= 100) x += fw; if (val >= 10) x += fw; if ( prec ) { if ( prec == 2 ) { if ( val < 100 ) { x += fw; } } if ( val < 10 ) { x+= fw; } } } else { x -= xinc; } lcd_lastPos += x ; if ( prec == 2 ) { mode -= LEADING0; // Can't have PREC2 and LEADING0 } for (uint8_t i=1; i<=len; i++) { div_t qr ; qr = div( val, 10 ) ; c = (qr.rem) + '0'; lcd_putcAtt(x, y, c, mode); if (prec==i) { if (mode & DBLSIZE) { xn = x; if( c<='3' && c>='1') ln++; uint8_t tn = (qr.quot) % 10; if(tn==2 || tn==4) { if (c=='4') { xn++; } else { xn--; ln++; } } } else { x -= 2; if (mode & INVERS) lcd_vline(x+1, y, 7); else lcd_plot(x+1, y+6); } if (qr.quot) prec = 0; } val = qr.quot ; if (!val) { if (prec) { if ( prec == 2 ) { if ( i > 1 ) { prec = 0 ; } } else { prec = 0 ; } } else if (mode & LEADING0) { if ( fullwidth == 0 ) { mode -= LEADING0; } } else break; } x-=fw; } if (xn) { lcd_hline(xn, y+2*FH-4, ln); lcd_hline(xn, y+2*FH-3, ln); } if(negative) lcd_putcAtt(x-fw,y,'-',mode); asm("") ; return 0 ; // Stops compiler creating two sets of POPS, saves flash }
int main() { uint8_t index = 0; uint8_t maxhsize = DISPLAY_CHAR_WIDTH; FRESULT fr; uint32_t state = ST_START; uint32_t nameCount = 0; uint32_t vpos = 0; uint32_t hpos = 0; #if defined(PCBTARANIS) wdt_reset(); RCC_AHB1PeriphClockCmd(PWR_RCC_AHB1Periph | KEYS_RCC_AHB1Periph | LCD_RCC_AHB1Periph | BACKLIGHT_RCC_AHB1Periph | I2C_RCC_AHB1Periph | SD_RCC_AHB1Periph, ENABLE); RCC_APB1PeriphClockCmd(LCD_RCC_APB1Periph | BACKLIGHT_RCC_APB1Periph | INTERRUPT_5MS_APB1Periph | I2C_RCC_APB1Periph | SD_RCC_APB1Periph, ENABLE); RCC_APB2PeriphClockCmd(BACKLIGHT_RCC_APB2Periph, ENABLE); #endif pwrInit(); delaysInit(); //needed for lcdInit() lcdInit(); backlightInit(); lcd_clear(); lcd_putsn(0, 0, (const char *)bootloaderVersion, 0); // trick to avoid bootloaderVersion to be optimized out ... lcd_putsLeft(0, BOOTLOADER_TITLE); lcd_invert_line(0); lcdRefresh(); keysInit(); i2cInit(); __enable_irq(); init10msTimer(); #if defined(PCBTARANIS) // SD card detect pin sdInit(); usbInit(); #endif for (;;) { wdt_reset(); if (Tenms) { Tenms = 0; lcdRefreshWait(); lcd_clear(); lcd_putsLeft(0, BOOTLOADER_TITLE); lcd_invert_line(0); uint8_t event = getEvent(); if (state != ST_USB) { if (usbPlugged()) { state = ST_USB; if (!unlocked) { unlocked = 1; unlockFlash(); } usbPluggedIn(); } } if (state == ST_START) { lcd_putsLeft(2*FH, "\010Write Firmware"); lcd_putsLeft(3*FH, "\010Restore EEPROM"); lcd_putsLeft(4*FH, "\010Exit"); lcd_invert_line(2+vpos); lcd_putsLeft(7*FH, INDENT "Or plug in a USB cable for mass storage"); if (event == EVT_KEY_FIRST(BOOT_KEY_DOWN)) { vpos == 2 ? vpos = 0 : vpos = vpos+1; } else if (event == EVT_KEY_FIRST(BOOT_KEY_UP)) { vpos == 0 ? vpos = 2 : vpos = vpos-1; } else if (event == EVT_KEY_BREAK(BOOT_KEY_MENU)) { switch (vpos) { case 0: state = ST_FLASH_MENU; break; case 1: state = ST_RESTORE_MENU; break; default: state = ST_REBOOT; } } } if (state == ST_USB) { lcd_putsLeft(4*FH, "\026USB Connected"); if (usbPlugged() == 0) { vpos = 0; if (unlocked) { lockFlash(); unlocked = 0; } state = ST_START; } #if defined(PCBSKY9X) usbMassStorage(); #endif } if (state == ST_FLASH_MENU || state == ST_RESTORE_MENU) { sdInit(); memoryType = (state == ST_RESTORE_MENU ? MEM_EEPROM : MEM_FLASH); state = ST_DIR_CHECK; } else if (state == ST_DIR_CHECK) { fr = f_chdir(getBinaryPath()); if (fr == FR_OK) { state = ST_OPEN_DIR; } else { lcd_putsLeft(2*FH, INDENT "Directory is missing!"); if (event == EVT_KEY_BREAK(BOOT_KEY_EXIT) || event == EVT_KEY_BREAK(BOOT_KEY_MENU)) { vpos = 0; state = ST_START; } } } if (state == ST_OPEN_DIR) { index = 0; fr = f_opendir(&Dj, "."); if (fr == FR_OK) { state = ST_FILE_LIST; nameCount = fillNames(0); hpos = 0; vpos = 0; } } if (state == ST_FILE_LIST) { uint32_t limit = 6; if (nameCount < limit) { limit = nameCount; } maxhsize = 0; for (uint32_t i=0; i<limit; i++) { uint32_t x; x = strlen(Filenames[i]); if (x > maxhsize) { maxhsize = x; } if (x > DISPLAY_CHAR_WIDTH) { if (hpos + DISPLAY_CHAR_WIDTH > x) { x = x - DISPLAY_CHAR_WIDTH; } else { x = hpos; } } else { x = 0; } lcd_putsnAtt(INDENT_WIDTH, 16 + FH * i, &Filenames[i][x], DISPLAY_CHAR_WIDTH, 0); } if (event == EVT_KEY_REPT(BOOT_KEY_DOWN) || event == EVT_KEY_FIRST(BOOT_KEY_DOWN)) { if (vpos < limit - 1) { vpos += 1; } else { if (nameCount > limit) { index += 1; nameCount = fillNames(index); } } } else if (event == EVT_KEY_REPT(BOOT_KEY_UP) || event == EVT_KEY_FIRST(BOOT_KEY_UP)) { if (vpos > 0) { vpos -= 1; } else { if (index) { index -= 1; nameCount = fillNames(index); } } } #if !defined(PCBTARANIS) else if (event == EVT_KEY_REPT(BOOT_KEY_RIGHT) || event == EVT_KEY_FIRST(BOOT_KEY_RIGHT)) { if (hpos + DISPLAY_CHAR_WIDTH < maxhsize) { hpos += 1; } } else if (event == EVT_KEY_REPT(BOOT_KEY_LEFT) || event == EVT_KEY_FIRST(BOOT_KEY_LEFT)) { if (hpos) { hpos -= 1; } } #endif else if (event == EVT_KEY_BREAK(BOOT_KEY_MENU)) { // Select file to flash state = ST_FLASH_CHECK; Valid = 0; } else if (event == EVT_KEY_FIRST(BOOT_KEY_EXIT)) { state = ST_START; vpos = 0; } lcd_invert_line(2 + vpos); } else if (state == ST_FLASH_CHECK) { int result = menuFlashFile(vpos, event); FirmwareSize = FileSize[vpos] - BOOTLOADER_SIZE; if (result == 0) { // canceled state = ST_FILE_LIST; } else if (result == 1) { // confirmed firmwareAddress = FIRMWARE_ADDRESS + BOOTLOADER_SIZE; firmwareWritten = 0; eepromAddress = 0; eepromWritten = 0; state = ST_FLASHING; } } else if (state == ST_FLASHING) { // commit to flashing lcd_putsLeft(4*FH, "\032Writing..."); if (!unlocked && (memoryType == MEM_FLASH)) { unlocked = 1; unlockFlash(); } int progress; if (memoryType == MEM_FLASH) { writeFlashBlock(); firmwareWritten += sizeof(Block_buffer); progress = (200*firmwareWritten) / FirmwareSize; } else { writeEepromBlock(); eepromWritten += sizeof(Block_buffer); progress = (200*eepromWritten) / EESIZE; } lcd_rect( 3, 6*FH+4, 204, 7); lcd_hline(5, 6*FH+6, progress, FORCE); lcd_hline(5, 6*FH+7, progress, FORCE); lcd_hline(5, 6*FH+8, progress, FORCE); fr = f_read(&FlashFile, (BYTE *)Block_buffer, sizeof(Block_buffer), &BlockCount); if (BlockCount == 0) { state = ST_FLASH_DONE; // EOF } if (firmwareWritten >= FLASHSIZE - BOOTLOADER_SIZE) { state = ST_FLASH_DONE; // Backstop } if (eepromWritten >= EESIZE) { state = ST_FLASH_DONE; // Backstop } } if (state == ST_FLASH_DONE) { if (unlocked) { lockFlash(); unlocked = 0; } lcd_putsLeft(4*FH, "\024Writing Complete"); if (event == EVT_KEY_FIRST(BOOT_KEY_EXIT) || event == EVT_KEY_BREAK(BOOT_KEY_MENU)) { state = ST_START; vpos = 0; } } if (event == EVT_KEY_LONG(BOOT_KEY_EXIT)) { state = ST_REBOOT; } lcdRefresh(); if (PowerUpDelay < 20) { // 200 mS PowerUpDelay += 1; } else { sdPoll10ms(); } } if (state != ST_FLASHING && state != ST_USB) { #if defined(REV9E) if (pwrPressed()) { #else if (pwrCheck() == e_power_off) { #endif lcdOff(); // this drains LCD caps pwrOff(); for (;;) { // Wait for power to go off } } } if (state == ST_REBOOT) { if (readKeys() == 0) { lcd_clear(); lcdRefresh(); lcdRefreshWait(); RCC->CSR |= RCC_CSR_RMVF; //clear the reset flags in RCC clock control & status register NVIC_SystemReset(); } } } return 0; }
int main() { uint8_t index = 0; uint8_t maxhsize = DISPLAY_CHAR_WIDTH; FRESULT fr; uint32_t state = ST_START; uint32_t nameCount = 0; uint32_t vpos = 0; uint32_t hpos = 0; #if defined(PCBTARANIS) wdt_reset(); RCC->AHB1ENR |= RCC_AHB1ENR_GPIOAEN; // Enable portA clock #endif pwrInit(); #if defined(PCBSKY9X) MATRIX->CCFG_SYSIO |= 0x000000F0L; // Disable syspins, enable B4,5,6,7 #endif #if defined(PCBSKY9X) init_SDcard(); PIOC->PIO_PER = PIO_PC25; // Enable bit C25 (USB-detect) start_timer0(); #endif lcdInit(); #if defined(PCBSKY9X) extern uint8_t OptrexDisplay; OptrexDisplay = 1; #endif lcd_clear(); lcd_putsLeft(0, BOOTLOADER_TITLE); lcd_invert_line(0); lcdRefresh(); #if defined(PCBSKY9X) OptrexDisplay = 0; lcdRefresh(); #endif #if defined(PCBTARANIS) keysInit(); I2C_EE_Init(); init_hw_timer(); #endif __enable_irq(); init10msTimer(); #if defined(PCBSKY9X) EblockAddress = -1; init_spi(); #endif #if defined(PCBSKY9X) LockBits = readLockBits(); if (LockBits) { clearLockBits(); } #endif #if defined(PCBTARANIS) // SD card detect pin sdInit(); usbInit(); usbStart(); #endif for (;;) { wdt_reset(); if (Tenms) { if (EE_timer) { if (--EE_timer == 0) { #if defined(PCBSKY9X) writeBlock(); #endif } } Tenms = 0; lcd_clear(); lcd_putsLeft(0, BOOTLOADER_TITLE); lcd_invert_line(0); uint8_t event = getEvent(); if (state != ST_USB) { if (usbPlugged()) { state = ST_USB; if (!unlocked) { unlocked = 1; unlockFlash(); } usbPluggedIn(); } } if (state == ST_START) { lcd_putsLeft(2*FH, "\010Write Firmware"); lcd_putsLeft(3*FH, "\010Restore EEPROM"); lcd_putsLeft(4*FH, "\010Exit"); lcd_invert_line(2+vpos); lcd_putsLeft(7*FH, INDENT "Or plug in a USB cable for mass storage"); if (event == EVT_KEY_FIRST(BOOT_KEY_DOWN)) { vpos == 2 ? vpos = 0 : vpos = vpos+1; } else if (event == EVT_KEY_FIRST(BOOT_KEY_UP)) { vpos == 0 ? vpos = 2 : vpos = vpos-1; } else if (event == EVT_KEY_BREAK(BOOT_KEY_MENU)) { switch (vpos) { case 0: state = ST_FLASH_MENU; break; case 1: state = ST_RESTORE_MENU; break; default: state = ST_REBOOT; } } } if (state == ST_USB) { lcd_putsLeft(4*FH, "\026USB Connected"); if (usbPlugged() == 0) { vpos = 0; if (unlocked) { lockFlash(); unlocked = 0; } state = ST_START; } #if defined(PCBSKY9X) usbMassStorage(); #endif } if (state == ST_FLASH_MENU || state == ST_RESTORE_MENU) { sdInit(); memoryType = (state == ST_RESTORE_MENU ? MEM_EEPROM : MEM_FLASH); state = ST_DIR_CHECK; } else if (state == ST_DIR_CHECK) { fr = f_chdir(getBinaryPath()); if (fr == FR_OK) { state = ST_OPEN_DIR; } else { lcd_putsLeft(2*FH, INDENT "Directory is missing!"); if (event == EVT_KEY_BREAK(BOOT_KEY_EXIT) || event == EVT_KEY_BREAK(BOOT_KEY_MENU)) { vpos = 0; state = ST_START; } } } if (state == ST_OPEN_DIR) { index = 0; fr = f_opendir(&Dj, "."); if (fr == FR_OK) { state = ST_FILE_LIST; nameCount = fillNames(0); hpos = 0; vpos = 0; } } if (state == ST_FILE_LIST) { uint32_t limit = 6; if (nameCount < limit) { limit = nameCount; } maxhsize = 0; for (uint32_t i=0; i<limit; i++) { uint32_t x; x = strlen(Filenames[i]); if (x > maxhsize) { maxhsize = x; } if (x > DISPLAY_CHAR_WIDTH) { if (hpos + DISPLAY_CHAR_WIDTH > x) { x = x - DISPLAY_CHAR_WIDTH; } else { x = hpos; } } else { x = 0; } lcd_putsnAtt(INDENT_WIDTH, 16 + FH * i, &Filenames[i][x], DISPLAY_CHAR_WIDTH, 0); } if (event == EVT_KEY_REPT(BOOT_KEY_DOWN) || event == EVT_KEY_FIRST(BOOT_KEY_DOWN)) { if (vpos < limit - 1) { vpos += 1; } else { if (nameCount > limit) { index += 1; nameCount = fillNames(index); } } } else if (event == EVT_KEY_REPT(BOOT_KEY_UP) || event == EVT_KEY_FIRST(BOOT_KEY_UP)) { if (vpos > 0) { vpos -= 1; } else { if (index) { index -= 1; nameCount = fillNames(index); } } } #if !defined(PCBTARANIS) else if (event == EVT_KEY_REPT(BOOT_KEY_RIGHT) || event == EVT_KEY_FIRST(BOOT_KEY_RIGHT)) { if (hpos + DISPLAY_CHAR_WIDTH < maxhsize) { hpos += 1; } } else if (event == EVT_KEY_REPT(BOOT_KEY_LEFT) || event == EVT_KEY_FIRST(BOOT_KEY_LEFT)) { if (hpos) { hpos -= 1; } } #endif else if (event == EVT_KEY_BREAK(BOOT_KEY_MENU)) { // Select file to flash state = ST_FLASH_CHECK; Valid = 0; } else if (event == EVT_KEY_FIRST(BOOT_KEY_EXIT)) { state = ST_START; vpos = 0; } lcd_invert_line(2 + vpos); } else if (state == ST_FLASH_CHECK) { int result = menuFlashFile(vpos, event); FirmwareSize = FileSize[vpos] - BOOTLOADER_SIZE; if (result == 0) { // canceled state = ST_FILE_LIST; } else if (result == 1) { // confirmed firmwareAddress = FIRMWARE_ADDRESS + BOOTLOADER_SIZE; firmwareWritten = 0; eepromAddress = 0; eepromWritten = 0; state = ST_FLASHING; } } else if (state == ST_FLASHING) { // commit to flashing lcd_putsLeft(4*FH, "\032Writing..."); if (!unlocked && (memoryType == MEM_FLASH)) { unlocked = 1; unlockFlash(); } int progress; if (memoryType == MEM_FLASH) { writeFlashBlock(); firmwareWritten += sizeof(Block_buffer); progress = (200*firmwareWritten) / FirmwareSize; } else { writeEepromBlock(); eepromWritten += sizeof(Block_buffer); progress = (200*eepromWritten) / EESIZE; } lcd_rect( 3, 6*FH+4, 204, 7); lcd_hline(5, 6*FH+6, progress, FORCE); lcd_hline(5, 6*FH+7, progress, FORCE); lcd_hline(5, 6*FH+8, progress, FORCE); fr = f_read(&FlashFile, (BYTE *)Block_buffer, sizeof(Block_buffer), &BlockCount); if (BlockCount == 0) { state = ST_FLASH_DONE; // EOF } if (firmwareWritten >= FLASHSIZE - BOOTLOADER_SIZE) { state = ST_FLASH_DONE; // Backstop } if (eepromWritten >= EESIZE) { state = ST_FLASH_DONE; // Backstop } } if (state == ST_FLASH_DONE) { if (unlocked) { lockFlash(); unlocked = 0; } lcd_putsLeft(4*FH, "\024Writing Complete"); if (event == EVT_KEY_FIRST(BOOT_KEY_EXIT) || event == EVT_KEY_BREAK(BOOT_KEY_MENU)) { state = ST_START; vpos = 0; } } if (event == EVT_KEY_LONG(BOOT_KEY_EXIT)) { state = ST_REBOOT; } lcdRefresh(); if (PowerUpDelay < 20) { // 200 mS PowerUpDelay += 1; } else { sdPoll10ms(); } } if (pwrCheck() == e_power_off && state != ST_FLASHING && state != ST_USB) { pwrOff(); for (;;) { // Wait for power to go off } } if (state == ST_REBOOT) { if ((~readKeys() & 0x7E) == 0) { NVIC_SystemReset(); } } } return 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 }
void displaySlider(uint8_t x, uint8_t y, uint8_t value, uint8_t max, uint8_t attr) { lcd_putc(RADIO_SETUP_2ND_COLUMN+(value*4*FW)/max, y, '$'); lcd_hline(RADIO_SETUP_2ND_COLUMN, y+3, 5*FW-1, SOLID); if (attr && (!(attr & BLINK) || !BLINK_ON_PHASE)) lcd_filled_rect(RADIO_SETUP_2ND_COLUMN, y, 5*FW-1, FH-1); }
void menuModelFailsafe(uint8_t event) { static bool longNames = false; bool newLongNames = false; uint8_t ch = 0; uint8_t channelStart = g_model.moduleData[g_moduleIdx].channelsStart; if (event == EVT_KEY_LONG(KEY_ENTER)) { killEvents(event); event = 0; if (s_editMode) { g_model.moduleData[g_moduleIdx].failsafeChannels[menuVerticalPosition] = channelOutputs[menuVerticalPosition+channelStart]; eeDirty(EE_MODEL); AUDIO_WARNING1(); s_editMode = 0; SEND_FAILSAFE_NOW(g_moduleIdx); } else { int16_t & failsafe = g_model.moduleData[g_moduleIdx].failsafeChannels[menuVerticalPosition]; if (failsafe < FAILSAFE_CHANNEL_HOLD) failsafe = FAILSAFE_CHANNEL_HOLD; else if (failsafe == FAILSAFE_CHANNEL_HOLD) failsafe = FAILSAFE_CHANNEL_NOPULSE; else failsafe = 0; eeDirty(EE_MODEL); AUDIO_WARNING1(); SEND_FAILSAFE_NOW(g_moduleIdx); } } SIMPLE_SUBMENU_NOTITLE(NUM_CHANNELS(g_moduleIdx)); SET_SCROLLBAR_X(0); #define COL_W (LCD_W/2) const uint8_t SLIDER_W = 64; // Column separator lcd_vline(LCD_W/2, FH, LCD_H-FH); lcd_putsCenter(0*FH, FAILSAFESET); lcd_invert_line(0); unsigned int lim = g_model.extendedLimits ? 640*2 : 512*2; for (uint8_t col=0; col<2; col++) { coord_t x = col*COL_W+1; // Channels for (uint8_t line=0; line<8; line++) { coord_t y = 9+line*7; int32_t channelValue = channelOutputs[ch+channelStart]; int32_t failsafeValue = 0; bool failsafeEditable = false; uint8_t ofs = (col ? 0 : 1); if (ch < NUM_CHANNELS(g_moduleIdx)) { failsafeValue = g_model.moduleData[g_moduleIdx].failsafeChannels[8*col+line]; failsafeEditable = true; } if (failsafeEditable) { // Channel name if present, number if not uint8_t lenLabel = ZLEN(g_model.limitData[ch+channelStart].name); if (lenLabel > 4) { newLongNames = longNames = true; } if (lenLabel > 0) lcd_putsnAtt(x+1-ofs, y, g_model.limitData[ch+channelStart].name, sizeof(g_model.limitData[ch+channelStart].name), ZCHAR | SMLSIZE); else putsChn(x+1-ofs, y, ch+1, SMLSIZE); // Value LcdFlags flags = TINSIZE; if (menuVerticalPosition == ch) { flags |= INVERS; if (s_editMode) { if (failsafeValue == FAILSAFE_CHANNEL_HOLD || failsafeValue == FAILSAFE_CHANNEL_NOPULSE) { s_editMode = 0; } else { flags |= BLINK; CHECK_INCDEC_MODELVAR(event, g_model.moduleData[g_moduleIdx].failsafeChannels[8*col+line], -lim, +lim); } } } #if defined(PPM_UNIT_PERCENT_PREC1) uint8_t wbar = (longNames ? SLIDER_W-16 : SLIDER_W-6); #else uint8_t wbar = (longNames ? SLIDER_W-10 : SLIDER_W); #endif if (failsafeValue == FAILSAFE_CHANNEL_HOLD) { lcd_putsAtt(x+COL_W-4-wbar-ofs-16, y, "HOLD", flags); failsafeValue = 0; } else if (failsafeValue == FAILSAFE_CHANNEL_NOPULSE) { lcd_putsAtt(x+COL_W-4-wbar-ofs-16, y, "NONE", flags); failsafeValue = 0; } else { #if defined(PPM_UNIT_US) lcd_outdezAtt(x+COL_W-4-wbar-ofs, y, PPM_CH_CENTER(ch)+failsafeValue/2, flags); #elif defined(PPM_UNIT_PERCENT_PREC1) lcd_outdezAtt(x+COL_W-4-wbar-ofs, y, calcRESXto1000(failsafeValue), PREC1|flags); #else lcd_outdezAtt(x+COL_W-4-wbar-ofs, y, calcRESXto1000(failsafeValue)/10, flags); #endif } // Gauge lcd_rect(x+COL_W-3-wbar-ofs, y, wbar+1, 6); unsigned int lenChannel = limit((uint8_t)1, uint8_t((abs(channelValue) * wbar/2 + lim/2) / lim), uint8_t(wbar/2)); unsigned int lenFailsafe = limit((uint8_t)1, uint8_t((abs(failsafeValue) * wbar/2 + lim/2) / lim), uint8_t(wbar/2)); coord_t xChannel = (channelValue>0) ? x+COL_W-ofs-3-wbar/2 : x+COL_W-ofs-2-wbar/2-lenChannel; coord_t xFailsafe = (failsafeValue>0) ? x+COL_W-ofs-3-wbar/2 : x+COL_W-ofs-2-wbar/2-lenFailsafe; lcd_hlineStip(xChannel, y+1, lenChannel, DOTTED, 0); lcd_hlineStip(xChannel, y+2, lenChannel, DOTTED, 0); lcd_hline(xFailsafe, y+3, lenFailsafe); lcd_hline(xFailsafe, y+4, lenFailsafe); } ch++; } } longNames = newLongNames; }
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); }
void displayTrims(uint8_t phase) { for (uint8_t i=0; i<4; i++) { static coord_t x[4] = {TRIM_LH_X, TRIM_LV_X, TRIM_RV_X, TRIM_RH_X}; static uint8_t vert[4] = {0,1,1,0}; coord_t xm, ym; uint8_t stickIndex = CONVERT_MODE(i); xm = x[stickIndex]; uint8_t att = ROUND; int16_t val = getTrimValue(phase, i); #if !defined(CPUM64) || !defined(FRSKY) int16_t dir = val; bool exttrim = false; if (val < TRIM_MIN || val > TRIM_MAX) { exttrim = true; } #endif if (val < -(TRIM_LEN+1)*4) { val = -(TRIM_LEN+1); } else if (val > (TRIM_LEN+1)*4) { val = TRIM_LEN+1; } else { val /= 4; } if (vert[i]) { ym = 31; lcd_vline(xm, ym-TRIM_LEN, TRIM_LEN*2); if (i!=2 || !g_model.thrTrim) { lcd_vline(xm-1, ym-1, 3); lcd_vline(xm+1, ym-1, 3); } ym -= val; #if !defined(CPUM64) || !defined(FRSKY) drawFilledRect(xm-3, ym-3, 7, 7, SOLID, att|ERASE); if (dir >= 0) { lcd_hline(xm-1, ym-1, 3); } if (dir <= 0) { lcd_hline(xm-1, ym+1, 3); } if (exttrim) { lcd_hline(xm-1, ym, 3); } #endif #if defined(CPUARM) if (g_model.displayTrims != DISPLAY_TRIMS_NEVER && dir != 0) { if (g_model.displayTrims == DISPLAY_TRIMS_ALWAYS || (trimsDisplayTimer > 0 && (trimsDisplayMask & (1<<i)))) { lcd_outdezAtt(dir>0 ? 22 : 54, xm-2, -abs(dir/5), TINSIZE|VERTICAL); } } #endif } else { ym = 60; lcd_hline(xm-TRIM_LEN, ym, TRIM_LEN*2); lcd_hline(xm-1, ym-1, 3); lcd_hline(xm-1, ym+1, 3); xm += val; #if !defined(CPUM64) || !defined(FRSKY) drawFilledRect(xm-3, ym-3, 7, 7, SOLID, att|ERASE); if (dir >= 0) { lcd_vline(xm+1, ym-1, 3); } if (dir <= 0) { lcd_vline(xm-1, ym-1, 3); } if (exttrim) { lcd_vline(xm, ym-1, 3); } #endif #if defined(CPUARM) if (g_model.displayTrims != DISPLAY_TRIMS_NEVER && dir != 0) { if (g_model.displayTrims == DISPLAY_TRIMS_ALWAYS || (trimsDisplayTimer > 0 && (trimsDisplayMask & (1<<i)))) { lcd_outdezAtt((stickIndex==0 ? TRIM_LH_X : TRIM_RH_X)+(dir>0 ? -11 : 20), ym-2, -abs(dir/5), TINSIZE); } } #endif } lcd_square(xm-3, ym-3, 7, att); } }
void displaySlider(coord_t x, coord_t y, uint8_t value, uint8_t max, uint8_t attr) { lcd_putc(x+(value*4*FW)/max, y, '$'); lcd_hline(x, y+3, 5*FW-1, FORCE); if (attr && (!(attr & BLINK) || !BLINK_ON_PHASE)) drawFilledRect(x, y, 5*FW-1, FH-1); }
void display5posSlider(uint8_t x, uint8_t y, uint8_t value, uint8_t attr) { lcd_putc(x+2*FW+(value*FW), y, '$'); lcd_hline(x, y+3, 5*FW-1, SOLID); if (attr && (!(attr & BLINK) || !BLINK_ON_PHASE)) lcd_filled_rect(x, y, 5*FW-1, FH-1); }
/* Draw a line */ void lcd_drawline(int x1, int y1, int x2, int y2) { int numpixels; int i; int deltax, deltay; int d, dinc1, dinc2; int x, xinc1, xinc2; int y, yinc1, yinc2; lcd_fastpixelfunc_type *pfunc = lcd_fastpixelfuncs[current_vp->drawmode]; deltay = abs(y2 - y1); if (deltay == 0) { /* DEBUGF("lcd_drawline() called for horizontal line - optimisation.\n"); */ lcd_hline(x1, x2, y1); return; } deltax = abs(x2 - x1); if (deltax == 0) { /* DEBUGF("lcd_drawline() called for vertical line - optimisation.\n"); */ lcd_vline(x1, y1, y2); return; } xinc2 = 1; yinc2 = 1; if (deltax >= deltay) { numpixels = deltax; d = 2 * deltay - deltax; dinc1 = deltay * 2; dinc2 = (deltay - deltax) * 2; xinc1 = 1; yinc1 = 0; } else { numpixels = deltay; d = 2 * deltax - deltay; dinc1 = deltax * 2; dinc2 = (deltax - deltay) * 2; xinc1 = 0; yinc1 = 1; } numpixels++; /* include endpoints */ if (x1 > x2) { xinc1 = -xinc1; xinc2 = -xinc2; } if (y1 > y2) { yinc1 = -yinc1; yinc2 = -yinc2; } x = x1; y = y1; for (i = 0; i < numpixels; i++) { if ( ((unsigned)x < (unsigned)current_vp->width) && ((unsigned)y < (unsigned)current_vp->height) #if defined(HAVE_VIEWPORT_CLIP) && ((unsigned)x < (unsigned)LCD_WIDTH) && ((unsigned)y < (unsigned)LCD_HEIGHT) #endif ) pfunc(FBADDR(x + current_vp->x, y + current_vp->y)); if (d < 0) { d += dinc1; x += xinc1; y += yinc1; } else { d += dinc2; x += xinc2; y += yinc2; } } }