Exemplo n.º 1
0
static void initPs2(void)
{
    if(interfaceReady == false){
        interfaceReady = true;

        initAfterInterfaceMount();

        startKeyMappingOnBoot();
    }
} 
Exemplo n.º 2
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

    usbInit();

    int interfaceCount = 0;

    if( eeprom_read_byte((uint8_t *)EEPROM_USB_COMPATIBILITY) == 0x00 )
    {
        usbDeviceDisconnect();  /* do this while interrupts are disabled */
        uchar   i = 0;
        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(;;){

        /*
         * USB3.0 + win10의 경우 usbDeviceConnect() 딜레이가 있으면 일부 장치에서 인식이 되지않아 이를 제거
         * 하지만, 구식 부트로더 (ps2avrGB_bootloader_140623)의 경우 빠져나올 때 usbDeviceDisconnect()를 처리하지 않아서
         * 이를 여기서 처리해줌.
         */
        if(interfaceReady == false && interfaceCount++ > 1000)
        {
            cli();

            usbDeviceDisconnect();
            wdt_enable(WDTO_15MS);
            for(;;);
        }

#if USB_COUNT_SOF
        if (usbSofCount != 0) {
            _isSuspended = false;
            usbSofCount = 0;
            suspendCount = 0;
            _usbReset = false;

            wakeUp();

        } else if(_usbReset == true){
            _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++ > 1000 && isReleaseAll()) {
                _isSuspended = true;

                sleep();
            }
        }
#endif

        // main event loop
        usbPoll();

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

            scanKeyUsbWithMacro(); // changes?

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

#if USB_COUNT_SOF
                if(_isSuspended == true) {
                    wake_up_signal();
                    updateNeeded = 0;
                    continue;
                }
#endif

                memset(reportKeyboard, 0, REPORT_SIZE_KEYBOARD);

                reportKeyboard[0] = _modifiers;
                reportKeyboard[1] = 0;
                memcpy ( reportKeyboard+2, reportBuffer, _countOfBuffer ); //strlen((char *)reportBuffer) );
//                DBG1(0x06, (uchar *)&reportKeyboard, 8);

                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

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

            }else if(_ledInitState == INIT_LED_INDEX_INITED){
                _ledInitState = INIT_LED_INDEX_COMPLETE;
                // for windows

            }

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

        }

#if !defined( USING_SIMPLE_MODE )
        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
            }
        }
#endif

        if(_initState == INIT_INDEX_INITED){
            if(initCount++ == 200){       // delay for OS X USB multi device
                // all platform init led
                initAfterInterfaceMount();
//                DBG1(0xAB, (uchar *)&initCount, 2);
            }else if(initCount > 200){
                initCount = 201;
                _initState = INIT_INDEX_COMPLETE;
            }
        }

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

    }

/*
#if !defined(INTERFACE_ONLY_USB)
    // data line reset;
    USB_INTR_ENABLE &= ~(1 << USB_INTR_ENABLE_BIT);
#endif
*/

}
Exemplo n.º 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

}