/** * 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 */ uint8_t usbFunctionSetup(uint8_t data[8]) { delegateInterfaceReadyUsb(); 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) { // wValue: ReportType (highbyte), ReportID (lowbyte) // we only have one report type, so don't look at wValue usbMsgPtr = (usbMsgPtr_t)&reportKeyboard; return sizeof(reportKeyboard); } else if (rq->bRequest == USBRQ_HID_SET_REPORT) { // DBG1(0xAA, data, 8); // Report Type: 0x02(Out)/ReportID: 0x00(none) && Interface: 0(keyboard) if (rq->wValue.word == 0x0200 && rq->wIndex.word == 0) { // We expect one byte reports expectReport = 1; return 0xff; // Call usbFunctionWrite with data } } else if (rq->bRequest == USBRQ_HID_GET_IDLE) { usbMsgPtr = idleRate; return 1; } else if (rq->bRequest == USBRQ_HID_SET_IDLE) { delegateInitInterfaceUsb(); idleRate = rq->wValue.bytes[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; }
/** * 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; }
/** * 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(); 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 == LED2_GET_REPORT_LENGTH_RAINBOW){ // ready for rainbow color setting; readyForRainbowColor = 1; } // // boot // static uchar optionsBuffer[0x84]; // // memset(optionsBuffer, 0, 0x83); // optionsBuffer[0] = REPORT_ID_BOOT; // LED options // /* LED options */ // optionsBuffer[0x83] = 0x84; // usbMsgPtr = (usbMsgPtr_t)optionsBuffer; // return sizeof(optionsBuffer); }else if(rq->wValue.word == HID_REPORT_OPTION){ // length : rq->wLength.word 필요한 리포트를 length로 구분한다. uint8_t k, j, i = 0; static uchar led2Buffer[CUSTOM_MACRO_SIZE_MAX]; if(rq->wLength.word == LED2_GET_REPORT_LENGTH_INFO){ // report led2 info getLed2((led2_info_t *)led2Buffer); usbMsgPtr = (usbMsgPtr_t)led2Buffer; return LED2_GET_REPORT_LENGTH_INFO; //sizeof(led2Buffer); }else if(rq->wLength.word >= LED2_GET_REPORT_LENGTH_KEYMAP_LAYER1 && rq->wLength.word <= LED2_GET_REPORT_LENGTH_KEYMAP_LAYER4){ // keymap for(k = 0; k < ROWS; ++k){ for (j = 0; j < COLUMNS; ++j) { led2Buffer[i++] = pgm_read_byte(KEYMAP_ADDRESS+(ROWS * COLUMNS * (rq->wLength.word - LED2_GET_REPORT_LENGTH_KEYMAP_LAYER1))+(k * COLUMNS + j)); } } // DBG1(0x89, led2Buffer, 120); usbMsgPtr = (usbMsgPtr_t)led2Buffer; return LED2_GET_REPORT_LENGTH_KEYMAP; }else if(rq->wLength.word >= LED2_GET_REPORT_LENGTH_MACRO1 && rq->wLength.word <= LED2_GET_REPORT_LENGTH_MACRO12){ // cst macro for(k = 0; k < CUSTOM_MACRO_SIZE_MAX; ++k){ led2Buffer[i++] = pgm_read_byte(CUSTOM_MACRO_ADDRESS+(CUSTOM_MACRO_SIZE_MAX * (rq->wLength.word - LED2_GET_REPORT_LENGTH_MACRO1))+(k)); } usbMsgPtr = (usbMsgPtr_t)led2Buffer; return CUSTOM_MACRO_SIZE_MAX; }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(readyForRainbowColor==1){ data[1] = LED2_INDEX_COLOR_RAINBOW_INIT; setLed2((uint8_t *)data); expectReport = 4; }else{ expectReport = 3; } readyForRainbowColor = 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; return 1; } else if (rq->bRequest == USBRQ_HID_SET_IDLE) { delegateInitInterfaceUsb(); idleRate = rq->wValue.bytes[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; }