diff --git a/CMakeLists.txt b/CMakeLists.txt index b55ba65..b348907 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -22,6 +22,7 @@ target_sources(host_cdc_msc_hid PUBLIC cdc_app.c diskio_USB.c diskio_SDIO.c + gamepad.c lib/FatFs/source/ff.c lib/FatFs/source/ffsystem.c lib/FatFs/source/diskio.c @@ -75,3 +76,5 @@ add_custom_target(Flash DEPENDS host_cdc_msc_hid COMMAND sudo picotool load -f ${PROJECT_BINARY_DIR}/host_cdc_msc_hid.uf2 ) + +add_definitions(-DPICO_STDIO_ENABLE_CRLF_SUPPORT=0) diff --git a/gamepad.c b/gamepad.c new file mode 100644 index 0000000..4525185 --- /dev/null +++ b/gamepad.c @@ -0,0 +1,158 @@ +#include "gamepad.h" +#include "tusb.h" +#include "class/hid/hid.h" + +#define INPUT_ELEMENT_NAME_LENGTH 30 + +struct input_element_t{ + uint16_t first_bit_position; + uint16_t mask; + char name[INPUT_ELEMENT_NAME_LENGTH]; +}; + +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; +} \ No newline at end of file diff --git a/gamepad.h b/gamepad.h new file mode 100644 index 0000000..f0d4278 --- /dev/null +++ b/gamepad.h @@ -0,0 +1,17 @@ +#include + +struct input_element_t{ + uint16_t first_bit_position; + uint16_t mask; + char name[30]; +}; + +struct gamepad_configuration_t{ + uint8_t dev_addr; + uint8_t instance; + uint8_t report_id; + struct input_element_t input_elements[30]; +}; + +uint8_t create_gamepad_configuration(uint8_t dev_addr, uint8_t instance, + uint8_t const* desc_report, uint16_t desc_len); \ No newline at end of file diff --git a/hid_app.c b/hid_app.c index 7d62514..effaf6d 100644 --- a/hid_app.c +++ b/hid_app.c @@ -24,6 +24,7 @@ */ #include "bsp/board_api.h" +#include "gamepad.h" #include "tusb.h" //--------------------------------------------------------------------+ @@ -53,7 +54,7 @@ static void process_generic_report(uint8_t dev_addr, uint8_t instance, uint8_t c typedef struct TU_ATTR_PACKED { - uint8_t dummy; + uint8_t report_id; uint8_t x, y, z, rz; // joystick uint hat_switch:4; @@ -98,6 +99,7 @@ void tuh_hid_mount_cb(uint8_t dev_addr, uint8_t instance, uint8_t const* desc_re { printf("HID device address = %d, instance = %d is mounted\r\n", dev_addr, instance); + // Interface protocol (hid_interface_protocol_enum_t) const char* protocol_str[] = { "None", "Keyboard", "Mouse" }; uint8_t const itf_protocol = tuh_hid_interface_protocol(dev_addr, instance); @@ -115,13 +117,17 @@ void tuh_hid_mount_cb(uint8_t dev_addr, uint8_t instance, uint8_t const* desc_re hid_info[instance].report_count = tuh_hid_parse_report_descriptor(hid_info[instance].report_info, MAX_REPORT, desc_report, desc_len); printf("HID has %u reports \r\n", hid_info[instance].report_count); - if(hid_info[instance].report_count == 0){ - printf("desc_len:%d\n", desc_len); - for(int i=0; i<10; i++){ - printf("+ 0x%X 0x%X\n", desc_report[i*2], desc_report[i*2+1]); + + for(int i=0; i< hid_info[instance].report_count; i++){ + if(hid_info[instance].report_info->usage == 5 && + hid_info[instance].report_info->usage_page == 1){ + printf("Found Gamepad descriptor\n"); + create_gamepad_configuration(dev_addr, instance, desc_report, desc_len); + } - printf("\n"); + } + } // request to receive report @@ -157,9 +163,9 @@ void tuh_hid_report_received_cb(uint8_t dev_addr, uint8_t instance, uint8_t cons default: // Generic report requires matching ReportID and contents with previous parsed report info - printf("Generic report recieved\n"); + // printf("Generic report recieved\n"); - process_generic_report(dev_addr, instance, report, len); + // process_generic_report(dev_addr, instance, report, len); break; } @@ -372,7 +378,15 @@ static void process_generic_report(uint8_t dev_addr, uint8_t instance, uint8_t c process_mouse_report( (hid_mouse_report_t const*) report ); break; + case HID_USAGE_DESKTOP_GAMEPAD: + + break; + default: break; } } } + +void process_gamepad_report(){ + +} diff --git a/tusb_config.h b/tusb_config.h index a59a0ff..9f60c1a 100644 --- a/tusb_config.h +++ b/tusb_config.h @@ -99,7 +99,7 @@ //-------------------------------------------------------------------- // Size of buffer to hold descriptors and other data used for enumeration -#define CFG_TUH_ENUMERATION_BUFSIZE 256 +#define CFG_TUH_ENUMERATION_BUFSIZE 512 #define CFG_TUH_HUB 1 // number of supported hubs #define CFG_TUH_CDC 1 // CDC ACM