diff --git a/hid_app.c b/hid_app.c index f0d42a0..a7b4576 100644 --- a/hid_app.c +++ b/hid_app.c @@ -24,6 +24,7 @@ */ #include "bsp/board_api.h" +#include "hid_app.h" #include "tusb.h" //--------------------------------------------------------------------+ @@ -43,11 +44,107 @@ static struct { uint8_t report_count; tuh_hid_report_info_t report_info[MAX_REPORT]; + uint16_t vid, pid; }hid_info[CFG_TUH_HID]; + + static void process_kbd_report(hid_keyboard_report_t const *report); static void process_mouse_report(hid_mouse_report_t const * report); static void process_generic_report(uint8_t dev_addr, uint8_t instance, uint8_t const* report, uint16_t len); +struct gamepad_data_t process_8bitpro_report(uint8_t dev_addr, uint8_t instance, uint8_t const* report, uint16_t len); +struct gamepad_data_t process_SonyDualShock4_report(uint8_t dev_addr, uint8_t instance, uint8_t const* report, uint16_t len); +struct gamepad_data_t process_BDA_NSW_report(uint8_t dev_addr, uint8_t instance, uint8_t const* report, uint16_t len); +void affiche_gamepad_data(struct gamepad_data_t _gamepad_report); +void refresh_gamepad_data(struct gamepad_data_t * gamepad_data); + +// HID report from 8bitPro + +typedef struct TU_ATTR_PACKED +{ + uint8_t report_id; + uint b1:1; // Bouton A + uint b2:1; // Bouton B + uint b3:1; // 4 : ??? + uint b4:1; // Bouton X + uint b5:1; // Bouton Y + uint b6:1; // 32 : ??? + uint b7:1; // Bouton L + uint b8:1; // Bouton R + uint b9:1; // Bouton L2 + uint b10:1; // Bouton R2 + uint b11:1; // Start + uint b12:1; // Select + uint b13:1; + uint b14:1; // Click joystick gauche + uint b15:1; // Click joystick droit + uint b16:1; // 16 bits + uint8_t hat_switch; // OK + uint8_t x, y; // joystick Xg, Yg + uint8_t z, rz; // joystick Xd, Yd + + uint8_t gachette_gauche; // ok + uint8_t gachette_droite; // ok + + +} _8bitpro_report_t ; + + +typedef struct TU_ATTR_PACKED +{ + uint8_t report_id; + uint8_t x, y, z, rz; // joystick + uint hat_switch:4; + uint b1:1; + uint b2:1; + uint b3:1; + uint b4:1; + + // 8 bits + uint b5:1; + uint b6:1; + uint b7:1; + uint b8:1; + uint b9:1; + uint b10:1; + uint b11:1; + uint b12:1; // 16 bits + + uint data_1:8; + + uint gachette_gauche:8; + uint gachette_droite:8; + + +} SonyDualShock4_report_t ; + + +typedef struct TU_ATTR_PACKED +{ + uint b1:1; // Bouton Y + uint b2:1; // Bouton B + uint b3:1; // Bouton A + uint b4:1; // Bouton X + uint b5:1; // Bouton L + uint b6:1; // Bouton R + uint b7:1; // Bouton L2 + uint b8:1; // Bouton R2 + uint b9:1; // Bouton - + uint b10:1; // Bouton + + uint b11:1; // Bouton joystick droit + uint b12:1; // Bouton joystick gauche + uint b13:1; // Bouton Start + uint b14:1; // Bouton Select + uint b15:1; // -- + uint b16:1; // -- + uint8_t hat_switch; // OK + uint8_t x, y; // joystick Xg, Yg + uint8_t z, rz; // joystick Xd, Yd + +} BDA_NSW_report_t ; + +struct gamepad_data_t gamepad_data; + void hid_app_task(void) { @@ -67,6 +164,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); @@ -77,8 +175,26 @@ void tuh_hid_mount_cb(uint8_t dev_addr, uint8_t instance, uint8_t const* desc_re // Therefore for this simple example, we only need to parse generic report descriptor (with built-in parser) if ( itf_protocol == HID_ITF_PROTOCOL_NONE ) { + uint16_t vid, pid; + tuh_vid_pid_get(dev_addr, &vid, &pid); + printf("VID = %04x, PID = %04x\r\n", vid, pid); + hid_info[instance].vid = vid; + hid_info[instance].pid = pid; + + 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); + + 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); + + } + + } + } // request to receive report @@ -114,7 +230,16 @@ 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 - process_generic_report(dev_addr, instance, report, len); + // Report - 2dc8:6002 8BitDo 8BitDo SN30 Pro+ + if(hid_info[instance].vid == 0x2dc8 && hid_info[instance].pid == 0x6002){ + gamepad_data = process_8bitpro_report(dev_addr, instance, report, len); + }else if(hid_info[instance].vid == 0x054c && hid_info[instance].pid == 0x05c4){ + gamepad_data = process_SonyDualShock4_report(dev_addr, instance, report, len); + }else if(hid_info[instance].vid == 0x20d6 && hid_info[instance].pid == 0xa713){ + gamepad_data = process_BDA_NSW_report(dev_addr, instance, report, len); + }else{ + process_generic_report(dev_addr, instance, report, len); + } break; } @@ -229,6 +354,113 @@ static void process_mouse_report(hid_mouse_report_t const * report) cursor_movement(report->x, report->y, report->wheel); } +//--------------------------------------------------------------------+ +// Report - 2dc8:6002 8BitDo 8BitDo SN30 Pro+ +//--------------------------------------------------------------------+ +struct gamepad_data_t process_8bitpro_report(uint8_t dev_addr, uint8_t instance, uint8_t const* report, uint16_t len){ + struct gamepad_data_t gamepad_data; + _8bitpro_report_t gamepad_report; + memcpy(&gamepad_report, report, sizeof(gamepad_report)); + refresh_gamepad_data(&gamepad_data); + + // Copie des données du rapport vers la structure standard + gamepad_data.joystick_x_gauche = gamepad_report.x; + gamepad_data.joystick_y_gauche = gamepad_report.y; + gamepad_data.joystick_x_droit = gamepad_report.z; + gamepad_data.joystick_y_droit = gamepad_report.rz; + gamepad_data.bouton_A = gamepad_report.b1; + gamepad_data.bouton_B = gamepad_report.b2; + gamepad_data.bouton_X = gamepad_report.b4; + gamepad_data.bouton_Y = gamepad_report.b5; + gamepad_data.bouton_L = gamepad_report.b7; + gamepad_data.bouton_R = gamepad_report.b8; + gamepad_data.bouton_L2 = gamepad_report.b9; + gamepad_data.bouton_R2 = gamepad_report.b10; + gamepad_data.bouton_Start = gamepad_report.b11; + gamepad_data.bouton_Select = gamepad_report.b12; + gamepad_data.bouton_joystick_gauche = gamepad_report.b15; + gamepad_data.bouton_joystick_droit = gamepad_report.b14; + gamepad_data.dpad = gamepad_report.hat_switch; + gamepad_data.gachette_droite = gamepad_report.gachette_droite; + gamepad_data.gachette_gauche = gamepad_report.gachette_gauche; + + affiche_gamepad_data(gamepad_data); + return gamepad_data; + +} + +//--------------------------------------------------------------------+ +// 054c:05c4 Sony Corp. DualShock 4 [CUH-ZCT1x] +//--------------------------------------------------------------------+ +struct gamepad_data_t process_SonyDualShock4_report(uint8_t dev_addr, uint8_t instance, uint8_t const* report, uint16_t len){ + struct gamepad_data_t gamepad_data; + SonyDualShock4_report_t gamepad_report; + memcpy(&gamepad_report, report, sizeof(gamepad_report)); + refresh_gamepad_data(&gamepad_data); + + // Copie des données du rapport vers la structure standard + gamepad_data.joystick_x_gauche = gamepad_report.x; + gamepad_data.joystick_y_gauche = gamepad_report.y; + gamepad_data.joystick_x_droit = gamepad_report.z; + gamepad_data.joystick_y_droit = gamepad_report.rz; + gamepad_data.bouton_Y = gamepad_report.b4; + gamepad_data.bouton_A = gamepad_report.b3; + gamepad_data.bouton_B = gamepad_report.b2; + gamepad_data.bouton_X = gamepad_report.b1; + gamepad_data.bouton_joystick_droit = gamepad_report.b11; + gamepad_data.bouton_joystick_gauche = gamepad_report.b12; + gamepad_data.bouton_Select = gamepad_report.b10; + gamepad_data.bouton_Start = gamepad_report.b9; + gamepad_data.bouton_R2 = gamepad_report.b8; + gamepad_data.bouton_L2 = gamepad_report.b7; + gamepad_data.bouton_R = gamepad_report.b6; + gamepad_data.bouton_L = gamepad_report.b5; + gamepad_data.dpad = gamepad_report.hat_switch; + gamepad_data.gachette_droite = gamepad_report.gachette_droite; + gamepad_data.gachette_gauche = gamepad_report.gachette_gauche; + + affiche_gamepad_data(gamepad_data); + return gamepad_data; + +} + +//--------------------------------------------------------------------+ +// Report - 20d6:a713 BDA NSW wired controller +//--------------------------------------------------------------------+ +struct gamepad_data_t process_BDA_NSW_report(uint8_t dev_addr, uint8_t instance, uint8_t const* report, uint16_t len){ + struct gamepad_data_t gamepad_data; + BDA_NSW_report_t gamepad_report; + memcpy(&gamepad_report, report, sizeof(gamepad_report)); + refresh_gamepad_data(&gamepad_data); + + // Copie des données du rapport vers la structure standard + gamepad_data.joystick_x_gauche = gamepad_report.x; + gamepad_data.joystick_y_gauche = gamepad_report.y; + gamepad_data.joystick_x_droit = gamepad_report.z; + gamepad_data.joystick_y_droit = gamepad_report.rz; + gamepad_data.bouton_Y = gamepad_report.b1; + gamepad_data.bouton_B = gamepad_report.b2; + gamepad_data.bouton_A = gamepad_report.b3; + gamepad_data.bouton_X = gamepad_report.b4; + gamepad_data.bouton_L = gamepad_report.b5; + gamepad_data.bouton_R = gamepad_report.b6; + gamepad_data.bouton_L2 = gamepad_report.b7; + gamepad_data.bouton_R2 = gamepad_report.b8; + + + gamepad_data.bouton_joystick_gauche = gamepad_report.b12; + gamepad_data.bouton_joystick_droit = gamepad_report.b11; + + gamepad_data.bouton_Start = gamepad_report.b13; + gamepad_data.bouton_Select = gamepad_report.b14; + + gamepad_data.dpad = gamepad_report.hat_switch; + + affiche_gamepad_data(gamepad_data); + return gamepad_data; + +} + //--------------------------------------------------------------------+ // Generic Report //--------------------------------------------------------------------+ @@ -239,6 +471,14 @@ static void process_generic_report(uint8_t dev_addr, uint8_t instance, uint8_t c uint8_t const rpt_count = hid_info[instance].report_count; tuh_hid_report_info_t* rpt_info_arr = hid_info[instance].report_info; tuh_hid_report_info_t* rpt_info = NULL; + + + //printf("HID Report brut\n"); + printf(">a:1\n"); + for(int i=0; i< len; i++){ + printf("0x%X ", report[i]); + } + printf("\n"); if ( rpt_count == 1 && rpt_info_arr[0].report_id == 0) { @@ -292,7 +532,53 @@ 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(){ + +} + +void affiche_gamepad_data(struct gamepad_data_t _gamepad_report){ + printf(">jxd:%d\n", _gamepad_report.joystick_x_gauche); + printf(">jyd:%d\n", _gamepad_report.joystick_y_gauche); + printf(">jxg:%d\n", _gamepad_report.joystick_x_droit); + printf(">jyg:%d\n", _gamepad_report.joystick_y_droit); + printf(">hat:%d\n", _gamepad_report.dpad); + + printf(">ba:%d\n", _gamepad_report.bouton_A); + printf(">bb:%d\n", _gamepad_report.bouton_B); + printf(">bx:%d\n", _gamepad_report.bouton_X); + printf(">by:%d\n", _gamepad_report.bouton_Y); + printf(">bstart:%d\n", _gamepad_report.bouton_Start); + printf(">bselect:%d\n", _gamepad_report.bouton_Select); + printf(">bl:%d\n", _gamepad_report.bouton_L); + printf(">br:%d\n", _gamepad_report.bouton_R); + printf(">bl2:%d\n", _gamepad_report.bouton_L2); + printf(">br2:%d\n", _gamepad_report.bouton_R2); + printf(">bjg:%d\n", _gamepad_report.bouton_joystick_droit); + printf(">bjd:%d\n", _gamepad_report.bouton_joystick_gauche); + + //printf(">data1:%d\n", _gamepad_report.data_1); + + printf(">gd:%d\n", _gamepad_report.gachette_droite); + printf(">gg:%d\n", _gamepad_report.gachette_gauche); +} + +void refresh_gamepad_data(struct gamepad_data_t * gamepad_data){ + gamepad_data->temps_ms = (uint32_t) get_absolute_time() / 1000; +} + +bool gamepad_connecte(){ + return ((get_absolute_time() / 1000) - gamepad_data.temps_ms < 1000); +} + +struct gamepad_data_t get_gamepad_data(){ + return gamepad_data; +} \ No newline at end of file diff --git a/hid_app.h b/hid_app.h new file mode 100644 index 0000000..38775ac --- /dev/null +++ b/hid_app.h @@ -0,0 +1,29 @@ +#include + + +struct gamepad_data_t{ + uint32_t temps_ms; + + uint8_t joystick_x_gauche; + uint8_t joystick_y_gauche; + uint8_t joystick_x_droit; + uint8_t joystick_y_droit; + uint8_t gachette_gauche; + uint8_t gachette_droite; + uint8_t dpad; + bool bouton_A; + bool bouton_B; + bool bouton_X; + bool bouton_Y; + bool bouton_Start; + bool bouton_Select; + bool bouton_L; + bool bouton_L2; + bool bouton_R; + bool bouton_R2; + bool bouton_joystick_gauche; + bool bouton_joystick_droit; +}; + +bool gamepad_connecte(); +struct gamepad_data_t get_gamepad_data(); diff --git a/main.c b/main.c index a391cbc..6220e3b 100644 --- a/main.c +++ b/main.c @@ -36,6 +36,7 @@ #include "com_usb.h" #include "pico/multicore.h" #include "ws2812.h" +#include "hid_app.h" //--------------------------------------------------------------------+ // MACRO CONSTANT TYPEDEF PROTYPES @@ -143,17 +144,19 @@ void core1_functions(){ /*------------- MAIN -------------*/ int main(void) { + board_init(); gpio_set_function(12, UART_FUNCSEL_NUM(uart0, 12)); gpio_set_function(13, UART_FUNCSEL_NUM(uart0, 13)); - printf("TinyUSB Host CDC MSC HID - Logs\r\n"); + printf("TinyUSB Host CDC MSC HID - LED2\r\n"); multicore_launch_core1(core1_functions); - board_init(); + ws2812_init(); ws2812_set_buffer_rgb(2,2,2,0); ws2812_set_buffer_rgb(2,2,2,3); + // Init detection carte SD gpio_init(1); gpio_set_dir(1, GPIO_IN); @@ -186,7 +189,7 @@ int main(void) { ws2812_set_mode(LED_ID_DETECTION, LED_PULSE_RAPIDE, 0x000004); - while(1){ + //while(1){ f = get_absolute_time() / 1000. - start_time; f = f / 1000.; if(f > 1){ @@ -205,7 +208,7 @@ int main(void) { ws2812_set_mode(LED_ID_DETECTION, LED_PULSE_RAPIDE, 0x000004); ws2812_set_mode(LED_ID_DIVERS, LED_STABLE, 0x000004); - sleep_ms(3000); + sleep_ms(1000); ws2812_set_mode(LED_ID_SD_CARD, LED_CLI_RAPIDE, 0x000404); ws2812_set_mode(LED_ID_USB, LED_CLI_NORMAL, 0x000404); @@ -213,7 +216,7 @@ int main(void) { ws2812_set_mode(LED_ID_DETECTION, LED_CLI_PANIQUE_1, 0x000404); ws2812_set_mode(LED_ID_DIVERS, LED_CLI_PANIQUE_2, 0x000404); - sleep_ms(3000); + sleep_ms(1000); ws2812_set_mode(LED_ID_SD_CARD, LED_CLI_PANIQUE_3, 0x040000); ws2812_set_mode(LED_ID_USB, LED_PULSE_RAPIDE, 0x040000); @@ -221,11 +224,10 @@ int main(void) { ws2812_set_mode(LED_ID_DETECTION, LED_PULSE_LENT, 0x040000); ws2812_set_mode(LED_ID_DIVERS, LED_STABLE, 0x040000); - sleep_ms(3000); - + sleep_ms(1000); sleep_ms(1); - } + //} @@ -266,26 +268,17 @@ int main(void) { log_init(drive_path); - //multicore_launch_core1(routine_log_sd); - - - const char buffer[]= "Ceci est le test de Poivron Robotique\n"; - char big_big_buffer[0x10000]; // 16 ko - - int size = 0; - big_big_buffer[0]= '\0'; - while(size + strlen(buffer) < 0x10000){ - strcat(big_big_buffer, buffer); - size += strlen(buffer); - } - while (1) { + struct gamepad_data_t gamepad_data; // tinyusb host task tuh_task(); led_blinking_task(); cdc_app_task(); hid_app_task(); + gamepad_data = get_gamepad_data(); + ws2812_set_mode(LED_ID_DIVERS, LED_STABLE, (gamepad_data.joystick_x_droit) << 8 | gamepad_data.joystick_y_droit); + //log_to_sd(big_big_buffer); //log_to_usb(big_big_buffer); // à commenter pour obtenir un test juste sur la carte SD.(ou simplement ne pas brancher de clé USB)