#include "dinput_app.h" #include "main.h" #include "usb_device.h" #include "usbd_dinput.h" typedef struct __attribute__((packed)) { uint16_t buttons; uint8_t hat; uint8_t axes[6]; } DInputReport; _Static_assert(sizeof(DInputReport) == DINPUT_REPORT_SIZE, "DInput input report must be exactly 9 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; } static uint8_t ReadHat(void) { uint8_t up = IsPressed(UP_GPIO_Port, UP_Pin); uint8_t down = IsPressed(DOWN_GPIO_Port, DOWN_Pin); uint8_t left = IsPressed(LEFT_GPIO_Port, LEFT_Pin); uint8_t right = IsPressed(RIGHT_GPIO_Port, RIGHT_Pin); if (up && right && !down && !left) return 1U; if (down && right && !up && !left) return 3U; if (down && left && !up && !right) return 5U; if (up && left && !down && !right) return 7U; if (up && !down && !left && !right) return 0U; if (right && !up && !down && !left) return 2U; if (down && !up && !left && !right) return 4U; if (left && !up && !down && !right) return 6U; return 8U; } void DInput_AppProcess(void) { DInputReport report = { .buttons = 0U, .hat = 8U, .axes = {0x80U, 0x80U, 0x80U, 0x80U, 0x80U, 0x80U} }; report.hat = ReadHat(); if (IsPressed(X_GPIO_Port, X_Pin)) report.buttons |= (1U << 0); if (IsPressed(Y_GPIO_Port, Y_Pin)) report.buttons |= (1U << 1); if (IsPressed(A_GPIO_Port, A_Pin)) report.buttons |= (1U << 2); if (IsPressed(B_GPIO_Port, B_Pin)) report.buttons |= (1U << 3); if (IsPressed(RB_GPIO_Port, RB_Pin)) report.buttons |= (1U << 4); if (IsPressed(LB_GPIO_Port, LB_Pin)) report.buttons |= (1U << 5); if (IsPressed(RT_GPIO_Port, RT_Pin)) report.buttons |= (1U << 6); if (IsPressed(LT_GPIO_Port, LT_Pin)) report.buttons |= (1U << 7); if (IsPressed(Start_GPIO_Port, Start_Pin)) report.buttons |= (1U << 8); if (IsPressed(Select_GPIO_Port, Select_Pin)) report.buttons |= (1U << 9); (void)USBD_DINPUT_SendReport(&hUsbDeviceFS, (uint8_t *)&report, sizeof(report)); }