int16_t checkIncDec(uint8_t event, int16_t val, int16_t i_min, int16_t i_max, uint8_t i_flags) { int16_t newval = val; #if defined(DBLKEYS) uint8_t in = KEYS_PRESSED(); if (!(i_flags & NO_DBLKEYS) && (EVT_KEY_MASK(event))) { bool dblkey = true; if (DBLKEYS_PRESSED_RGT_LFT(in)) newval = -val; else if (DBLKEYS_PRESSED_RGT_UP(in)) { newval = (i_max > 100 ? 100 : i_max); } else if (DBLKEYS_PRESSED_LFT_DWN(in)) { newval = (i_min < -100 ? -100 : i_min); } else if (DBLKEYS_PRESSED_UP_DWN(in)) { newval = 0; } else { dblkey = false; } if (dblkey) { killEvents(KEY_UP); killEvents(KEY_DOWN); killEvents(KEY_RIGHT); killEvents(KEY_LEFT); event = 0; } } #endif if (event==EVT_KEY_FIRST(KEY_RIGHT) || event==EVT_KEY_REPT(KEY_RIGHT) || (s_editMode>0 && (IS_ROTARY_RIGHT(event) || event==EVT_KEY_FIRST(KEY_UP) || event==EVT_KEY_REPT(KEY_UP)))) { newval++; AUDIO_KEYPAD_UP(); } else if (event==EVT_KEY_FIRST(KEY_LEFT) || event==EVT_KEY_REPT(KEY_LEFT) || (s_editMode>0 && (IS_ROTARY_LEFT(event) || event==EVT_KEY_FIRST(KEY_DOWN) || event==EVT_KEY_REPT(KEY_DOWN)))) { newval--; AUDIO_KEYPAD_DOWN(); } if (!READ_ONLY() && i_min==0 && i_max==1 && (event==EVT_KEY_BREAK(KEY_ENTER) || IS_ROTARY_BREAK(event))) { s_editMode = 0; newval = !val; } #if defined(NAVIGATION_POT1) // change values based on P1 newval -= p1valdiff; p1valdiff = 0; #endif #if defined(AUTOSWITCH) if (i_flags & INCDEC_SWITCH) { newval = checkIncDecMovedSwitch(newval); } #endif #if defined(AUTOSOURCE) if (i_flags & INCDEC_SOURCE) { if (s_editMode>0) { int8_t source = GET_MOVED_SOURCE(i_min, i_max); if (source) { newval = source; } #if defined(AUTOSWITCH) else { uint8_t swtch = abs(getMovedSwitch()); if (swtch) { newval = switchToMix(swtch); } } #endif } } #endif if (newval > i_max || newval < i_min) { newval = (newval > i_max ? i_max : i_min); killEvents(event); AUDIO_WARNING2(); } if (newval != val) { if (!(i_flags & NO_INCDEC_MARKS) && (newval != i_max) && (newval != i_min) && (newval==0 || newval==-100 || newval==+100) && !IS_ROTARY_EVENT(event)) { pauseEvents(event); // delay before auto-repeat continues if (newval>val) // without AUDIO it's optimized, because the 2 sounds are the same AUDIO_KEYPAD_UP(); else AUDIO_KEYPAD_DOWN(); } eeDirty(i_flags & (EE_GENERAL|EE_MODEL)); checkIncDec_Ret = (newval > val ? 1 : -1); } else { checkIncDec_Ret = 0; } return newval; }
uint32_t fileList(uint8_t event, struct fileControl *fc ) { uint32_t limit ; uint32_t result = 0 ; uint8_t maxhsize ; uint32_t i ; limit = 6 ; if ( fc->nameCount < limit ) { limit = fc->nameCount ; } maxhsize = 0 ; for ( i = 0 ; i < limit ; i += 1 ) { uint32_t x ; uint32_t len ; len = x = strlen( Filenames[i] ) ; if ( x > maxhsize ) { maxhsize = x ; } if ( x > DISPLAY_CHAR_WIDTH ) { if ( ( fc->hpos + DISPLAY_CHAR_WIDTH ) > x ) { x = x - DISPLAY_CHAR_WIDTH ; } else { x = fc->hpos ; } len = DISPLAY_CHAR_WIDTH ; } else { x = 0 ; } lcd_putsn_P( 0, 16+FH*i, &Filenames[i][x], len ) ; } #if !defined(PCBTARANIS) if ( event == 0 ) { extern int32_t Rotary_diff ; if ( Rotary_diff > 0 ) { event = EVT_KEY_FIRST(KEY_DOWN) ; } else if ( Rotary_diff < 0 ) { event = EVT_KEY_FIRST(KEY_UP) ; } Rotary_diff = 0 ; } #endif if ( ( event == EVT_KEY_REPT(KEY_DOWN) ) || event == EVT_KEY_FIRST(KEY_DOWN) ) { if ( fc->vpos < limit-1 ) { fc->vpos += 1 ; } else { if ( fc->nameCount > limit ) { fc->index += 1 ; fc->nameCount = fillNames( fc->index, fc ) ; } } } if ( ( event == EVT_KEY_REPT(KEY_UP)) || ( event == EVT_KEY_FIRST(KEY_UP) ) ) { if ( fc->vpos > 0 ) { fc->vpos -= 1 ; } else { if ( fc->index ) { fc->index -= 1 ; fc->nameCount = fillNames( fc->index, fc ) ; } } } if ( ( event == EVT_KEY_REPT(MKEY_RIGHT)) || ( event == EVT_KEY_FIRST(MKEY_RIGHT) ) ) { if ( fc->hpos + DISPLAY_CHAR_WIDTH < maxhsize ) fc->hpos += 1 ; } if ( ( event == EVT_KEY_REPT(MKEY_LEFT)) || ( event == EVT_KEY_FIRST(MKEY_LEFT) ) ) { if ( fc->hpos ) fc->hpos -= 1 ; } if ( ( event == EVT_KEY_LONG(KEY_MENU) ) || ( event == EVT_KEY_BREAK(BTN_RE) ) ) { // Select file to flash killEvents(event); result = 1 ; } if ( ( event == EVT_KEY_FIRST(KEY_EXIT) ) || ( event == EVT_KEY_LONG(BTN_RE) ) ) { // Select file to flash result = 2 ; } if ( event == EVT_KEY_BREAK(KEY_MENU) ) { // Tag file result = 3 ; } #if defined(PCBTARANIS) lcd_filled_rect( 0, 2*FH+FH*fc->vpos, DISPLAY_CHAR_WIDTH*FW, 8, 0xFF, 0 ) ; #else lcd_char_inverse( 0, 2*FH+FH*fc->vpos, DISPLAY_CHAR_WIDTH*FW, 0 ) ; #endif return result ; }
void Key::input(bool val, EnumKeys enuk) { // uint8_t old=m_vals; m_vals <<= 1; if(val) m_vals |= 1; //portbit einschieben m_cnt++; if(m_state && m_vals==0){ //gerade eben sprung auf 0 if(m_state!=KSTATE_KILLED) { putEvent(EVT_KEY_BREAK(enuk)); if(!( m_state == 16 && m_cnt<16)){ m_dblcnt=0; } // } } m_cnt = 0; m_state = KSTATE_OFF; } switch(m_state){ case KSTATE_OFF: if(m_vals==FFVAL){ //gerade eben sprung auf ff m_state = KSTATE_START; if(m_cnt>16) m_dblcnt=0; //pause zu lang fuer double m_cnt = 0; } break; //fallthrough case KSTATE_START: putEvent(EVT_KEY_FIRST(enuk)); m_dblcnt++; #ifdef KSTATE_RPTDELAY m_state = KSTATE_RPTDELAY; #else m_state = 16; #endif m_cnt = 0; break; #ifdef KSTATE_RPTDELAY case KSTATE_RPTDELAY: // gruvin: longer delay before first key repeat if(m_cnt == 24) putEvent(EVT_KEY_LONG(enuk)); // need to catch this inside RPTDELAY time if (m_cnt == 40) { m_state = 16; m_cnt = 0; } break; #endif case 16: #ifndef KSTATE_RPTDELAY if(m_cnt == 24) putEvent(EVT_KEY_LONG(enuk)); //fallthrough #endif case 8: case 4: case 2: if(m_cnt >= 48) { //3 6 12 24 48 pulses in every 480ms m_state >>= 1; m_cnt = 0; } //fallthrough case 1: if( (m_cnt & (m_state-1)) == 0) putEvent(EVT_KEY_REPT(enuk)); break; case KSTATE_PAUSE: //pause if(m_cnt >= 64) { m_state = 8; m_cnt = 0; } break; case KSTATE_KILLED: //killed break; }
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 }
void menuModelSelect(uint8_t event) { if (s_warning_result) { s_warning_result = 0; eeDeleteModel(m_posVert); // delete file s_copyMode = 0; event = EVT_ENTRY_UP; } uint8_t _event_ = (IS_ROTARY_BREAK(event) || IS_ROTARY_LONG(event) ? 0 : event); if ((s_copyMode && EVT_KEY_MASK(event) == KEY_EXIT) || event == EVT_KEY_BREAK(KEY_EXIT)) { _event_ -= KEY_EXIT; } int8_t oldSub = m_posVert; check_submenu_simple(_event_, MAX_MODELS-1); #if defined(NAVIGATION_POT2) if (event==0 && p2valdiff<0) { event = EVT_KEY_FIRST(KEY_RIGHT); } #endif if (s_editMode > 0) s_editMode = 0; #if !defined(CPUARM) if (event) { eeFlush(); // flush eeprom write } #endif int8_t sub = m_posVert; switch (event) { case EVT_ENTRY: m_posVert = sub = g_eeGeneral.currModel; if (sub >= LCD_LINES-1) s_pgOfs = sub-LCD_LINES+2; s_copyMode = 0; s_editMode = EDIT_MODE_INIT; eeCheck(true); break; case EVT_KEY_LONG(KEY_EXIT): killEvents(event); if (s_copyMode && s_copyTgtOfs == 0 && g_eeGeneral.currModel != sub && eeModelExists(sub)) { POPUP_CONFIRMATION(STR_DELETEMODEL); #if defined(CPUARM) SET_WARNING_INFO(modelHeaders[sub].name, sizeof(g_model.header.name), ZCHAR); #else char * name = reusableBuffer.modelsel.mainname; eeLoadModelName(sub, name); SET_WARNING_INFO(name, sizeof(g_model.header.name), ZCHAR); #endif } else { s_copyMode = 0; m_posVert = g_eeGeneral.currModel; } break; #if defined(ROTARY_ENCODER_NAVIGATION) case EVT_ROTARY_LONG: killEvents(event); if (s_editMode < 0) { popMenu(); break; } else if (!s_copyMode) { m_posVert = sub = g_eeGeneral.currModel; s_copyMode = 0; s_editMode = EDIT_MODE_INIT; } // no break #endif case EVT_KEY_BREAK(KEY_EXIT): if (s_copyMode) { sub = m_posVert = (s_copyMode == MOVE_MODE || s_copySrcRow<0) ? (MAX_MODELS+sub+s_copyTgtOfs) % MAX_MODELS : s_copySrcRow; s_copyMode = 0; } else if (m_posVert != g_eeGeneral.currModel) { m_posVert = g_eeGeneral.currModel; } else { popMenu(); } break; #if defined(ROTARY_ENCODER_NAVIGATION) case EVT_ROTARY_BREAK: if (s_editMode == -1) { s_editMode = 0; break; } // no break; #endif case EVT_KEY_LONG(KEY_ENTER): case EVT_KEY_BREAK(KEY_ENTER): s_editMode = 0; if (READ_ONLY()) { if (g_eeGeneral.currModel != sub && eeModelExists(sub)) { selectModel(sub); } } else if (s_copyMode && (s_copyTgtOfs || s_copySrcRow>=0)) { displayPopup(s_copyMode==COPY_MODE ? STR_COPYINGMODEL : STR_MOVINGMODEL); eeCheck(true); // force writing of current model data before this is changed uint8_t cur = (MAX_MODELS + sub + s_copyTgtOfs) % MAX_MODELS; if (s_copyMode == COPY_MODE) { if (!eeCopyModel(cur, s_copySrcRow)) { cur = sub; } } s_copySrcRow = g_eeGeneral.currModel; // to update the currModel value while (sub != cur) { uint8_t src = cur; cur = (s_copyTgtOfs > 0 ? cur+MAX_MODELS-1 : cur+1) % MAX_MODELS; eeSwapModels(src, cur); if (src == s_copySrcRow) s_copySrcRow = cur; else if (cur == s_copySrcRow) s_copySrcRow = src; } if (s_copySrcRow != g_eeGeneral.currModel) { g_eeGeneral.currModel = s_copySrcRow; eeDirty(EE_GENERAL); } s_copyMode = 0; event = EVT_ENTRY_UP; } else if (event == EVT_KEY_LONG(KEY_ENTER) || IS_ROTARY_BREAK(event)) { s_copyMode = 0; killEvents(event); #if defined(NAVIGATION_MENUS) if (g_eeGeneral.currModel != sub) { if (eeModelExists(sub)) { MENU_ADD_ITEM(STR_SELECT_MODEL); MENU_ADD_SD_ITEM(STR_BACKUP_MODEL); MENU_ADD_ITEM(STR_COPY_MODEL); MENU_ADD_ITEM(STR_MOVE_MODEL); MENU_ADD_ITEM(STR_DELETE_MODEL); } else { #if defined(SDCARD) MENU_ADD_ITEM(STR_CREATE_MODEL); MENU_ADD_ITEM(STR_RESTORE_MODEL); #else selectModel(sub); #endif } } else { MENU_ADD_SD_ITEM(STR_BACKUP_MODEL); MENU_ADD_ITEM(STR_COPY_MODEL); MENU_ADD_ITEM(STR_MOVE_MODEL); } menuHandler = onModelSelectMenu; #else if (g_eeGeneral.currModel != sub) { selectModel(sub); } #endif } else if (eeModelExists(sub)) { s_copyMode = (s_copyMode == COPY_MODE ? MOVE_MODE : COPY_MODE); s_copyTgtOfs = 0; s_copySrcRow = -1; } break; #if defined(ROTARY_ENCODER_NAVIGATION) case EVT_ROTARY_LEFT: case EVT_ROTARY_RIGHT: #endif case EVT_KEY_FIRST(KEY_LEFT): case EVT_KEY_FIRST(KEY_RIGHT): #if defined(ROTARY_ENCODER_NAVIGATION) if ((!IS_ROTARY_RIGHT(event) && !IS_ROTARY_LEFT(event)) || s_editMode < 0) { #endif if (sub == g_eeGeneral.currModel) { chainMenu((IS_ROTARY_RIGHT(event) || event == EVT_KEY_FIRST(KEY_RIGHT)) ? menuModelSetup : menuTabModel[DIM(menuTabModel)-1]); } else { AUDIO_WARNING2(); } break; #if defined(ROTARY_ENCODER_NAVIGATION) } // no break #endif case EVT_KEY_FIRST(KEY_MOVE_UP): case EVT_KEY_REPT(KEY_MOVE_UP): case EVT_KEY_FIRST(KEY_MOVE_DOWN): case EVT_KEY_REPT(KEY_MOVE_DOWN): if (s_copyMode) { int8_t next_ofs = s_copyTgtOfs + oldSub - m_posVert; if (next_ofs == MAX_MODELS || next_ofs == -MAX_MODELS) next_ofs = 0; if (s_copySrcRow < 0 && s_copyMode==COPY_MODE) { s_copySrcRow = oldSub; // find a hole (in the first empty slot above / below) sub = eeFindEmptyModel(s_copySrcRow, IS_ROTARY_DOWN(event) || event==EVT_KEY_FIRST(KEY_MOVE_DOWN)); if (sub < 0) { // no free room for duplicating the model AUDIO_ERROR(); sub = oldSub; s_copyMode = 0; } next_ofs = 0; m_posVert = sub; } s_copyTgtOfs = next_ofs; } break; } #if !defined(PCBSKY9X) lcd_puts(9*FW-(LEN_FREE-4)*FW, 0, STR_FREE); if (event) reusableBuffer.modelsel.eepromfree = EeFsGetFree(); lcd_outdezAtt(17*FW, 0, reusableBuffer.modelsel.eepromfree, 0); #endif #if defined(ROTARY_ENCODER_NAVIGATION) displayScreenIndex(e_ModelSelect, DIM(menuTabModel), (sub == g_eeGeneral.currModel) ? ((IS_RE_NAVIGATION_ENABLE() && s_editMode < 0) ? INVERS|BLINK : INVERS) : 0); #else displayScreenIndex(e_ModelSelect, DIM(menuTabModel), (sub == g_eeGeneral.currModel) ? INVERS : 0); #endif TITLE(STR_MENUMODELSEL); for (uint8_t i=0; i<LCD_LINES-1; i++) { coord_t y = MENU_HEADER_HEIGHT + 1 + i*FH; uint8_t k = i+s_pgOfs; lcd_outdezNAtt(3*FW+2, y, k+1, LEADING0+((!s_copyMode && sub==k) ? INVERS : 0), 2); if (s_copyMode == MOVE_MODE || (s_copyMode == COPY_MODE && s_copySrcRow >= 0)) { if (k == sub) { if (s_copyMode == COPY_MODE) { k = s_copySrcRow; lcd_putc(MODELSEL_W-FW, y, '+'); } else { k = sub + s_copyTgtOfs; } } else if (s_copyTgtOfs < 0 && ((k < sub && k >= sub+s_copyTgtOfs) || (k-MAX_MODELS < sub && k-MAX_MODELS >= sub+s_copyTgtOfs))) k += 1; else if (s_copyTgtOfs > 0 && ((k > sub && k <= sub+s_copyTgtOfs) || (k+MAX_MODELS > sub && k+MAX_MODELS <= sub+s_copyTgtOfs))) k += MAX_MODELS-1; } k %= MAX_MODELS; if (eeModelExists(k)) { #if defined(PCBSKY9X) putsModelName(4*FW, y, modelHeaders[k].name, k, 0); #else char * name = reusableBuffer.modelsel.listnames[i]; if (event) eeLoadModelName(k, name); putsModelName(4*FW, y, name, k, 0); lcd_outdezAtt(20*FW, y, eeModelSize(k), 0); #endif if (k==g_eeGeneral.currModel && (s_copyMode!=COPY_MODE || s_copySrcRow<0 || i+s_pgOfs!=(vertpos_t)sub)) lcd_putc(1, y, '*'); } if (s_copyMode && (vertpos_t)sub==i+s_pgOfs) { drawFilledRect(9, y, MODELSEL_W-1-9, 7); lcd_rect(8, y-1, MODELSEL_W-1-7, 9, s_copyMode == COPY_MODE ? SOLID : DOTTED); } } }
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; }
int16_t checkIncDec(uint8_t event, int16_t val, int16_t i_min, int16_t i_max, uint8_t i_flags) #endif { int16_t newval = val; #if defined(DBLKEYS) uint8_t in = KEYS_PRESSED(); if (EVT_KEY_MASK(event)) { bool dblkey = true; if (DBLKEYS_PRESSED_RGT_LFT(in)) newval = -val; else if (DBLKEYS_PRESSED_RGT_UP(in)) { newval = (i_max > 100 ? 100 : i_max); #if defined(CPUARM) if (i_flags & DBLKEYS_1000) newval *= 10; #endif } else if (DBLKEYS_PRESSED_LFT_DWN(in)) { newval = (i_min < -100 ? -100 : i_min); #if defined(CPUARM) if (i_flags & DBLKEYS_1000) newval *= 10; #endif } else if (DBLKEYS_PRESSED_UP_DWN(in)) newval = 0; else dblkey = false; #if defined(CPUARM) #endif if (dblkey) { killEvents(KEY_UP); killEvents(KEY_DOWN); killEvents(KEY_RIGHT); killEvents(KEY_LEFT); #if defined(PCBTARANIS) killEvents(KEY_PAGE); killEvents(KEY_MENU); killEvents(KEY_ENTER); killEvents(KEY_EXIT); #endif event = 0; } } #endif #if defined(PCBTARANIS) if (s_editMode>0 && (IS_ROTARY_RIGHT(event) || event==EVT_KEY_FIRST(KEY_UP) || event==EVT_KEY_REPT(KEY_UP))) { #else if (event==EVT_KEY_FIRST(KEY_RIGHT) || event==EVT_KEY_REPT(KEY_RIGHT) || (s_editMode>0 && (IS_ROTARY_RIGHT(event) || event==EVT_KEY_FIRST(KEY_UP) || event==EVT_KEY_REPT(KEY_UP)))) { #endif #if defined(CPUARM) do { if (IS_KEY_REPT(event) && (i_flags & INCDEC_REP10)) { newval += min(10, i_max-val); } else { newval++; } } while (isValueAvailable && !isValueAvailable(newval) && newval<=i_max); if (newval > i_max) { newval = val; killEvents(event); AUDIO_WARNING2(); } else #else newval++; #endif AUDIO_KEYPAD_UP(); } #if defined(PCBTARANIS) else if (s_editMode>0 && (IS_ROTARY_LEFT(event) || event==EVT_KEY_FIRST(KEY_DOWN) || event==EVT_KEY_REPT(KEY_DOWN))) { #else else if (event==EVT_KEY_FIRST(KEY_LEFT) || event==EVT_KEY_REPT(KEY_LEFT) || (s_editMode>0 && (IS_ROTARY_LEFT(event) || event==EVT_KEY_FIRST(KEY_DOWN) || event==EVT_KEY_REPT(KEY_DOWN)))) { #endif #if defined(CPUARM) do { if (IS_KEY_REPT(event) && (i_flags & INCDEC_REP10)) { newval -= min(10, val-i_min); } else { newval--; } } while (isValueAvailable && !isValueAvailable(newval) && newval>=i_min); if (newval < i_min) { newval = val; killEvents(event); AUDIO_WARNING2(); } else #else newval--; #endif AUDIO_KEYPAD_DOWN(); } if (!READ_ONLY() && i_min==0 && i_max==1 && (event==EVT_KEY_BREAK(KEY_ENTER) || IS_ROTARY_BREAK(event))) { s_editMode = 0; newval = !val; } #if defined(NAVIGATION_POT1) // change values based on P1 newval -= p1valdiff; p1valdiff = 0; #endif #if defined(AUTOSWITCH) if (i_flags & INCDEC_SWITCH) { if (s_editMode>0) { int8_t swtch = getMovedSwitch(); if (swtch) { #if defined(PCBTARANIS) if(swtch == SWSRC_SH2) newval = (newval == SWSRC_SH2 ? SWSRC_SH0 : SWSRC_SH2); else if(swtch != SWSRC_SH0) newval = swtch; #else if (IS_MOMENTARY(newval) && IS_MOMENTARY(swtch)) newval = -newval; else newval = swtch; #endif } } } #endif #if defined(AUTOSOURCE) if (i_flags & INCDEC_SOURCE) { if (s_editMode>0) { int8_t source = GET_MOVED_SOURCE(i_min, i_max); if (source) { newval = source; } #if defined(AUTOSWITCH) else { uint8_t swtch = abs(getMovedSwitch()); if (swtch) { newval = switchToMix(swtch); } } #endif } } #endif if (newval > i_max || newval < i_min) { newval = (newval > i_max ? i_max : i_min); killEvents(event); AUDIO_WARNING2(); } if (newval != val) { if (!(i_flags & NO_INCDEC_MARKS) && (newval != i_max) && (newval != i_min) && (newval==0 || newval==-100 || newval==+100) && !IS_ROTARY_EVENT(event)) { pauseEvents(event); // delay before auto-repeat continues if (newval>val) // without AUDIO it's optimized, because the 2 sounds are the same AUDIO_KEYPAD_UP(); else AUDIO_KEYPAD_DOWN(); } eeDirty(i_flags & (EE_GENERAL|EE_MODEL)); checkIncDec_Ret = (newval > val ? 1 : -1); } else { checkIncDec_Ret = 0; } return newval; } #if defined(CPUM64) int8_t checkIncDecModel(uint8_t event, int8_t i_val, int8_t i_min, int8_t i_max) { return checkIncDec(event, i_val, i_min, i_max, EE_MODEL); } int8_t checkIncDecModelZero(uint8_t event, int8_t i_val, int8_t i_max) { return checkIncDecModel(event, i_val, 0, i_max); } int8_t checkIncDecGen(uint8_t event, int8_t i_val, int8_t i_min, int8_t i_max) { return checkIncDec(event, i_val, i_min, i_max, EE_GENERAL); } #endif bool check_simple(check_event_t event, uint8_t curr, const MenuFuncP *menuTab, uint8_t menuTabSize, vertpos_t maxrow) { return check(event, curr, menuTab, menuTabSize, 0, 0, maxrow); } bool check_submenu_simple(check_event_t event, uint8_t maxrow) { return check_simple(event, 0, 0, 0, maxrow); } void title(const pm_char * s) { lcd_putsAtt(0, 0, s, INVERS); } #define SCROLL_TH 64 #define SCROLL_POT1_TH 32 #if defined(CPUARM) #define CURSOR_NOT_ALLOWED_IN_ROW(row) ((int8_t)MAXCOL(row) < 0) #else #define CURSOR_NOT_ALLOWED_IN_ROW(row) (MAXCOL(row) == TITLE_ROW) #endif #if defined(PCBTARANIS) #define MAXCOL_RAW(row) (horTab ? pgm_read_byte(horTab+min(row, (vertpos_t)horTabMax)) : (const uint8_t)0) #define MAXCOL(row) (MAXCOL_RAW(row) >= HIDDEN_ROW ? MAXCOL_RAW(row) : (const uint8_t)(MAXCOL_RAW(row) & (~NAVIGATION_LINE_BY_LINE))) #define COLATTR(row) (MAXCOL_RAW(row) == (uint8_t)-1 ? (const uint8_t)0 : (const uint8_t)(MAXCOL_RAW(row) & NAVIGATION_LINE_BY_LINE)) #else #define MAXCOL(row) (horTab ? pgm_read_byte(horTab+min(row, (vertpos_t)horTabMax)) : (const uint8_t)0) #endif #define INC(val, min, max) if (val<max) {val++;} else {val=min;} #define DEC(val, min, max) if (val>min) {val--;} else {val=max;} #if LCD_W >= 212 uint8_t scrollbar_X = LCD_W-1; #endif #if defined(CPUARM) bool modelHasNotes() { char filename[sizeof(MODELS_PATH)+1+sizeof(g_model.header.name)+sizeof(TEXT_EXT)] = MODELS_PATH "/"; char *buf = strcat_modelname(&filename[sizeof(MODELS_PATH)], g_eeGeneral.currModel); strcpy(buf, TEXT_EXT); return isFileAvailable(filename); }
int16_t checkIncDec(uint8_t event, int16_t val, int16_t i_min, int16_t i_max, uint8_t i_flags) { int16_t newval = val; uint8_t kpl=KEY_RIGHT, kmi=KEY_LEFT, kother = -1; if(event & _MSK_KEY_DBL){ uint8_t hlp=kpl; kpl=kmi; kmi=hlp; event=EVT_KEY_FIRST(EVT_KEY_MASK & event); } if(event==EVT_KEY_FIRST(kpl) || event== EVT_KEY_REPT(kpl) || (s_editMode>0 && (event==EVT_KEY_FIRST(KEY_UP) || event== EVT_KEY_REPT(KEY_UP))) ) { newval++; #if defined (BEEPSPKR) beepKeySpkr(BEEP_KEY_UP_FREQ); #else beepKey(); #endif kother=kmi; }else if(event==EVT_KEY_FIRST(kmi) || event== EVT_KEY_REPT(kmi) || (s_editMode>0 && (event==EVT_KEY_FIRST(KEY_DOWN) || event== EVT_KEY_REPT(KEY_DOWN))) ) { newval--; #if defined (BEEPSPKR) beepKeySpkr(BEEP_KEY_DOWN_FREQ); #else beepKey(); #endif kother=kpl; } if((kother != (uint8_t)-1) && keyState((EnumKeys)kother)){ newval=-val; killEvents(kmi); killEvents(kpl); } if(i_min==0 && i_max==1 && event==EVT_KEY_FIRST(KEY_MENU)) { s_editMode = 0; newval=!val; killEvents(event); } #if defined(NAVIGATION_POT1) || defined (NAVIGATION_RE1) //change values based on P1 newval -= p1valdiff; #endif if(newval > i_max) { newval = i_max; killEvents(event); #if defined (BEEPSPKR) beepWarn2Spkr(BEEP_KEY_UP_FREQ); #else beepWarn2(); #endif } if(newval < i_min) { newval = i_min; killEvents(event); #if defined (BEEPSPKR) beepWarn2Spkr(BEEP_KEY_DOWN_FREQ); #else beepWarn2(); #endif } if(newval != val){ if(newval==0) { pauseEvents(event); // delay before auto-repeat continues #if defined (BEEPSPKR) if (newval>val) beepWarn2Spkr(BEEP_KEY_UP_FREQ); else beepWarn2Spkr(BEEP_KEY_DOWN_FREQ); #else beepKey(); #endif } eeDirty(i_flags & (EE_GENERAL|EE_MODEL)); checkIncDec_Ret = (newval > val ? 1 : -1); } else { checkIncDec_Ret = 0; } return newval; }
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 checkIncDec(unsigned int event, int val, int i_min, int i_max, unsigned int i_flags, IsValueAvailable isValueAvailable, const CheckIncDecStops &stops) { int newval = val; #if defined(DBLKEYS) uint32_t in = KEYS_PRESSED(); if (!(i_flags & NO_DBLKEYS) && (EVT_KEY_MASK(event))) { bool dblkey = true; if (DBLKEYS_PRESSED_RGT_LFT(in)) { if (!isValueAvailable || isValueAvailable(-val)) { newval = -val; } } else if (DBLKEYS_PRESSED_RGT_UP(in)) { newval = (i_max > stops.max() ? stops.max() : i_max); while (isValueAvailable && !isValueAvailable(newval) && newval>i_min) { --newval; } } else if (DBLKEYS_PRESSED_LFT_DWN(in)) { newval = (i_min < stops.min() ? stops.min() : i_min); while (isValueAvailable && !isValueAvailable(newval) && newval<i_max) { ++newval; } } else if (DBLKEYS_PRESSED_UP_DWN(in)) { newval = 0; } else { dblkey = false; } if (dblkey) { killEvents(KEY_UP); killEvents(KEY_DOWN); killEvents(KEY_RIGHT); killEvents(KEY_LEFT); killEvents(KEY_PAGE); killEvents(KEY_MENU); killEvents(KEY_ENTER); killEvents(KEY_EXIT); event = 0; } } #endif if (s_editMode>0 && (IS_ROTARY_RIGHT(event) || event==EVT_KEY_FIRST(KEY_UP) || event==EVT_KEY_REPT(KEY_UP))) { do { if (IS_KEY_REPT(event) && (i_flags & INCDEC_REP10)) { newval += min(10, i_max-val); } else { newval++; } } while (isValueAvailable && !isValueAvailable(newval) && newval<=i_max); if (newval > i_max) { newval = val; killEvents(event); AUDIO_WARNING2(); } else { AUDIO_KEYPAD_UP(); } } else if (s_editMode>0 && (IS_ROTARY_LEFT(event) || event==EVT_KEY_FIRST(KEY_DOWN) || event==EVT_KEY_REPT(KEY_DOWN))) { do { if (IS_KEY_REPT(event) && (i_flags & INCDEC_REP10)) { newval -= min(10, val-i_min); } else { newval--; } } while (isValueAvailable && !isValueAvailable(newval) && newval>=i_min); if (newval < i_min) { newval = val; killEvents(event); AUDIO_WARNING2(); } else { AUDIO_KEYPAD_DOWN(); } } if (!READ_ONLY() && i_min==0 && i_max==1 && (event==EVT_KEY_BREAK(KEY_ENTER) || IS_ROTARY_BREAK(event))) { s_editMode = 0; newval = !val; } #if defined(AUTOSWITCH) if (i_flags & INCDEC_SWITCH) { newval = checkIncDecMovedSwitch(newval); } #endif #if defined(AUTOSOURCE) if (i_flags & INCDEC_SOURCE) { if (s_editMode>0) { int source = GET_MOVED_SOURCE(i_min, i_max); if (source) { newval = source; } #if defined(AUTOSWITCH) else { unsigned int swtch = abs(getMovedSwitch()); if (swtch) { newval = switchToMix(swtch); } } #endif } } #endif if (newval > i_max || newval < i_min) { newval = (newval > i_max ? i_max : i_min); killEvents(event); AUDIO_WARNING2(); } if (newval != val) { if (!(i_flags & NO_INCDEC_MARKS) && (newval != i_max) && (newval != i_min) && stops.contains(newval) && !IS_ROTARY_EVENT(event)) { bool pause = (newval > val ? !stops.contains(newval+1) : !stops.contains(newval-1)); if (pause) { pauseEvents(event); // delay before auto-repeat continues if (newval>val) // without AUDIO it's optimized, because the 2 sounds are the same AUDIO_KEYPAD_UP(); else AUDIO_KEYPAD_DOWN(); } } eeDirty(i_flags & (EE_GENERAL|EE_MODEL)); checkIncDec_Ret = (newval > val ? 1 : -1); } else { checkIncDec_Ret = 0; } if (i_flags & INCDEC_SOURCE) { if (event == EVT_KEY_LONG(KEY_ENTER)) { killEvents(event); checkIncDecSelection = MIXSRC_NONE; if (i_min <= MIXSRC_FIRST_INPUT && i_max >= MIXSRC_FIRST_INPUT) { if (getFirstAvailable(MIXSRC_FIRST_INPUT, MIXSRC_LAST_INPUT, isInputAvailable) != MIXSRC_NONE) { POPUP_MENU_ADD_ITEM(STR_MENU_INPUTS); } } #if defined(LUA_MODEL_SCRIPTS) if (i_min <= MIXSRC_FIRST_LUA && i_max >= MIXSRC_FIRST_LUA) { if (getFirstAvailable(MIXSRC_FIRST_LUA, MIXSRC_LAST_LUA, isSourceAvailable) != MIXSRC_NONE) { POPUP_MENU_ADD_ITEM(STR_MENU_LUA); } } #endif if (i_min <= MIXSRC_FIRST_STICK && i_max >= MIXSRC_FIRST_STICK) POPUP_MENU_ADD_ITEM(STR_MENU_STICKS); if (i_min <= MIXSRC_FIRST_POT && i_max >= MIXSRC_FIRST_POT) POPUP_MENU_ADD_ITEM(STR_MENU_POTS); if (i_min <= MIXSRC_MAX && i_max >= MIXSRC_MAX) POPUP_MENU_ADD_ITEM(STR_MENU_MAX); #if defined(HELI) if (i_min <= MIXSRC_FIRST_HELI && i_max >= MIXSRC_FIRST_HELI) POPUP_MENU_ADD_ITEM(STR_MENU_HELI); #endif if (i_min <= MIXSRC_FIRST_TRIM && i_max >= MIXSRC_FIRST_TRIM) POPUP_MENU_ADD_ITEM(STR_MENU_TRIMS); if (i_min <= MIXSRC_FIRST_SWITCH && i_max >= MIXSRC_FIRST_SWITCH) POPUP_MENU_ADD_ITEM(STR_MENU_SWITCHES); if (i_min <= MIXSRC_FIRST_TRAINER && i_max >= MIXSRC_FIRST_TRAINER) POPUP_MENU_ADD_ITEM(STR_MENU_TRAINER); if (i_min <= MIXSRC_FIRST_CH && i_max >= MIXSRC_FIRST_CH) POPUP_MENU_ADD_ITEM(STR_MENU_CHANNELS); if (i_min <= MIXSRC_FIRST_GVAR && i_max >= MIXSRC_FIRST_GVAR && isValueAvailable(MIXSRC_FIRST_GVAR)) { POPUP_MENU_ADD_ITEM(STR_MENU_GVARS); } if (i_min <= MIXSRC_FIRST_TELEM && i_max >= MIXSRC_FIRST_TELEM) { for (int i = 0; i < MAX_SENSORS; i++) { TelemetrySensor * sensor = & g_model.telemetrySensors[i]; if (sensor->isAvailable()) { POPUP_MENU_ADD_ITEM(STR_MENU_TELEMETRY); break; } } } popupMenuHandler = onSourceLongEnterPress; } if (checkIncDecSelection != 0) { newval = checkIncDecSelection; if (checkIncDecSelection != MIXSRC_MAX) s_editMode = EDIT_MODIFY_FIELD; checkIncDecSelection = 0; } } else if (i_flags & INCDEC_SWITCH) { if (event == EVT_KEY_LONG(KEY_ENTER)) { killEvents(event); checkIncDecSelection = SWSRC_NONE; if (i_min <= SWSRC_FIRST_SWITCH && i_max >= SWSRC_LAST_SWITCH) POPUP_MENU_ADD_ITEM(STR_MENU_SWITCHES); if (i_min <= SWSRC_FIRST_TRIM && i_max >= SWSRC_LAST_TRIM) POPUP_MENU_ADD_ITEM(STR_MENU_TRIMS); if (i_min <= SWSRC_FIRST_LOGICAL_SWITCH && i_max >= SWSRC_LAST_LOGICAL_SWITCH) { for (int i = 0; i < NUM_LOGICAL_SWITCH; i++) { if (isValueAvailable && isValueAvailable(SWSRC_FIRST_LOGICAL_SWITCH+i)) { POPUP_MENU_ADD_ITEM(STR_MENU_LOGICAL_SWITCHES); break; } } } if (isValueAvailable && isValueAvailable(SWSRC_ON)) POPUP_MENU_ADD_ITEM(STR_MENU_OTHER); if (isValueAvailable && isValueAvailable(-newval)) POPUP_MENU_ADD_ITEM(STR_MENU_INVERT); popupMenuHandler = onSwitchLongEnterPress; s_editMode = EDIT_MODIFY_FIELD; } if (checkIncDecSelection != 0) { newval = (checkIncDecSelection == SWSRC_INVERT ? -newval : checkIncDecSelection); s_editMode = EDIT_MODIFY_FIELD; checkIncDecSelection = 0; } } return newval; }
void menuModelExpoMix(uint8_t expo, uint8_t event) { uint8_t sub = m_posVert; if (s_editMode > 0) s_editMode = 0; uint8_t chn = (expo ? expoAddress(s_currIdx)->chn+1 : mixAddress(s_currIdx)->destCh+1); switch (event) { case EVT_ENTRY: case EVT_ENTRY_UP: s_copyMode = 0; s_copyTgtOfs = 0; break; case EVT_KEY_LONG(KEY_EXIT): if (s_copyMode && s_copyTgtOfs == 0) { deleteExpoMix(expo, s_currIdx); killEvents(event); event = 0; } // no break case EVT_KEY_BREAK(KEY_EXIT): if (s_copyMode) { if (s_copyTgtOfs) { // cancel the current copy / move operation if (s_copyMode == COPY_MODE) { deleteExpoMix(expo, s_currIdx); } else { do { swapExpoMix(expo, s_currIdx, s_copyTgtOfs > 0); s_copyTgtOfs += (s_copyTgtOfs < 0 ? +1 : -1); } while (s_copyTgtOfs != 0); eeDirty(EE_MODEL); } m_posVert = s_copySrcRow; s_copyTgtOfs = 0; } s_copyMode = 0; event = 0; } break; case EVT_KEY_BREAK(KEY_ENTER): if ((!s_currCh || (s_copyMode && !s_copyTgtOfs)) && !READ_ONLY()) { s_copyMode = (s_copyMode == COPY_MODE ? MOVE_MODE : COPY_MODE); s_copySrcIdx = s_currIdx; s_copySrcCh = chn; s_copySrcRow = sub; break; } // no break case EVT_KEY_LONG(KEY_ENTER): killEvents(event); if (s_copyTgtOfs) { s_copyMode = 0; s_copyTgtOfs = 0; } else { if (READ_ONLY()) { if (!s_currCh) { pushMenu(expo ? menuModelExpoOne : menuModelMixOne); } } else { if (s_copyMode) s_currCh = 0; if (s_currCh) { if (reachExpoMixCountLimit(expo)) break; insertExpoMix(expo, s_currIdx); pushMenu(expo ? menuModelExpoOne : menuModelMixOne); s_copyMode = 0; } else { event = 0; s_copyMode = 0; MENU_ADD_ITEM(STR_EDIT); MENU_ADD_ITEM(STR_INSERT_BEFORE); MENU_ADD_ITEM(STR_INSERT_AFTER); MENU_ADD_ITEM(STR_COPY); MENU_ADD_ITEM(STR_MOVE); MENU_ADD_ITEM(STR_DELETE); menuHandler = onExpoMixMenu; } } } break; case EVT_KEY_LONG(KEY_LEFT): case EVT_KEY_LONG(KEY_RIGHT): if (s_copyMode && !s_copyTgtOfs) { if (reachExpoMixCountLimit(expo)) break; s_currCh = chn; if (event == EVT_KEY_LONG(KEY_RIGHT)) { s_currIdx++; m_posVert++; } insertExpoMix(expo, s_currIdx); pushMenu(expo ? menuModelExpoOne : menuModelMixOne); s_copyMode = 0; killEvents(event); } break; case EVT_KEY_FIRST(KEY_MOVE_UP): case EVT_KEY_REPT(KEY_MOVE_UP): case EVT_KEY_FIRST(KEY_MOVE_DOWN): case EVT_KEY_REPT(KEY_MOVE_DOWN): if (s_copyMode) { uint8_t key = (event & 0x1f); uint8_t next_ofs = (key==KEY_MOVE_UP ? s_copyTgtOfs - 1 : s_copyTgtOfs + 1); if (s_copyTgtOfs==0 && s_copyMode==COPY_MODE) { // insert a mix on the same channel (just above / just below) if (reachExpoMixCountLimit(expo)) break; copyExpoMix(expo, s_currIdx); if (key==KEY_MOVE_DOWN) s_currIdx++; else if (sub-s_pgOfs >= 6) s_pgOfs++; } else if (next_ofs==0 && s_copyMode==COPY_MODE) { // delete the mix deleteExpoMix(expo, s_currIdx); if (key==KEY_MOVE_UP) s_currIdx--; } else { // only swap the mix with its neighbor if (!swapExpoMix(expo, s_currIdx, key==KEY_MOVE_UP)) break; eeDirty(EE_MODEL); } s_copyTgtOfs = next_ofs; } break; } if (expo) { lcd_outdezAtt(FW*sizeof(TR_MENUINPUTS)+FW+FW/2, 0, getExpoMixCount(true)); lcd_puts(FW*sizeof(TR_MENUINPUTS)+FW+FW/2, 0, STR_MAX(MAX_EXPOS)); // Value uint8_t index = expoAddress(s_currIdx)->chn; if (!s_currCh) { lcd_outdezAtt(127, 2, calcRESXto1000(anas[index]), PREC1|TINSIZE); } SIMPLE_MENU(STR_MENUINPUTS, menuTabModel, e_InputsAll, s_maxLines); // Gauge if (!s_currCh) { drawGauge(127, 1, 58, 6, anas[index], 1024); } } else { lcd_outdezAtt(FW*sizeof(TR_MIXER)+FW+FW/2, 0, getExpoMixCount(false)); lcd_puts(FW*sizeof(TR_MIXER)+FW+FW/2, 0, STR_MAX(MAX_MIXERS)); // Value uint8_t index = mixAddress(s_currIdx)->destCh; if (!s_currCh) { displayHeaderChannelName(index); lcd_outdezAtt(127, 2, calcRESXto1000(ex_chans[index]), PREC1|TINSIZE); } SIMPLE_MENU(STR_MIXER, menuTabModel, e_MixAll, s_maxLines); // Gauge if (!s_currCh) { drawGauge(127, 1, 58, 6, ex_chans[index], 1024); } } sub = m_posVert; s_currCh = 0; int cur = 0; int i = 0; for (int ch=1; ch<=(expo ? NUM_INPUTS : NUM_CHNOUT); ch++) { void *pointer = NULL; MixData * &md = (MixData * &)pointer; ExpoData * &ed = (ExpoData * &)pointer; coord_t y = MENU_HEADER_HEIGHT+1+(cur-s_pgOfs)*FH; if (expo ? (i<MAX_EXPOS && (ed=expoAddress(i))->chn+1 == ch && EXPO_VALID(ed)) : (i<MAX_MIXERS && (md=mixAddress(i))->srcRaw && md->destCh+1 == ch)) { if (cur-s_pgOfs >= 0 && cur-s_pgOfs < NUM_BODY_LINES) { if (expo) { putsMixerSource(0, y, ch, 0); } else { putsChn(0, y, ch, 0); // show CHx } } uint8_t mixCnt = 0; do { if (s_copyMode) { if (s_copyMode == MOVE_MODE && cur-s_pgOfs >= 0 && cur-s_pgOfs < NUM_BODY_LINES && s_copySrcCh == ch && s_copyTgtOfs != 0 && i == (s_copySrcIdx + (s_copyTgtOfs<0))) { lcd_rect(expo ? 18 : 22, y-1, expo ? LCD_W-18 : LCD_W-22, 9, DOTTED); cur++; y+=FH; } if (s_currIdx == i) { sub = m_posVert = cur; s_currCh = ch; } } else if (sub == cur) { s_currIdx = i; } if (cur-s_pgOfs >= 0 && cur-s_pgOfs < NUM_BODY_LINES) { uint8_t attr = ((s_copyMode || sub != cur) ? 0 : INVERS); if (expo) { GVAR_MENU_ITEM(EXPO_LINE_WEIGHT_POS, y, ed->weight, MIN_EXPO_WEIGHT, 100, attr | (isExpoActive(i) ? BOLD : 0), 0, 0); displayExpoLine(y, ed); if (ed->mode!=3) { lcd_putc(EXPO_LINE_SIDE_POS, y, ed->mode == 2 ? 126 : 127); } } else { if (mixCnt > 0) lcd_putsiAtt(FW, y, STR_VMLTPX2, md->mltpx, 0); putsMixerSource(MIX_LINE_SRC_POS, y, md->srcRaw, 0); gvarWeightItem(MIX_LINE_WEIGHT_POS, y, md, attr | (isMixActive(i) ? BOLD : 0), 0); displayMixLine(y, md); char cs = ' '; if (md->speedDown || md->speedUp) cs = 'S'; if (md->delayUp || md->delayDown) cs = (cs =='S' ? '*' : 'D'); lcd_putc(MIX_LINE_DELAY_POS, y, cs); } if (s_copyMode) { if ((s_copyMode==COPY_MODE || s_copyTgtOfs == 0) && s_copySrcCh == ch && i == (s_copySrcIdx + (s_copyTgtOfs<0))) { /* draw a border around the raw on selection mode (copy/move) */ lcd_rect(expo ? EXPO_LINE_SELECT_POS : 22, y-1, expo ? (LCD_W-EXPO_LINE_SELECT_POS) : (LCD_W-22), 9, s_copyMode == COPY_MODE ? SOLID : DOTTED); } if (cur == sub) { /* invert the raw when it's the current one */ drawFilledRect(expo ? EXPO_LINE_SELECT_POS+1 : 23, y, expo ? (LCD_W-EXPO_LINE_SELECT_POS-2) : (LCD_W-24), 7); } } } cur++; y+=FH; mixCnt++; i++; if (expo) ed++; else md++; } while (expo ? (i<MAX_EXPOS && ed->chn+1 == ch && EXPO_VALID(ed)) : (i<MAX_MIXERS && md->srcRaw && md->destCh+1 == ch)); if (s_copyMode == MOVE_MODE && cur-s_pgOfs >= 0 && cur-s_pgOfs < NUM_BODY_LINES && s_copySrcCh == ch && i == (s_copySrcIdx + (s_copyTgtOfs<0))) { lcd_rect(expo ? EXPO_LINE_SELECT_POS : 22, y-1, expo ? LCD_W-EXPO_LINE_SELECT_POS : LCD_W-22, 9, DOTTED); cur++; y+=FH; } } else { uint8_t attr = 0; if (sub == cur) { s_currIdx = i; s_currCh = ch; if (!s_copyMode) { attr = INVERS; } } if (cur-s_pgOfs >= 0 && cur-s_pgOfs < NUM_BODY_LINES) { if (expo) { putsMixerSource(0, y, ch, attr); } else { putsChn(0, y, ch, attr); // show CHx } if (s_copyMode == MOVE_MODE && s_copySrcCh == ch) { lcd_rect(expo ? EXPO_LINE_SELECT_POS : 22, y-1, expo ? (LCD_W-EXPO_LINE_SELECT_POS) : (LCD_W-22), 9, DOTTED); } } cur++; y+=FH; } } s_maxLines = cur; if (sub >= s_maxLines-1) m_posVert = s_maxLines-1; }
void Key::input(bool val, EnumKeys enuk) { // uint8_t old=m_vals; m_vals <<= 1; if(val) m_vals |= 1; //portbit einschieben m_cnt++; if(m_state && m_vals==0){ //gerade eben sprung auf 0 if(m_state!=KSTATE_KILLED) { putEvent(EVT_KEY_BREAK(enuk)); if(!( m_state == 32 && m_cnt<16)){ m_dblcnt=0; } // } } m_cnt = 0; m_state = KSTATE_OFF; } switch(m_state){ case KSTATE_OFF: if(m_vals==FFVAL){ //gerade eben sprung auf ff m_state = KSTATE_START; if(m_cnt>20) m_dblcnt=0; //pause zu lang fuer double m_cnt = 0; } break; //fallthrough case KSTATE_START: putEvent(EVT_KEY_FIRST(enuk)); m_dblcnt++; m_state = 32; m_cnt = 0; break; case 32: //if(m_dblcnt>1) printf("double=%d\n",m_dblcnt); if(m_cnt == 24) putEvent(EVT_KEY_LONG(enuk)); //fallthrough case 16: case 8: if(m_cnt >= 64) { //2 4 8 16 32 pulses in every 640ms m_state >>= 1; m_cnt = 0; } //fallthrough case 4: //case 2: #ifdef xSIM printf("."); fflush(stdout); #endif if( (m_cnt & (m_state-1)) == 0) { #ifdef xSIM printf("\n"); #endif putEvent(EVT_KEY_REPT(enuk)); } break; case KSTATE_SLOW: //slow if(m_cnt >= 32) { m_cnt = 0; putEvent(EVT_KEY_REPT(enuk)); } break; case KSTATE_PAUSE: //pause if(m_cnt >= 64) { m_state = 8; m_cnt = 0; } break; case KSTATE_KILLED: //killed break; }
void editName(coord_t x, coord_t y, char *name, uint8_t size, uint8_t event, uint8_t active, uint8_t attr) { uint8_t mode = 0; if (active) { if (s_editMode <= 0) mode = INVERS + FIXEDWIDTH; else mode = FIXEDWIDTH; } lcd_putsnAtt(x, y, name, size, attr | mode); coord_t backupNextPos = lcdNextPos; if (active) { uint8_t cur = editNameCursorPos; if (s_editMode > 0) { int8_t c = name[cur]; int8_t v = c; if (IS_ROTARY_RIGHT(event) || IS_ROTARY_LEFT(event) || event==EVT_KEY_FIRST(KEY_DOWN) || event==EVT_KEY_FIRST(KEY_UP) || event==EVT_KEY_REPT(KEY_DOWN) || event==EVT_KEY_REPT(KEY_UP)) { if (attr == ZCHAR) { v = checkIncDec(event, abs(v), 0, ZCHAR_MAX, 0); if (c <= 0) v = -v; } else { v = checkIncDec(event, abs(v), '0', 'z', 0); } } switch (event) { case EVT_ROTARY_BREAK: if (s_editMode == EDIT_MODIFY_FIELD) { s_editMode = EDIT_MODIFY_STRING; cur = 0; } else if (cur<size-1) cur++; else s_editMode = 0; break; case EVT_ROTARY_LONG: if (attr & ZCHAR) { if (v == 0) { s_editMode = 0; killEvents(event); } else if (v>=-26 && v<=26) { v = -v; // toggle case } } else { if (v == ' ') { s_editMode = 0; killEvents(event); break; } else if (v>='A' && v<='Z') { v = 'a'+v-'A'; // toggle case } else if (v>='a' && v<='z') { v = 'A'+v-'a'; // toggle case } } break; } if (c != v) { name[cur] = v; eeDirty(menuVerticalPositions[0] == 0 ? EE_MODEL : EE_GENERAL); } if (attr == ZCHAR) { lcd_putcAtt(x+editNameCursorPos*FW, y, idx2char(v), ERASEBG|INVERS|FIXEDWIDTH); } else { lcd_putcAtt(x+editNameCursorPos*FW, y, v, ERASEBG|INVERS|FIXEDWIDTH); } } else { cur = 0; } editNameCursorPos = cur; lcdNextPos = backupNextPos; } }
{ "MIXSRC_SF", MIXSRC_SF }, { "MIXSRC_SG", MIXSRC_SG }, { "MIXSRC_SH", MIXSRC_SH }, { "MIXSRC_CH1", MIXSRC_CH1 }, { "SWSRC_LAST", SWSRC_LAST_LOGICAL_SWITCH }, { "EVT_MENU_BREAK", EVT_KEY_BREAK(KEY_MENU) }, { "EVT_PAGE_BREAK", EVT_KEY_BREAK(KEY_PAGE) }, { "EVT_PAGE_LONG", EVT_KEY_LONG(KEY_PAGE) }, { "EVT_ENTER_BREAK", EVT_KEY_BREAK(KEY_ENTER) }, { "EVT_ENTER_LONG", EVT_KEY_LONG(KEY_ENTER) }, { "EVT_EXIT_BREAK", EVT_KEY_BREAK(KEY_EXIT) }, { "EVT_PLUS_BREAK", EVT_KEY_BREAK(KEY_PLUS) }, { "EVT_MINUS_BREAK", EVT_KEY_BREAK(KEY_MINUS) }, { "EVT_PLUS_FIRST", EVT_KEY_FIRST(KEY_PLUS) }, { "EVT_MINUS_FIRST", EVT_KEY_FIRST(KEY_MINUS) }, { "EVT_PLUS_REPT", EVT_KEY_REPT(KEY_PLUS) }, { "EVT_MINUS_REPT", EVT_KEY_REPT(KEY_MINUS) }, { "FILL_WHITE", FILL_WHITE }, { "GREY_DEFAULT", GREY_DEFAULT }, { "SOLID", SOLID }, { "DOTTED", DOTTED }, { "FORCE", FORCE }, { "ERASE", ERASE }, { "ROUND", ROUND }, { "LCD_W", LCD_W }, { "LCD_H", LCD_H }, { "PLAY_NOW", PLAY_NOW }, { "PLAY_BACKGROUND", PLAY_BACKGROUND }, { "TIMEHOUR", TIMEHOUR }, { NULL, 0 } /* sentinel */ };
const char * displayMenu(uint8_t event) { const char * result = NULL; uint8_t display_count = min(s_menu_count, (uint16_t)MENU_MAX_LINES); uint8_t y = (display_count >= 5 ? MENU_Y - FH - 1 : MENU_Y); lcd_filled_rect(MENU_X, y, MENU_W, display_count * (FH+1) + 2, SOLID, ERASE); lcd_rect(MENU_X, y, MENU_W, display_count * (FH+1) + 2); for (uint8_t i=0; i<display_count; i++) { lcd_putsAtt(MENU_X+6, i*(FH+1) + y + 2, s_menu[i], s_menu_flags); if (i == s_menu_item) lcd_filled_rect(MENU_X+1, i*(FH+1) + y + 1, MENU_W-2, 9); } if (s_menu_count > display_count) { displayScrollbar(MENU_X+MENU_W-1, y+1, MENU_MAX_LINES * (FH+1), s_menu_offset, s_menu_count, MENU_MAX_LINES); } switch(event) { #if defined(ROTARY_ENCODER_NAVIGATION) CASE_EVT_ROTARY_LEFT #endif case EVT_KEY_FIRST(KEY_MOVE_UP): case EVT_KEY_REPT(KEY_MOVE_UP): if (s_menu_item > 0) { s_menu_item--; } #if defined(SDCARD) else if (s_menu_offset > 0) { s_menu_offset--; result = STR_UPDATE_LIST; } #endif else { s_menu_item = display_count - 1; #if defined(SDCARD) if (s_menu_count > MENU_MAX_LINES) { s_menu_offset = s_menu_count - display_count; result = STR_UPDATE_LIST; } #endif } break; #if defined(ROTARY_ENCODER_NAVIGATION) CASE_EVT_ROTARY_RIGHT #endif case EVT_KEY_FIRST(KEY_MOVE_DOWN): case EVT_KEY_REPT(KEY_MOVE_DOWN): if (s_menu_item < display_count - 1 && s_menu_offset + s_menu_item + 1 < s_menu_count) { s_menu_item++; } #if defined(SDCARD) else if (s_menu_count > s_menu_offset + display_count) { s_menu_offset++; result = STR_UPDATE_LIST; } #endif else { s_menu_item = 0; #if defined(SDCARD) if (s_menu_offset) { s_menu_offset = 0; result = STR_UPDATE_LIST; } #endif } break; CASE_EVT_ROTARY_BREAK case EVT_KEY_BREAK(KEY_ENTER): result = s_menu[s_menu_item]; // no break #if defined(ROTARY_ENCODER_NAVIGATION) CASE_EVT_ROTARY_LONG killEvents(event); #endif case EVT_KEY_BREAK(KEY_EXIT): s_menu_count = 0; s_menu_item = 0; s_menu_flags = 0; s_menu_offset = 0; break; } return result; }
void Key::input(bool val, EnumKeys enuk) { uint8_t t_vals = m_vals ; t_vals <<= 1 ; if (val) t_vals |= 1; //portbit einschieben m_vals = t_vals ; m_cnt++; if (m_state && m_vals==0) { //gerade eben sprung auf 0 if (m_state != KSTATE_KILLED) { putEvent(EVT_KEY_BREAK(enuk)); } m_cnt = 0; m_state = KSTATE_OFF; } switch(m_state){ case KSTATE_OFF: if (m_vals == FFVAL) { //gerade eben sprung auf ff m_state = KSTATE_START; m_cnt = 0; } break; //fallthrough case KSTATE_START: putEvent(EVT_KEY_FIRST(enuk)); inactivity.counter = 0; m_state = KSTATE_RPTDELAY; m_cnt = 0; break; case KSTATE_RPTDELAY: // gruvin: delay state before first key repeat if(m_cnt == KEY_LONG_DELAY) putEvent(EVT_KEY_LONG(enuk)); if (m_cnt == 40) { m_state = 16; m_cnt = 0; } break; case 16: case 8: case 4: case 2: if(m_cnt >= 48) { //3 6 12 24 48 pulses in every 480ms m_state >>= 1; m_cnt = 0; } // no break case 1: if( (m_cnt & (m_state-1)) == 0) putEvent(EVT_KEY_REPT(enuk)); break; case KSTATE_PAUSE: //pause if(m_cnt >= 64) { m_state = 8; m_cnt = 0; } break; case KSTATE_KILLED: //killed break; }
bool check(uint8_t event, uint8_t curr, const MenuFuncP *menuTab, uint8_t menuTabSize, const pm_uint8_t *horTab, uint8_t horTabMax, uint8_t maxrow) { uint8_t maxcol = MAXCOL(m_posVert); #ifdef NAVIGATION_RE1 // check rotary encoder 1 if changed -> cursor down/up static int16_t re1valprev; p1valdiff = 0; scrollRE = re1valprev - g_rotenc[0]; if (scrollRE) { re1valprev = g_rotenc[0]; if (s_editMode > 0) { p1valdiff = - scrollRE; scrollRE = 0; } } if (event == EVT_KEY_LONG(BTN_RE1)) { if (!menuTab && !s_editMode) { popMenu(); killEvents(event); } } if (event == EVT_KEY_BREAK(BTN_RE1)) { if (s_editMode > 0 && (maxcol & ZCHAR)) { if (m_posHorz < maxcol-ZCHAR) { m_posHorz++; } else { s_editMode = 0; } } else { scrollRE = 0; if (s_editMode++ > 0) s_editMode = 0; if (s_editMode > 0 && m_posVert == 0 && menuTab) s_editMode = -1; } } #else #define scrollRE 0 #endif #ifdef NAVIGATION_POT1 // check pot 1 - if changed -> scroll values static int16_t p1valprev; p1valdiff = (p1valprev-calibratedStick[6]) / SCROLL_POT1_TH; if (p1valdiff) p1valprev = calibratedStick[6]; #endif #ifdef NAVIGATION_POT2 // check pot 2 - if changed -> scroll menu static int16_t p2valprev; int8_t scrollLR = (p2valprev-calibratedStick[4]) / SCROLL_TH; if (scrollLR) p2valprev = calibratedStick[4]; #else #define scrollLR 0 #endif #ifdef 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(scrollLR || scrollUD || p1valdiff) g_LightOffCounter = g_eeGeneral.lightAutoOff*500; // on keypress turn the light on 5*100 if (menuTab) { uint8_t attr = 0; if (m_posVert==0 && !s_noScroll) { attr = INVERS; int8_t cc = curr; if (scrollLR || (scrollRE && s_editMode < 0)) { cc = limit((int8_t)0, (int8_t)(curr - scrollLR + scrollRE), (int8_t)(menuTabSize-1)); } switch(event) { case EVT_KEY_FIRST(KEY_LEFT): if (curr > 0) cc = curr - 1; else cc = menuTabSize-1; break; case EVT_KEY_FIRST(KEY_RIGHT): if (curr < (menuTabSize-1)) cc = curr + 1; else cc = 0; break; } if (cc != curr) { chainMenu((MenuFuncP)pgm_read_adr(&menuTab[cc])); return false; } } s_noScroll = 0; DisplayScreenIndex(curr, menuTabSize, attr); } theFile.DisplayProgressBar(menuTab ? lcd_lastPos-2*FW-((curr+1)/10*FWNUM)-2 : 20*FW+1); if (s_editMode<=0) { if (scrollUD) { m_posVert = limit((int8_t)0, (int8_t)(m_posVert - scrollUD), (int8_t)maxrow); m_posHorz = min(m_posHorz, MAXCOL(m_posVert)); BLINK_SYNC; } if (scrollLR && m_posVert>0) { m_posHorz = limit((int8_t)0, (int8_t)(m_posHorz - scrollLR), (int8_t)maxcol); BLINK_SYNC; } #ifdef NAVIGATION_RE1 while (!s_editMode && scrollRE) { if (scrollRE > 0) { --scrollRE; maxcol = MAXCOL(m_posVert); if (maxcol & ZCHAR) maxcol = 0; if (++m_posHorz > maxcol) { m_posHorz = 0; if (++m_posVert > maxrow) { m_posVert = maxrow; m_posHorz = MAXCOL(m_posVert); scrollRE = 0; } } } else { ++scrollRE; if (m_posHorz-- == 0) { if (m_posVert-- == 0) { m_posVert = 0; m_posHorz = 0; scrollRE = 0; } else { m_posHorz = MAXCOL(m_posVert); } } } } #endif } switch(event) { case EVT_ENTRY: minit(); #ifdef NAVIGATION_RE1 if (menuTab) { s_editMode = -1; break; } // no break #else s_editMode = -1; break; #endif #ifdef NAVIGATION_RE1 case EVT_ENTRY_UP: s_editMode = 0; break; #endif case EVT_KEY_FIRST(KEY_MENU): if (maxcol > 0) s_editMode = (s_editMode<=0); break; case EVT_KEY_LONG(KEY_EXIT): s_editMode = 0; popMenu(); break; case EVT_KEY_BREAK(KEY_EXIT): if(s_editMode>0) { s_editMode = 0; break; } if (m_posVert==0 || !menuTab) { popMenu(); //beeps itself } else { beepKey(); minit(); BLINK_SYNC; } break; case EVT_KEY_REPT(KEY_RIGHT): //inc if(m_posHorz==maxcol) break; case EVT_KEY_FIRST(KEY_RIGHT)://inc if(!horTab || s_editMode>0)break; INC(m_posHorz,maxcol); BLINK_SYNC; break; case EVT_KEY_REPT(KEY_LEFT): //dec if(m_posHorz==0) break; case EVT_KEY_FIRST(KEY_LEFT)://dec if(!horTab || s_editMode>0)break; DEC(m_posHorz,maxcol); BLINK_SYNC; break; case EVT_KEY_REPT(KEY_DOWN): //inc if(m_posVert==maxrow) break; case EVT_KEY_FIRST(KEY_DOWN): //inc if(s_editMode>0)break; do { INC(m_posVert,maxrow); } while(MAXCOL(m_posVert) == (uint8_t)-1); m_posHorz = min(m_posHorz, MAXCOL(m_posVert)); BLINK_SYNC; break; case EVT_KEY_REPT(KEY_UP): //dec if(m_posVert==0) break; case EVT_KEY_FIRST(KEY_UP): //dec if(s_editMode>0)break; do { DEC(m_posVert,maxrow); } while(MAXCOL(m_posVert) == (uint8_t)-1); m_posHorz = min(m_posHorz, MAXCOL(m_posVert)); BLINK_SYNC; break; } uint8_t max = menuTab ? 7 : 6; if(m_posVert<1) s_pgOfs=0; else if(m_posVert-s_pgOfs>max) s_pgOfs = m_posVert-max; else if(m_posVert-s_pgOfs<1) s_pgOfs = m_posVert-1; return true; }