uint8_t process_MouseReport(USB_MouseRelReport_Data_t* MouseReport, uint16_t* const ReportSize) #endif { int16_t param; if (!keys_in_InBuf(&input_mouse)) return false; // if no requests: leave #ifdef _USE_ABS_MOUSEPOINTER_ *ReportSize = sizeof(USB_MouseAbsReport_Data_t); #else *ReportSize = sizeof(USB_MouseRelReport_Data_t); #endif switch (read_InBuf(&input_mouse)) { // requested feature case HID_CIM_FEATURE_MOUSEPOS_XY: // get x/y mousepos from ringbuf and create HID report ! #ifdef _USE_ABS_MOUSEPOINTER_ MouseReport->X =(uint16_t)read_InBuf(&input_mouse); // X-Pos low byte MouseReport->X+=((uint16_t)read_InBuf(&input_mouse))<<8; // X-Pos high byte MouseReport->Y =(uint16_t)read_InBuf(&input_mouse); // Y-Pos low byte MouseReport->Y+=((uint16_t)read_InBuf(&input_mouse))<<8; // Y-Pos high byte #else param=read_InBuf(&input_mouse); // X-Pos low byte param+=((int16_t)read_InBuf(&input_mouse))<<8; // X-Pos high byte MouseReport->X = param; param=read_InBuf(&input_mouse); // Y-Pos low byte param+=((int16_t)read_InBuf(&input_mouse))<<8; // Y-Pos high byte MouseReport->Y = param; #endif MouseReport->Button=mouse_button_saved; return(true); case HID_CIM_FEATURE_MOUSEBUTTONSTATE: // get mouse-buttonstate from ringbuffer and create HID report ! MouseReport->Button=read_InBuf(&input_mouse); // buttonstate byte mouse_button_saved=MouseReport->Button; return(true); case HID_CIM_FEATURE_MOUSEWHEEL: // get mouse-wheel change from ringbuffer and create HID report ! MouseReport->Wheel=(int8_t)read_InBuf(&input_mouse); // buttonstate byte return(true); } return(false); }
uint8_t process_JoystickReport(USB_JoystickReport_Data_t* JoystickReport, uint16_t* const ReportSize) { int16_t param; if (!keys_in_InBuf(&input_joystick)) return false; // if no requests: leave *ReportSize = sizeof(USB_JoystickReport_Data_t); switch (read_InBuf(&input_joystick)) { // requested feature case HID_CIM_FEATURE_JOY1POSANALOG: param=read_InBuf(&input_joystick); // X-Pos low byte param+=((int16_t)read_InBuf(&input_joystick))<<8; // X-Pos high byte JoystickReport->X = param; param=read_InBuf(&input_joystick); // Y-Pos low byte param+=((int16_t)read_InBuf(&input_joystick))<<8; // Y-Pos high byte JoystickReport->Y = param; joy_x_saved =JoystickReport->X; joy_y_saved =JoystickReport->Y; JoystickReport->Button = joy_button_saved; return(true); // TODO: implement features for 2nd and 3rd Joystick if necessary case HID_CIM_FEATURE_JOYBUTTONSTATE: param=read_InBuf(&input_joystick); // buttonstate low byte JoystickReport->Button = param; param=read_InBuf(&input_joystick); // buttonstate high byte // (TODO: include high byte into HID report) joy_button_saved=JoystickReport->Button; JoystickReport->X = joy_x_saved; JoystickReport->Y = joy_y_saved; return(true); } return(false); }
uint8_t process_KeyboardReport(USB_KeyboardReport_Data_t* KeyboardReport, uint16_t* const ReportSize) { static char release_last =0; static uint8_t hold_keys =0; static uint8_t modifiers[6]; static uint8_t keys[6]; uint8_t i; uint8_t act_key; if (release_last) { // handle pending key release immediately release_last=0; if (hold_keys) hold_keys--; KeyboardReport->KeyCode[hold_keys] = 0; modifiers[hold_keys]=0; KeyboardReport->Modifier=0; for (i=0;i<hold_keys;i++) { KeyboardReport->KeyCode[i] = keys[i]; KeyboardReport->Modifier |= modifiers[i]; } *ReportSize = sizeof(USB_KeyboardReport_Data_t); return true; } if (!keys_in_InBuf(&input_keyboard)) return false; // if no requests: leave *ReportSize = sizeof(USB_KeyboardReport_Data_t); switch (read_InBuf(&input_keyboard)) { // requested feature case HID_CIM_FEATURE_KEYPRESS: // get keycode and modifier from ringbuffer and create HID report ! if (hold_keys<6) { keys[hold_keys]=read_InBuf(&input_keyboard); modifiers[hold_keys] = read_InBuf(&input_keyboard); hold_keys++; KeyboardReport->Modifier=0; for (i=0;i<hold_keys;i++) { KeyboardReport->KeyCode[i] = keys[i]; KeyboardReport->Modifier |= modifiers[i]; } release_last=1; return(true); } case HID_CIM_FEATURE_KEYHOLD: if (hold_keys<6) { keys[hold_keys]=read_InBuf(&input_keyboard); modifiers[hold_keys] = read_InBuf(&input_keyboard); hold_keys++; KeyboardReport->Modifier=0; for (i=0;i<hold_keys;i++) { KeyboardReport->KeyCode[i] = keys[i]; KeyboardReport->Modifier |= modifiers[i]; } return(true); } case HID_CIM_FEATURE_KEYRELEASE: if (hold_keys) { act_key=read_InBuf(&input_keyboard); read_InBuf(&input_keyboard); // dummy-read modifier for (i=0;i<hold_keys;i++) { if (keys[i]==act_key) { while (i<hold_keys-1) { keys[i]=keys[i+1]; modifiers[i]=modifiers[i+1]; i++; } hold_keys--; KeyboardReport->KeyCode[hold_keys] = 0; modifiers[hold_keys]=0; } } KeyboardReport->Modifier=0; for (i=0;i<hold_keys;i++) { KeyboardReport->KeyCode[i] = keys[i]; KeyboardReport->Modifier |= modifiers[i]; } *ReportSize = sizeof(USB_KeyboardReport_Data_t); } return(true); } return(false); }
//void parse_CIM_protocol(unsigned char actbyte) void parse_CIM_protocol(void) { uint32_t checksum=0; static uint8_t transmission_mode; static uint8_t reply_status_code; static uint8_t last_serial; uint8_t actbyte; while (keys_in_InBuf(&uart_in)) { actbyte=read_InBuf(&uart_in); switch (readstate) { case 0: // first sync byte reply_status_code=0; if (actbyte=='@') readstate++; break; case 1: // second sync byte if (actbyte=='T') readstate++; else readstate=0; break; // packet in sync ! case 2: // ARE-ID: SW-version low byte ARE_frame.are_id=actbyte; readstate++; break; case 3: // ARE-ID: SW-version high byte ARE_frame.are_id+=((uint16_t)actbyte)<<8; if (ARE_frame.are_id < ARE_MINIMAL_VERSION) // outdated ARE ? reply_status_code |= CIM_ERROR_INVALID_ARE_VERSION; readstate++; break; case 4: // data length low byte ARE_frame.data_size=actbyte; readstate++; break; case 5: // data length high byte ARE_frame.data_size+=((uint16_t)actbyte)<<8; if (ARE_frame.data_size > DATABUF_SIZE) { // dismiss packets of excessive length readstate=0; //ARE_frame.data_size=0; //reply_status_code |= CIM_ERROR_INVALID_FEATURE; } else readstate++; break; case 6: // serial_number ARE_frame.serial_number = actbyte; if (first_packet) // don't check first serial first_packet=0; else if (actbyte != (last_serial+1)%0x80) // check current serial number reply_status_code |= CIM_ERROR_LOST_PACKETS; last_serial=actbyte; readstate++; break; case 7: // CIM-feature low byte ARE_frame.cim_feature= actbyte; readstate++; break; case 8: // CIM-feature high byte ARE_frame.cim_feature+=((int)actbyte)<<8; readstate++; break; case 9: // Request code low byte ( command ) ARE_frame.request_code=actbyte; readstate++; break; case 10:// Request code high byte (transmission mode) transmission_mode=actbyte; // bit 0: CRC enable // reply_status_code|=(actbyte & CIM_STATUS_CRC); // remember CRC state for reply if (ARE_frame.data_size>0) { readstate++; datapos=0; } else { // no data in packet if (transmission_mode & CIM_STATUS_CRC) readstate+=2; // proceed with CRC else readstate=FRAME_DONE; // frame is finished here ! } break; case 11: // read out data ARE_frame.data[datapos]=actbyte; datapos++; if (datapos==ARE_frame.data_size) { if (transmission_mode & CIM_STATUS_CRC) // with CRC: get checksum readstate++; else readstate=FRAME_DONE; // no CRC: frame is finished here ! } break; case 12: // checksum byte 1 checksum=actbyte; readstate++; break; case 13: // checksum byte 2 checksum+=((long)actbyte)<<8; readstate++; break; case 14: // checksum byte 3 checksum+=((long)actbyte)<<16; readstate++; break; case 15: // checksum byte 4 checksum+=((long)actbyte)<<24; // check CRC now (currently not used): // if (checksum != crc32(ARE_frame.data, ARE_frame.data_size)) reply_status_code |= CIM_ERROR_CRC_MISMATCH; // frame finished here ! readstate=FRAME_DONE; break; default: readstate=0; break; } if (readstate==FRAME_DONE) { // frame finished: store command in ringbuffer process_ARE_frame(reply_status_code); readstate=0; } } }