#include "gamepad.h" #include "tusb.h" #include "class/hid/hid.h" #define INPUT_ELEMENT_NAME_LENGTH 30 struct input_element_t create_input_element( uint16_t first_bit_position, uint16_t mask, char name[]){ struct input_element_t input_element; input_element.first_bit_position = first_bit_position; input_element.mask = mask; if(strlen(name) > INPUT_ELEMENT_NAME_LENGTH - 1){ strcpy(input_element.name, name); }else{ strcpy(input_element.name, "Too long"); } return input_element; } struct gamepad_configuration_t create_8bitpro_configuration(uint8_t dev_addr, uint8_t instance){ struct gamepad_configuration_t gamepad_configuration; gamepad_configuration.dev_addr = dev_addr; gamepad_configuration.instance = instance; gamepad_configuration.report_id = 0x01; } uint8_t create_gamepad_configuration(uint8_t dev_addr, uint8_t instance, uint8_t const* desc_report, uint16_t desc_len) { // Report Item 6.2.2.2 USB HID 1.11 union TU_ATTR_PACKED { uint8_t byte; struct TU_ATTR_PACKED { uint8_t size : 2; uint8_t type : 2; uint8_t tag : 4; }; } header; // current parsed report count & size from descriptor // uint8_t ri_report_count = 0; // uint8_t ri_report_size = 0; uint8_t ri_collection_depth = 0; while (desc_len) { header.byte = *desc_report++; desc_len--; uint8_t const tag = header.tag; uint8_t const type = header.type; uint8_t const size = header.size; uint8_t const data8 = desc_report[0]; TU_LOG(2, "tag = %d, type = %d, size = %d, data = ", tag, type, size); for (uint32_t i = 0; i < size; i++) { TU_LOG(2, "%02X ", desc_report[i]); } TU_LOG(2, "\r\n"); switch (type) { case RI_TYPE_MAIN: switch (tag) { case RI_MAIN_INPUT: break; case RI_MAIN_OUTPUT: break; case RI_MAIN_FEATURE: break; case RI_MAIN_COLLECTION: ri_collection_depth++; break; case RI_MAIN_COLLECTION_END: ri_collection_depth--; if (ri_collection_depth == 0) { // Fin de collection } break; default:break; } break; case RI_TYPE_GLOBAL: switch (tag) { case RI_GLOBAL_USAGE_PAGE: // only take in account the "usage page" before REPORT ID if (ri_collection_depth == 0) { } break; case RI_GLOBAL_LOGICAL_MIN: break; case RI_GLOBAL_LOGICAL_MAX: break; case RI_GLOBAL_PHYSICAL_MIN: break; case RI_GLOBAL_PHYSICAL_MAX: break; case RI_GLOBAL_REPORT_ID: //info->report_id = data8; break; case RI_GLOBAL_REPORT_SIZE: // ri_report_size = data8; break; case RI_GLOBAL_REPORT_COUNT: // ri_report_count = data8; break; case RI_GLOBAL_UNIT_EXPONENT: break; case RI_GLOBAL_UNIT: break; case RI_GLOBAL_PUSH: break; case RI_GLOBAL_POP: break; default: break; } break; case RI_TYPE_LOCAL: switch (tag) { case RI_LOCAL_USAGE: // only take in account the "usage" before starting REPORT ID //if (ri_collection_depth == 0) info->usage = data8; break; case RI_LOCAL_USAGE_MIN: break; case RI_LOCAL_USAGE_MAX: break; case RI_LOCAL_DESIGNATOR_INDEX: break; case RI_LOCAL_DESIGNATOR_MIN: break; case RI_LOCAL_DESIGNATOR_MAX: break; case RI_LOCAL_STRING_INDEX: break; case RI_LOCAL_STRING_MIN: break; case RI_LOCAL_STRING_MAX: break; case RI_LOCAL_DELIMITER: break; default: break; } break; // error default: break; } desc_report += size; desc_len -= size; } /*for (uint8_t i = 0; i < report_num; i++) { info = report_info_arr + i; TU_LOG_DRV("%u: id = %u, usage_page = %u, usage = %u\r\n", i, info->report_id, info->usage_page, info->usage); }*/ //return report_num; return 0; }