Пример #1
0
/**
 * The write function is called when LEDs should be set. Normally, we get only
 * one byte that contains info about the LED states.
 * \param data pointer to received data
 * \param len number ob bytes received
 * \return 0x01
 */
uint8_t usbFunctionWrite(uchar *data, uchar len) {
//    DBG1(0xBB, (uchar *)&len, 1);
    if (expectReport == 1 && (len == 1)) {
        // change LEDs of indicator
        delegateLedUsb(data[0]);
        expectReport = 0;
    }else if (expectReport == 2){   // options
        DBG1(0xEE, data, len);
        // start bootloader
        if(data[1] == OPTION_INDEX_BOOTLOADER && len == 8){
        	if(data[2] == 0xFF){
        		eeprom_write_byte((uint8_t *)EEPROM_BOOTLOADER_START, 0x00);
        	}
        	delegateGotoBootloader();
/* TODO
 * 이전 버전과 호환을 위해 남겨둠
 */
#ifdef ENABLE_BOOTMAPPER
        }else if(data[1] == OPTION_INDEX_BOOTMAPPER){
        	if(data[2] == OPTION_VALUE_BOOTMAPPER_START){
        		setToBootMapper(true);
        	}else{
        		setToBootMapper(false);
        	}
#endif
       /* }else if(data[1] == OPTION_INDEX_READY){
            stopPwmForUsbReport(true);

        }else if(data[1] == OPTION_INDEX_ACTION){
            stopPwmForUsbReport(false);*/
        }else{
        	setOptions((uint8_t *)data);
        }
    }else if (expectReport == 4){
    	// rainbow color setting
    	setOptions((uint8_t *)data);
    }else if (expectReport == 5){
        // write quick macro;
        updateQuickMacro((uint8_t *)data, len);
    }

    return 0x01;
}
Пример #2
0
/**
 * This function is called whenever we receive a setup request via USB.
 * \param data[8] eight bytes of data we received
 * \return number of bytes to use, or 0xff if usbFunctionWrite() should be
 * called
 */
usbMsgLen_t usbFunctionSetup(uint8_t data[8]) {

    delegateInterfaceReadyUsb();

    static uint8_t readyForNext = 0;

    usbRequest_t *rq = (void *)data;
//    DBG1(0xCC, data, 8);

    if ((rq->bmRequestType & USBRQ_TYPE_MASK) == USBRQ_TYPE_CLASS) {
        // class request type
        if (rq->bRequest == USBRQ_HID_GET_REPORT) {
            if (rq->wValue.word == HID_REPORT_KEBOARD)
            {
                // wValue: ReportType (highbyte), ReportID (lowbyte)
                usbMsgPtr = (usbMsgPtr_t)&reportKeyboard;
                return sizeof(reportKeyboard);
            }else if(rq->wValue.word == HID_REPORT_BOOT){

            	if(rq->wLength.word == OPTION_GET_REPORT_LENGTH_RAINBOW){	// ready for rainbow color setting;
            		readyForNext = NEXT_RAINBOW;
            	}else if(rq->wLength.word >= OPTION_GET_REPORT_LENGTH_QUICK_MACRO1 && rq->wLength.word <= OPTION_GET_REPORT_LENGTH_QUICK_MACRO12){
            	    readyForNext = rq->wLength.word;
            	}


            }else if(rq->wValue.word == HID_REPORT_OPTION){
            	// length : rq->wLength.word 필요한 리포트를 length로 구분한다.

            	if(rq->wLength.word == OPTION_GET_REPORT_LENGTH_INFO){
            		// report led2 info
            	    static option_info_t optionsBuffer;
            	    getOptions(&optionsBuffer);
            		usbMsgPtr = (usbMsgPtr_t)&optionsBuffer;
            		return sizeof(optionsBuffer); //OPTION_GET_REPORT_LENGTH_INFO;
            	}else if(rq->wLength.word == OPTION_GET_REPORT_LENGTH_TOGGLE_BOOTMAPPER){
            	    static bool gIsBootloader;
            	    if(isBootMapper()){
                        setToBootMapper(false);
                        gIsBootloader = false;
                    }else{
                        setToBootMapper(true);
                        gIsBootloader = true;
                    }
            	    usbMsgPtr = (usbMsgPtr_t)&gIsBootloader;
            	    return 1;
#if HAS_OPTIONS
            	}else if(rq->wLength.word >= OPTION_GET_REPORT_LENGTH_KEYMAP_LAYER1 && rq->wLength.word <= OPTION_GET_REPORT_LENGTH_KEYMAP_LAYER4){
                    // keymap
                    usbMsgFlags = USB_FLG_MSGPTR_IS_ROM;
                    usbMsgPtr = (usbMsgPtr_t)(KEYMAP_ADDRESS + (ROWS * COLUMNS * (rq->wLength.word - OPTION_GET_REPORT_LENGTH_KEYMAP_LAYER1)));
                    return OPTION_GET_REPORT_LENGTH_KEYMAP;
                }else if(rq->wLength.word >= OPTION_GET_REPORT_LENGTH_MACRO1 && rq->wLength.word <= OPTION_GET_REPORT_LENGTH_MACRO12){
                    // cst macro
                    usbMsgFlags = USB_FLG_MSGPTR_IS_ROM;
                    usbMsgPtr = (usbMsgPtr_t)(CUSTOM_MACRO_ADDRESS+(CUSTOM_MACRO_SIZE_MAX * (rq->wLength.word - OPTION_GET_REPORT_LENGTH_MACRO1)));
                    return CUSTOM_MACRO_SIZE_MAX;

                }else if(rq->wLength.word == OPTION_GET_OPTION_INDEX_DUALACTION){
                    // dual action
                    usbMsgFlags = USB_FLG_MSGPTR_IS_ROM;
                    usbMsgPtr = (usbMsgPtr_t)(DUALACTION_ADDRESS);
                    return DUALACTION_BYTES;

                }else if(rq->wLength.word >= OPTION_GET_REPORT_LENGTH_QUICK_MACRO1 && rq->wLength.word <= OPTION_GET_REPORT_LENGTH_QUICK_MACRO12){
                    usbMsgFlags = USB_FLG_USE_USER_RW;
                    usbMsgPtr = (usbMsgPtr_t)(EEPROM_MACRO+(MACRO_SIZE_MAX * (rq->wLength.word - OPTION_GET_REPORT_LENGTH_QUICK_MACRO1)));
                    return MACRO_SIZE_MAX;
#else
                }else if(rq->wLength.word >= OPTION_GET_REPORT_LENGTH_KEYMAP_LAYER1 && rq->wLength.word <= OPTION_GET_REPORT_LENGTH_KEYMAP_LAYER4){
                    // keymap
                    usbMsgFlags = USB_FLG_MSGPTR_IS_ROM;
                    usbMsgPtr = (usbMsgPtr_t)(KEYMAP_ADDRESS + (ROWS * COLUMNS * (rq->wLength.word - OPTION_GET_REPORT_LENGTH_KEYMAP_LAYER1)));
                    return OPTION_GET_REPORT_LENGTH_KEYMAP;
                }else if(rq->wLength.word >= OPTION_GET_REPORT_LENGTH_MACRO1 && rq->wLength.word <= OPTION_GET_REPORT_LENGTH_MACRO12){
                    // cst macro
                    usbMsgFlags = USB_FLG_MSGPTR_IS_ROM;
                    usbMsgPtr = (usbMsgPtr_t)(CUSTOM_MACRO_ADDRESS+(CUSTOM_MACRO_SIZE_MAX * (rq->wLength.word - OPTION_GET_REPORT_LENGTH_MACRO1)));
                    return CUSTOM_MACRO_SIZE_MAX;

                }else if(rq->wLength.word == OPTION_GET_OPTION_INDEX_DUALACTION){
                    // dual action
                    usbMsgFlags = USB_FLG_MSGPTR_IS_ROM;
                    usbMsgPtr = (usbMsgPtr_t)(DUALACTION_ADDRESS);
                    return DUALACTION_BYTES;

                }else if(rq->wLength.word >= OPTION_GET_REPORT_LENGTH_QUICK_MACRO1 && rq->wLength.word <= OPTION_GET_REPORT_LENGTH_QUICK_MACRO12){
                    usbMsgFlags = USB_FLG_USE_USER_RW;
                    usbMsgPtr = (usbMsgPtr_t)(EEPROM_MACRO+(MACRO_SIZE_MAX * (rq->wLength.word - OPTION_GET_REPORT_LENGTH_QUICK_MACRO1)));
                    return MACRO_SIZE_MAX;

#endif
            	}else {
            		return rq->wLength.word;
            	}
            }
        } else if (rq->bRequest == USBRQ_HID_SET_REPORT) {
//        	DBG1(0xAA, (uchar *)&rq->wValue.word, 2);
        	// 02 03 : Report Type: 0x03,  ReportID: 0x02
        	// 01 03 : Report Type: 0x03,  ReportID: 0x01
            // Report Type: 0x02(Out)/ReportID: 0x00(none) && Interface: 0(keyboard)
            if (rq->wValue.word == HID_REPORT_KEBOARD && rq->wIndex.word == 0)
            {
                // We expect one byte reports
                expectReport = 1;
                return USB_NO_MSG; // Call usbFunctionWrite with data
            }else if(rq->wValue.word == HID_REPORT_BOOT){
                // boot
//                isStart = 1;
                if(readyForNext == NEXT_RAINBOW){
                	data[1] = OPTION_INDEX_COLOR_RAINBOW_INIT;
                	// init setting;
                	setOptions((uint8_t *)data);
                	expectReport = 4;
                }else if(readyForNext >= OPTION_GET_REPORT_LENGTH_QUICK_MACRO1 && readyForNext <= OPTION_GET_REPORT_LENGTH_QUICK_MACRO12){
                    // write quick macro
                    IsAddressHead = true;
                    quickMacroAddress = EEPROM_MACRO + (MACRO_SIZE_MAX * (readyForNext - OPTION_GET_REPORT_LENGTH_QUICK_MACRO1));
                    expectReport = 5;
                }
                readyForNext = 0;

                return USB_NO_MSG; // Call usbFunctionWrite with data
            }else if(rq->wValue.word == HID_REPORT_OPTION){
            	// options
                expectReport = 2;

                return USB_NO_MSG; // Call usbFunctionWrite with data
            }
        } else if (rq->bRequest == USBRQ_HID_GET_IDLE) {
            usbMsgPtr = idleRate;
//            DBG1(0x71, (uchar *)&idleRate, 1);
            return 1;
        } else if (rq->bRequest == USBRQ_HID_SET_IDLE) {

            delegateInitInterfaceUsb();

            idleRate = rq->wValue.bytes[1];
//            DBG1(0x70, (uchar *)&idleRate, 1);

        } else if (rq->bRequest == USBRQ_HID_GET_PROTOCOL) {
            if (rq->wValue.bytes[1] < 1) {
                protocolVer = rq->wValue.bytes[1];
            }
        } else if(rq->bRequest == USBRQ_HID_SET_PROTOCOL) {
            usbMsgPtr = protocolVer;
            return 1;
        }
    } else {        
        // no vendor specific requests implemented
    }

    return 0;
}
Пример #3
0
/**
 * The write function is called when LEDs should be set. Normally, we get only
 * one byte that contains info about the LED states.
 * \param data pointer to received data
 * \param len number ob bytes received
 * \return 0x01
 */
uint8_t usbFunctionWrite(uchar *data, uchar len) {
    DBG1(0xBB, (uchar *)&len, 1);
    if (expectReport == 1 && (len == 1)) {
        delegateLedUsb(data[0]); 
        expectReport = 0;
    }else if (expectReport == 2){   // options
        DBG1(0xEE, data, len);
        // start bootloader
        if(data[1] == OPTION_INDEX_BOOTLOADER && len == 8){
        	if(data[2] == 0xFF){
        		eeprom_write_byte((uint8_t *)EEPROM_BOOTLOADER_START, 0x00);
        	}
        	delegateGotoBootloader();
#ifdef ENABLE_BOOTMAPPER
        }else if(data[1] == OPTION_INDEX_BOOTMAPPER){
        	if(data[2] == OPTION_VALUE_BOOTMAPPER_START){
        		setToBootMapper(true);
        	}else{
        		setToBootMapper(false);
        	}
#endif
        }else if(data[1] == OPTION_INDEX_READY){
        	//stop timer
        	// stop timer1
        	stopFullLed();

        }else if(data[1] == OPTION_INDEX_ACTION){
        	// start timer1
        	startFullLed();

        }else{
        	setLed2((uint8_t *)data);
        }

//        expectReport = 0;
    }else if (expectReport == 4){
    	// rainbow color setting
    	DBG1(0x44, data, len);
        setLed2((uint8_t *)data);
    }else if (expectReport == 3){   // HID_REPORT_BOOT
        DBG1(0xDD, data, len);
        /*
         * 44: 02 10 00 00 00 00 00 00
        44: ff 00 ff 00 ff 00 00 00
        44: 00 00 00 00 00 00 00 00
        44: 00 00 00 00 00 00 00 00
        44: 00 00 00
         */
//        uchar   isLast;
//        static uchar            offset;
//        if(isStart == 1){
//        	isStart = 0;
//			offset = 0;
//			len -= 4;
//		}
//		offset += len;
//		isLast = offset & 0x80; /* != 0 if last block received */
//		DBG1(0xDE, (void *)&isLast, 1);
//		return isLast;

       /* uint8_t gRet;

        gRet = writeFlash(data, len, isStart);
        if(isStart == 1){
            isStart = 0;
        }

        DBG1(0xDF, (uchar *)&gRet, 1);
        return gRet;*/

        /*
         *
         *
         * 여기까지 제대로 실행이 되지만, '커뮤니케이션 에러'가 발생하면서 다음 page로 진행이 되지 않는다.
         * - 일단 page는 저장이 된 상태
         *
         * USB_CFG_SUPPRESS_INTR_CODE 와 USB_CFG_INTR_POLL_INTERVAL 값을 변경해야 통신이 원활히 된다.
         * (아마도 다른 인터럽트를 허용하지 않고 해당 통신만 전담하는 세팅인것 같다.)
         *
         * USB_CFG_INTR_POLL_INTERVAL를 높히면 매크로 출력시 속도가 느리고,
         * USB_CFG_SUPPRESS_INTR_CODE를 1로 설정하면 키보드로 작동을 안한다.
         *
         * 이 둘을 최적화 했다 치더라도, 통신 중(페이지 단위로 쓰기 위해서 8바이트씩 전송되는 데이터를 조합하고 이 페이지를 5개 받는다)에
         * 플래시를 쓰면 커뮤니케이션 에러가 발생하고,
         *
         * 이를 방지하기 위해서 모든 페이지를 메모리에 저장 후 쓰려고 하면, 작동은하지만 메모리가 부족한 현상이 있다.
         *
         *
         *
         *
         * */
    }

    return 0x01;
}