예제 #1
0
static void applyQuickSwap(uint8_t xModi) {
	static uint8_t prevModifier = 0;

	if(getDownBufferAt(0) > 0){
		enabledQuickSwapCount = 0;
		return;
	}
	
	if(xModi == prevModifier) return;

	if(xModi == 0x0C || xModi == 0xC0 || xModi == 0x48 || xModi == 0x84){	// ALT + GUI
		_quickSwapCount = 0;
		enabledQuickSwapCount = COUNT_TYPE_QUICKSWAP_ALT_GUI;
	}else{		
		enabledQuickSwapCount = 0;
	}

	prevModifier = xModi;

}
예제 #2
0
static void applyQuickSwap(void) {
	static uint8_t prevModifier = 0;

	if(getDownBufferAt(0) > 0){
		enabledQuickSwapCount = 0;
		return;
	}
	
	uint8_t gModi = getModifierDownBuffer();

	if(gModi != prevModifier) {

        if(gModi == (MODI_RSHIFT|MODI_LALT|MODI_LGUI) || gModi == (MODI_RSHIFT|MODI_RALT|MODI_RGUI) || gModi == (MODI_RSHIFT|MODI_LALT|MODI_RGUI) || gModi == (MODI_RSHIFT|MODI_LALT|MODI_LGUI)){	// ALT + GUI + R SHIFT
            _quickSwapCount = 0;
            enabledQuickSwapCount = COUNT_TYPE_QUICKSWAP_ALT_GUI;
        }else{
            enabledQuickSwapCount = 0;
        }

        prevModifier = gModi;

    }

//}
//static void countQuickSwapEnabled(void){
	if(enabledQuickSwapCount && ++_quickSwapCount > quickSwapCountMax){
		if(enabledQuickSwapCount == COUNT_TYPE_QUICKSWAP_ALT_GUI){
			blinkOnce(50);
			if((quickSwapMode & QUICKSWAP_ALT_GUI) == QUICKSWAP_ALT_GUI){			
				quickSwapMode &= ~QUICKSWAP_ALT_GUI;
			}else{
				quickSwapMode |= QUICKSWAP_ALT_GUI;		
				_delay_ms(50);
				blinkOnce(100);
			}
		}		
		eeprom_update_byte((uint8_t *)EEPROM_QUICK_SWAP, quickSwapMode);
		enabledQuickSwapCount = 0;
	}

}
예제 #3
0
/**
 * Main function, containing the main loop that manages timer- and
 * USB-functionality.
 * /return the obligatory integer that nobody cares about...
 */
void usb_main(void) {

    // USB Reset by device only required on Watchdog Reset         
    P2U_PS2_PORT &= ~((1 << P2U_PS2_CLOCK_PIN)|(1 << P2U_PS2_DATA_PIN)); // input:tri-state     output:low                 
    P2U_USB_CFG_DDR &= ~((1 << P2U_USB_CFG_DPLUS_BIT)|(1 << P2U_USB_CFG_DMINUS_BIT));// input, remove USB reset condition
    
    // configure timer 0 for a rate of 12M/(1024 * 256) = 45.78Hz (~22ms)
    //TCCR0 |= (1<<CS02)|(1<<CS00);          // timer 0 prescaler: 1024
//    TCCR0 &= ~((1<<CS02)|(1<<CS01)|(1<<CS00));    // timer stop

    usbInit();

    uint8_t idleCounter = 0;

    uchar   i = 0;
    usbDeviceDisconnect();  /* do this while interrupts are disabled */
    do{             /* fake USB disconnect for > 250 ms */
        // wdt_reset();
        _delay_ms(1);
    }while(--i);
    usbDeviceConnect();

    // init
    setKeyScanDriver(&driverKeyScanUsb);
    setUpdateDriver(&updateUsb);
    clearReportBuffer();

    sei();

#if USB_COUNT_SOF    
    bool _isSuspended = false;
    int suspendCount = 0;
#endif

    for(;;){


#ifndef INTERFACE_ONLY_USB
        // 카운트 이내에 신호가 잡히지 않으면 이동;
        // 특별한 경우에만 발생하는 현상이다.
        if(INTERFACE == INTERFACE_USB && interfaceReady == false && interfaceCount++ > 3000){
            // move to ps/2
            INTERFACE = INTERFACE_PS2;
            DBG1(0x88, 0, 0);
            break;
        }
#endif

#if USB_COUNT_SOF
        if (usbSofCount != 0) {
//      DBG1(0x55, (uchar *)&usbSofCount, 1);
            _isSuspended = false;
            usbSofCount = 0;
            suspendCount = 0;
            _usbReset = false;

            wakeUp();

        } else if(_usbReset == true){
//            DBG1(0x56, (uchar *)&usbSofCount, 1);
            _isSuspended = false;
            usbSofCount = 1;
            wakeUp();

        }else{
            // Suspend when no SOF in 3ms-10ms(7.1.7.4 Suspending of USB1.1)
            if (_isSuspended == false && suspendCount++ > 10000 && getModifierDownBuffer() == 0 && getDownBufferAt(0) == 0) {
//                DBG1(0x5a, (uchar *)&usbSofCount, 2);
                _isSuspended = true;

                sleep();
            }
        }
#endif

        // main event loop
        usbPoll();

#if USB_COUNT_SOF 
        /*if(_isSuspended == true) {
            continue;
        }*/
#endif

        // check timer if we need periodic reports
        if (TIFR & (1 << TOV0)) {
            TIFR = (1 << TOV0); // reset flag
            if (idleRate != 0) { // do we need periodic reports?
                if(idleCounter > 4){ // yes, but not yet
                    idleCounter -= 5; // 22ms in units of 4ms
                } else { // yes, it is time now
                    updateNeeded = 1;
                    idleCounter = idleRate;
                }
            }
        }

        // if an update is needed, send the report
        if (usbInterruptIsReady()) {

            scanKeyUsbWithMacro(); // changes?

            // ps2avrU loop, must be after scan matrix;
            enterFrame();

            if(updateNeeded){
                if(interfaceReady==false) continue;

                memset(reportKeyboard, 0, REPORT_SIZE_KEYBOARD);
                reportKeyboard[0] = _modifiers;
                reportKeyboard[1] = 0;
                memcpy ( reportKeyboard+2, reportBuffer, strlen((char *)reportBuffer) );
                // DBG1(0x06, (uchar *)&reportKeyboard[0], 1);
                usbSetInterrupt((void *)&reportKeyboard, sizeof(reportKeyboard));
                updateNeeded = 0;
#if !USB_COUNT_SOF
                wakeUpUsb();
#endif

            }else if(_initState == INIT_INDEX_SET_IDLE){
            	DBG1(0x99, (uchar *)&_initState, 1);

                _initState = INIT_INDEX_INITED;

                // 재부팅시 첫키 입력 오류를 방지하기 위해서 HID init 후 all release 전송;
                memset(reportKeyboard, 0, REPORT_SIZE_KEYBOARD);
                usbSetInterrupt((void *)&reportKeyboard, sizeof(reportKeyboard));
                clearMatrix();
#if !USB_COUNT_SOF
                wakeUpUsb();
#endif

                // 플러깅 후 출력되는 메세지는 넘락등 LED가 반응한 후에 보여진다.
                // usbInterruptIsReady() 일지라도 LED 반응 전에는 출력이 되지 않는다.
                // LED 반응 후에 처리하려고 하면 MAC OS에서 실행되지 않는다.
                // (MAC OS에서는 플러깅 시 LED가 반응하지 않는다. 대신 바로 출력이 된다.)
                // for os x
                if(idleRate > 0) {
                    startKeyMappingOnBoot();
                }

//                DBG1(0xAA, (uchar *)&idleRate, 1);

            }else if(_ledInitState == INIT_INDEX_INITED){
                _ledInitState = INIT_INDEX_COMPLETE;
                // for windows
                if(idleRate == 0) {
                    startKeyMappingOnBoot();
                }

            }
        }

        if(usbInterruptIsReady3()){
            if(_extraHasChanged){
                report_extra_t gReportExtra = {
                    .report_id = REPORT_ID_CONSUMER,
                    .usage = extraData
                };
                usbSetInterrupt3((void *)&gReportExtra, sizeof(gReportExtra));
                _extraHasChanged = false;
#if !USB_COUNT_SOF
                wakeUpUsb();
#endif
            }
            if(_systemHasChanged){
                report_extra_t gReportExtra = {
                    .report_id = REPORT_ID_SYSTEM,
                    .usage = systemData
                };
                usbSetInterrupt3((void *)&gReportExtra, sizeof(gReportExtra));
                _systemHasChanged = false;
#if !USB_COUNT_SOF
                wakeUpUsb();
#endif
            }
        }

        if(_initState == INIT_INDEX_INITED){
            if(initCount++ == 200){       // delay for OS X USB multi device
                // all platform init led
                initAfterInterfaceMount();
            }else if(initCount > 200){
                initCount = 201;
                _initState = INIT_INDEX_COMPLETE;
            }
        }

#if !USB_COUNT_SOF
        // 입력이 한동안 없으면 슬립모드로;
        countSleepUsb();
#endif

    }

#ifndef INTERFACE_ONLY_USB
    // data line reset;
    USB_INTR_ENABLE &= ~(1 << USB_INTR_ENABLE_BIT);
#endif

}