-
Notifications
You must be signed in to change notification settings - Fork 1
/
USBPcS3ProMicro.c
153 lines (126 loc) · 4.66 KB
/
USBPcS3ProMicro.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
/*
*
* USBPcS3: Interfaz USB que emula control de PS3 para Pro Micro originales o piratas 5V 16MHz | ATMega32u4
*
* Copyright (c) 2020
* Bruno Freitas - [email protected]
* Jon Wilson - [email protected]
* Kevin Mackett - [email protected]
* Bastian Aguirre - crtgamers.cl
*
* Este programa es software gratuito: puedes redistribuirlo y / o modificar
* bajo los términos de la Licencia Pública General GNU publicada por
* Free Software Foundation, ya sea la versión 3 de la Licencia, o
* (a su elección) cualquier versión posterior.
*
* Este programa se distribuye con la esperanza de que sea útil,
* pero SIN NINGUNA GARANTÍA; sin siquiera la garantía implícita de
* COMERCIABILIDAD o APTITUD PARA UN PROPÓSITO PARTICULAR. Ver el
* Licencia pública general GNU para más detalles.
*
* Debería haber recibido una copia de la Licencia Pública General GNU
* junto con este programa. Si no, vea <http://www.gnu.org/licenses/>.
*/
#include "USBPcS3ProMicro.h"
USB_JoystickReport_Data_t gamepad_state;
static uint8_t ps3_magic_bytes[8] = { 0x21, 0x26, 0x01, 0x07, 0x00, 0x00, 0x00, 0x00 };
void (*padUSBConnectEventCallback)(void) = NULL;
void (*padUSBDisconnectEventCallback)(void) = NULL;
/** Controlador de eventos para el evento USB_Connect. Esto indica que el dispositivo está enumerando a través de los LED de estado y
* inicia la tarea USB de la biblioteca para comenzar el proceso de enumeración y administración de USB.
*/
void EVENT_USB_Device_Connect(void)
{
if(padUSBConnectEventCallback)
padUSBConnectEventCallback();
}
/** Controlador de eventos para el evento USB_Disconnect. Esto indica que el dispositivo ya no está conectado a un host a través de
* los LED de estado y detiene la gestión de USB y las tareas de informes del joystick.
*/
void EVENT_USB_Device_Disconnect(void)
{
if(padUSBDisconnectEventCallback)
padUSBDisconnectEventCallback();
}
/** Controlador de eventos para el evento USB_ConfigurationChanged. Esto se activa cuando el host establece la configuración actual
* del dispositivo USB después de la enumeración: se configuran los puntos finales del dispositivo y se inicia la tarea de informes del joystick.
*/
void EVENT_USB_Device_ConfigurationChanged(void)
{
/* Configurar el punto final del informe HID */
Endpoint_ConfigureEndpoint(JOYSTICK_EPADDR, EP_TYPE_INTERRUPT, JOYSTICK_EPSIZE, 1);
}
/** Controlador de eventos para el evento USB_ControlRequest. Se utiliza para capturar y procesar solicitudes de control enviadas a
* el dispositivo del host USB antes de pasar las solicitudes de control no gestionadas a la biblioteca para su procesamiento
* internamente.
*/
void EVENT_USB_Device_ControlRequest(void)
{
/* Manejar solicitudes específicas de clase HID */
switch (USB_ControlRequest.bRequest)
{
case HID_REQ_GetReport:
if (USB_ControlRequest.bmRequestType == (REQDIR_DEVICETOHOST | REQTYPE_CLASS | REQREC_INTERFACE))
{
if(USB_ControlRequest.wValue == 0x0300) {
Endpoint_ClearSETUP();
Endpoint_Write_Control_Stream_LE(ps3_magic_bytes, sizeof(ps3_magic_bytes));
Endpoint_ClearOUT();
} else {
Endpoint_ClearSETUP();
/* Escriba los datos del informe en el punto final de control */
Endpoint_Write_Control_Stream_LE(&gamepad_state, sizeof(gamepad_state));
Endpoint_ClearOUT();
}
}
break;
}
}
/** Función para gestionar la generación y transmisión de informes HID al host. */
void HID_Task(void)
{
/* El dispositivo debe estar conectado y configurado para que se ejecute la tarea */
if (USB_DeviceState != DEVICE_STATE_Configured)
return;
/* Seleccione el punto final del informe del joystick */
Endpoint_SelectEndpoint(JOYSTICK_EPADDR);
/* Verifique si el host está listo para otro paquete */
if (Endpoint_IsINReady())
{
/* Escribir datos de informe de joystick */
Endpoint_Write_Stream_LE(&gamepad_state, sizeof(gamepad_state), NULL);
/* Finalice la transferencia de flujo para enviar el último paquete */
Endpoint_ClearIN();
}
}
void vs_reset_pad_status(void) {
memset(&gamepad_state, 0x00, sizeof(USB_JoystickReport_Data_t));
gamepad_state.direction = 0x08;
gamepad_state.l_x_axis = 0x80;
gamepad_state.l_y_axis = 0x80;
gamepad_state.r_x_axis = 0x80;
gamepad_state.r_y_axis = 0x80;
}
void vs_init(bool watchdog) {
if (watchdog) {
wdt_enable(WDTO_2S);
} else {
wdt_disable();
}
vs_reset_pad_status();
USB_Init();
sei();
}
void vs_reset_watchdog(void) {
wdt_reset();
}
void vs_send_pad_state(void) {
HID_Task();
USB_USBTask();
}
void vs_set_connect_callback(void (*callbackPtr)(void)) {
padUSBConnectEventCallback = callbackPtr;
}
void vs_set_disconnect_callback(void (*callbackPtr)(void)) {
padUSBDisconnectEventCallback = callbackPtr;
}