#include "xinput_app.h" #include "main.h" #include "usb_device.h" #include "usbd_xinput.h" typedef struct __attribute__((packed)) { uint8_t reportId; uint8_t reportSize; uint8_t buttons1; uint8_t buttons2; uint8_t leftTrigger; uint8_t rightTrigger; int16_t leftX; int16_t leftY; int16_t rightX; int16_t rightY; uint8_t reserved[6]; } XInputReport; _Static_assert(sizeof(XInputReport) == XINPUT_REPORT_SIZE, "XInput input report must be exactly 20 bytes"); extern USBD_HandleTypeDef hUsbDeviceFS; static uint8_t IsPressed(GPIO_TypeDef *port, uint16_t pin) { return (HAL_GPIO_ReadPin(port, pin) == GPIO_PIN_RESET) ? 1U : 0U; } void XInput_AppProcess(void) { XInputReport report = {0}; report.reportId = 0x00U; report.reportSize = sizeof(report); if (IsPressed(UP_GPIO_Port, UP_Pin)) { report.buttons1 |= (1U << 0); } if (IsPressed(DOWN_GPIO_Port, DOWN_Pin)) { report.buttons1 |= (1U << 1); } if (IsPressed(LEFT_GPIO_Port, LEFT_Pin)) { report.buttons1 |= (1U << 2); } if (IsPressed(RIGHT_GPIO_Port, RIGHT_Pin)) { report.buttons1 |= (1U << 3); } if (IsPressed(Start_GPIO_Port, Start_Pin)) { report.buttons1 |= (1U << 4); } if (IsPressed(Select_GPIO_Port, Select_Pin)) { report.buttons1 |= (1U << 5); } if (IsPressed(LB_GPIO_Port, LB_Pin)) { report.buttons2 |= (1U << 0); } if (IsPressed(RB_GPIO_Port, RB_Pin)) { report.buttons2 |= (1U << 1); } if (IsPressed(A_GPIO_Port, A_Pin)) { report.buttons2 |= (1U << 4); } if (IsPressed(B_GPIO_Port, B_Pin)) { report.buttons2 |= (1U << 5); } if (IsPressed(X_GPIO_Port, X_Pin)) { report.buttons2 |= (1U << 6); } if (IsPressed(Y_GPIO_Port, Y_Pin)) { report.buttons2 |= (1U << 7); } report.leftTrigger = IsPressed(LT_GPIO_Port, LT_Pin) ? 0xFFU : 0x00U; report.rightTrigger = IsPressed(RT_GPIO_Port, RT_Pin) ? 0xFFU : 0x00U; (void)USBD_XINPUT_SendReport(&hUsbDeviceFS, (uint8_t *)&report, sizeof(report)); }