static void blinkNumLockLED(void) { static int counter = 0; const int countMAX = 100; //on off on off if(ledBlinkNumLockCount > 0){ counter++; if(counter > countMAX){ if(ledBlinkNumLockCount == 5 || ledBlinkNumLockCount == 3){ turnOnLED(LEDNUM); //PORTLEDS |= (1 << LEDCAPS); }else if(ledBlinkNumLockCount == 4 || ledBlinkNumLockCount == 2){ turnOffLED(LEDNUM); //PORTLEDS &= ~(1 << LEDCAPS); }else{ if(isBeyondFnLedEnabled()){ if(isBeyondFN()){ turnOnLED(LEDNUM); } }else{ if((getLEDState() & LED_STATE_NUM)){ turnOnLED(LEDNUM); } } } counter = 0; ledBlinkNumLockCount--; } }else{ counter = 0; } }
void setLEDIndicate(void) { static bool prevNum = false; if(isBeyondFnLedEnabled()){ ledBlinkNumLockCount = getLedBlnik(LED_STATE_NUM, isBeyondFN(), &prevNum); }else{ if (LEDstate & LED_STATE_NUM) { // light up num lock turnOnLED(LEDNUM);//PORTLEDS |= (1 << LEDNUM); // } else { turnOffLED(LEDNUM);//PORTLEDS &= ~(1 << LEDNUM); // } } if (LEDstate & LED_STATE_CAPS) { // light up caps lock turnOnLED(LEDCAPS); //PORTLEDS |= (1 << LEDCAPS); // } else { turnOffLED(LEDCAPS); //PORTLEDS &= ~(1 << LEDCAPS); // } #ifdef LEDSCROLL if (LEDstate & LED_STATE_SCROLL) { // light up scroll lock turnOnLED(LEDSCROLL); //PORTLEDS |= (1 << LEDCAPS); // } else { turnOffLED(LEDSCROLL); //PORTLEDS &= ~(1 << LEDCAPS); // } #endif #ifndef SCROLL_LOCK_LED_IS_APART static bool prevScroll = false; ledBlinkScrollLockCount = getLedBlnik(LED_STATE_SCROLL, (LEDstate & LED_STATE_CAPS), &prevScroll); #endif }
void blinkOnce(const int xStayMs){ if(isBeyondFnLedEnabled()){ if (isBeyondFN()) { // light up num lock on FN2 toggle turnOffLED(LEDNUM);//PORTLEDS |= (1 << LEDNUM); // } else { turnOnLED(LEDNUM);//PORTLEDS &= ~(1 << LEDNUM); // } }else{ if (LEDstate & LED_STATE_NUM) { // light up num lock turnOffLED(LEDNUM);//PORTLEDS &= ~(1 << LEDNUM); // }else{ turnOnLED(LEDNUM);//PORTLEDS &= ~(1 << LEDNUM); // } } if (LEDstate & LED_STATE_CAPS) { // light up caps lock turnOffLED(LEDCAPS); //PORTLEDS &= ~(1 << LEDCAPS); // } else { turnOnLED(LEDCAPS); //PORTLEDS |= (1 << LEDCAPS); // } /* _delay_ms()에 xStayMs를 인자로 넣으면 hex 파일의 용량이 0x1000가량 증가한다. 매뉴얼 펑션으로 _delay_ms(1)을 ms 만큼 루프시키도록 만들어서 사용; */ __delay_ms(xStayMs); if(isBeyondFnLedEnabled()){ if (isBeyondFN()) { // light up num lock on FN2 toggle turnOnLED(LEDNUM);//PORTLEDS |= (1 << LEDNUM); // } else { turnOffLED(LEDNUM);//PORTLEDS &= ~(1 << LEDNUM); // } }else{ if (LEDstate & LED_STATE_NUM) { // light up num lock turnOnLED(LEDNUM);//PORTLEDS &= ~(1 << LEDNUM); // }else{ turnOffLED(LEDNUM);//PORTLEDS &= ~(1 << LEDNUM); // } } if (LEDstate & LED_STATE_CAPS) { // light up caps lock turnOnLED(LEDCAPS); //PORTLEDS |= (1 << LEDCAPS); // } else { turnOffLED(LEDCAPS); //PORTLEDS &= ~(1 << LEDCAPS); // } }
void setLEDIndicate(void) { static uint8_t prevLEDstate; if (isBeyondFnLedEnabled() == BEYOND_FN_LED_NL) { getLedBlink(LED_STATE_NUM, isBeyondFN(), &prevLEDstate, &ledBlinkCount); } else { if (LEDstate & LED_STATE_NUM) { // light up num lock turnOnLED(LEDNUM); //PORTLEDS |= (1 << LEDNUM); // } else { turnOffLED(LEDNUM); //PORTLEDS &= ~(1 << LEDNUM); // } } if (LEDstate & LED_STATE_CAPS) { // light up caps lock turnOnLED(LEDCAPS); //PORTLEDS |= (1 << LEDCAPS); // } else { turnOffLED(LEDCAPS); //PORTLEDS &= ~(1 << LEDCAPS); // } #ifdef LEDSCROLL if (isBeyondFnLedEnabled() == BEYOND_FN_LED_SL) { getLedBlink(LED_STATE_SCROLL, isBeyondFN(), &prevLEDstate, &ledBlinkCount); } else { if (LEDstate & LED_STATE_SCROLL) { // light up scroll lock turnOnLED(LEDSCROLL);//PORTLEDS |= (1 << LEDCAPS); // } else { turnOffLED(LEDSCROLL); //PORTLEDS &= ~(1 << LEDCAPS); // } } #endif #ifndef SCROLL_LOCK_LED_IS_APART getLedBlink(LED_STATE_SCROLL, (LEDstate & LED_STATE_CAPS), &prevLEDstate, &ledBlinkScrollLockCount); #endif prevLEDstate = LEDstate; }
// 키를 누르거나 땔때 FN 및 LED등 을 컨트롤한다. bool applyFN(uint8_t xKeyidx, uint8_t xCol, uint8_t xRow, bool xIsDown) { // DEBUG_PRINT(("applyFN : %d xIsDown : %d\n", xKeyidx, xIsDown)); applyKeyDownForFullLED(xKeyidx, xCol, xRow, xIsDown); if(isFnKey(xKeyidx)) return false; setDualAction(xKeyidx, xIsDown); // 듀얼액션 키의 기본 키를 가져온다. xKeyidx = getDualActionDefaultKey(xKeyidx); if(isFnKey(xKeyidx)) return false; if(xIsDown) { if((xKeyidx == KEY_BEYOND_FN || xKeyidx == KEY_BEYOND_FN3) || (_isExtraFNDown && xKeyidx == BEYOND_FN_CANCEL_KEY)){ // beyond_fn을 활성화; if( xKeyidx == BEYOND_FN_CANCEL_KEY ) { // 취소만 가능한 키 _beyondFnIndex = false; }else{ if(_beyondFnIndex == 0){ if(xKeyidx == KEY_BEYOND_FN){ _beyondFnIndex = LAYER_FN2; }else{ _beyondFnIndex = LAYER_FN3; } }else{ if(xKeyidx == KEY_BEYOND_FN){ if(_beyondFnIndex == LAYER_FN2){ _beyondFnIndex = LAYER_NORMAL; }else{ _beyondFnIndex = LAYER_FN2; } }else if(xKeyidx == KEY_BEYOND_FN3){ if(_beyondFnIndex == LAYER_FN3){ _beyondFnIndex = LAYER_NORMAL; }else{ _beyondFnIndex = LAYER_FN3; } } } } #ifndef DISABLE_FN2_TOGGLE_LED_BLINK if(isBeyondFnLedEnabled() == false){ if(_beyondFnIndex == 0){ blinkOnce(100); }else{ blinkOnce(100); _delay_ms(80); blinkOnce(70); } } #endif if(isBeyondFnLedEnabled()){ setLed(LED_STATE_NUM, isBeyondFN()); } return 0; }else if(_isQuickMacroDown && isEepromMacroKey(xKeyidx)){ _quickMacroIndex = xKeyidx - KEY_MAC1; _isReadyQuickMacro = true; return 0; }else if(xKeyidx == EXTRA_FN){ _isExtraFNDown = true; }else if((_isExtraFNDown && xKeyidx == LED_KEY)){ uint8_t gModi = getModifierDownBuffer(); if(gModi == 0x02 || gModi == 0x20){ changeFullLedState(FULL_LED_MODE2); }else{ changeFullLedState(FULL_LED_MODE1); } return 0; }else if(xKeyidx == KEY_LED){ changeFullLedState(FULL_LED_MODE1); return 0; }else if(xKeyidx == KEY_LED2){ changeFullLedState(FULL_LED_MODE2); return 0; }else if(xKeyidx == KEY_LED_UP){ uint8_t gModi = getModifierDownBuffer(); if(gModi == 0x02 || gModi == 0x20){ increaseLedBrightness(FULL_LED_MODE2); }else{ increaseLedBrightness(FULL_LED_MODE1); } return 0; }else if(xKeyidx == KEY_LED_DOWN){ uint8_t gModi = getModifierDownBuffer(); if(gModi == 0x02 || gModi == 0x20){ reduceLedBrightness(FULL_LED_MODE2); }else{ reduceLedBrightness(FULL_LED_MODE1); } return 0; }else if(xKeyidx == KEY_LED_ON_OFF){ _ledOff ^= true; if(_ledOff == false){ turnOnLedAll(); }else{ turnOffLedAll(); } }else if(xKeyidx == KEY_QUICK_MACRO){ if(isQuickMacro()){ stopQuickMacro(); }else{ _isQuickMacroDown = true; } return 0; } }else{ // up if(xKeyidx == KEY_BEYOND_FN){ // beyond_fn return 0; }else if(xKeyidx == EXTRA_FN){ _isExtraFNDown = false; }else if(xKeyidx == KEY_QUICK_MACRO){ _isQuickMacroDown = false; return 0; } } return 1; }
// function that determine keymap // 0 = normal, 1 = fn, 2 = beyond_fn uint8_t getLayer(void) { uint8_t col, row, keyidx, cur, gLayer; /* 게으른 FN이 작동되는 상황 정리; - 첫키로 FN이 눌려야 한다. 이미 다른 키가 눌려있다면 작동 안 함; <- 불편할 수 있으므로 기본 레이어일 경우에는 다른 키들이 눌려져 있어도 FN이 작동하도록 한다. : - 작동이 된 후에는 모든 키가 release 되는 순간까지 layer를 유지 시킨다. (즉, 모든 키가 release 되고 1프레임 후에 작동 해제 되어야한다. ps2의 경우 제일 마지막 키의 release값을 처리해야하기 때문에.) */ if(_currentLazyLayer > 0) return _currentLazyLayer; gLayer= 0; // fn이 가장 우선, 다음 fn2 uint8_t *gMatrix = getCurrentMatrix(); for(row=0;row<ROWS;row++){ if(gMatrix[row] == 0) continue; for(col=0;col<COLUMNS;col++){ cur = gMatrix[row] & BV(col); if(cur){ keyidx = getCurrentKeyindex(_fnScanLayer, row, col); keyidx = getDualActionKeyWhenCompound(keyidx); // fn 키는 무조건 다운 액션을 적용; #ifdef DEBUG_QUICK_BOOTLOADER // for test if(col == 0 && row == 0){ wdt_enable(WDTO_15MS); while(1); } #endif // DEBUG_PRINT(("col= %d, row= %d keymap\n", col, row)); if(keyidx == KEY_FN){ gLayer = LAYER_FN; }else if(keyidx == KEY_FN2){ gLayer = LAYER_FN2; }else if(keyidx == KEY_FN3){ gLayer = LAYER_FN3; }else if(keyidx == KEY_NOR){ if(_fnScanLayer == LAYER_FN2){ // _fnScanLayer은 2를 유지하면서 스캔할 레이어는 0으로 반환; _isFnPressed = true; return LAYER_NORMAL; } } if(gLayer > 0){ // _fnScanLayer은 0을 유지하면서 스캔할 레이어는 1로 반환; if(isLazyFn()){ if(isReleaseAllPrev() || _isFnPressed == false){ _currentLazyLayer = gLayer; }else{ return _fnScanLayer; } } _isFnPressed = true; return gLayer; } } } } if(isBeyondFN()) { _fnScanLayer = isBeyondFN(); }else{ _fnScanLayer = LAYER_NORMAL; } _isFnPressed = false; return _fnScanLayer; }