User | Revision | Line number | New contents of line |
abe00makoto |
0:e939856c1939
|
1
|
/*
|
abe00makoto |
0:e939856c1939
|
2
|
Copyright (c) 2011 Bart Janssens
|
abe00makoto |
0:e939856c1939
|
3
|
|
abe00makoto |
0:e939856c1939
|
4
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
abe00makoto |
0:e939856c1939
|
5
|
of this software and associated documentation files (the "Software"), to deal
|
abe00makoto |
0:e939856c1939
|
6
|
in the Software without restriction, including without limitation the rights
|
abe00makoto |
0:e939856c1939
|
7
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
abe00makoto |
0:e939856c1939
|
8
|
copies of the Software, and to permit persons to whom the Software is
|
abe00makoto |
0:e939856c1939
|
9
|
furnished to do so, subject to the following conditions:
|
abe00makoto |
0:e939856c1939
|
10
|
|
abe00makoto |
0:e939856c1939
|
11
|
The above copyright notice and this permission notice shall be included in
|
abe00makoto |
0:e939856c1939
|
12
|
all copies or substantial portions of the Software.
|
abe00makoto |
0:e939856c1939
|
13
|
|
abe00makoto |
0:e939856c1939
|
14
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
abe00makoto |
0:e939856c1939
|
15
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
abe00makoto |
0:e939856c1939
|
16
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
abe00makoto |
0:e939856c1939
|
17
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
abe00makoto |
0:e939856c1939
|
18
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
abe00makoto |
0:e939856c1939
|
19
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
abe00makoto |
0:e939856c1939
|
20
|
THE SOFTWARE.
|
abe00makoto |
0:e939856c1939
|
21
|
*/
|
abe00makoto |
0:e939856c1939
|
22
|
|
abe00makoto |
0:e939856c1939
|
23
|
#include <stdio.h>
|
abe00makoto |
0:e939856c1939
|
24
|
#include <stdlib.h>
|
abe00makoto |
0:e939856c1939
|
25
|
#include <string.h>
|
abe00makoto |
0:e939856c1939
|
26
|
|
abe00makoto |
0:e939856c1939
|
27
|
#include "USBHost.h"
|
abe00makoto |
0:e939856c1939
|
28
|
#include "hci.h"
|
abe00makoto |
0:e939856c1939
|
29
|
#include "Utils.h"
|
abe00makoto |
0:e939856c1939
|
30
|
#include "ps3.h"
|
abe00makoto |
0:e939856c1939
|
31
|
|
abe00makoto |
0:e939856c1939
|
32
|
#include "mbed.h"
|
abe00makoto |
0:e939856c1939
|
33
|
|
abe00makoto |
0:e939856c1939
|
34
|
|
abe00makoto |
0:e939856c1939
|
35
|
|
abe00makoto |
0:e939856c1939
|
36
|
#define AUTOEVT(_class,_subclass,_protocol) (((_class) << 16) | ((_subclass) << 8) | _protocol)
|
abe00makoto |
0:e939856c1939
|
37
|
#define PS3EVT AUTOEVT(CLASS_HID,0,0)
|
abe00makoto |
0:e939856c1939
|
38
|
#define byteswap(x) ((x >> 8) | (x << 8))
|
abe00makoto |
0:e939856c1939
|
39
|
|
abe00makoto |
0:e939856c1939
|
40
|
u8 ps3_data[48];
|
abe00makoto |
0:e939856c1939
|
41
|
|
abe00makoto |
0:e939856c1939
|
42
|
|
abe00makoto |
0:e939856c1939
|
43
|
Ps3USB::Ps3USB(int device, int configuration, int interfaceNumber)
|
abe00makoto |
0:e939856c1939
|
44
|
{
|
abe00makoto |
0:e939856c1939
|
45
|
printf("Creating new sixaxis \r\n");
|
abe00makoto |
0:e939856c1939
|
46
|
_device = device;
|
abe00makoto |
0:e939856c1939
|
47
|
_configuration = configuration;
|
abe00makoto |
0:e939856c1939
|
48
|
_interfaceNumber = interfaceNumber;
|
abe00makoto |
0:e939856c1939
|
49
|
printf("device = %d configuration = %d interfaceNumber = %d\r\n", device, configuration, interfaceNumber);
|
abe00makoto |
0:e939856c1939
|
50
|
int result;
|
abe00makoto |
0:e939856c1939
|
51
|
int err;
|
abe00makoto |
0:e939856c1939
|
52
|
|
abe00makoto |
0:e939856c1939
|
53
|
_count = 1;
|
abe00makoto |
0:e939856c1939
|
54
|
|
abe00makoto |
0:e939856c1939
|
55
|
u8 abuffer[48] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
abe00makoto |
0:e939856c1939
|
56
|
0x00, 0x02, 0xff, 0x27, 0x10, 0x00, 0x32, 0xff,
|
abe00makoto |
0:e939856c1939
|
57
|
0x27, 0x10, 0x00, 0x32, 0xff, 0x27, 0x10, 0x00,
|
abe00makoto |
0:e939856c1939
|
58
|
0x32, 0xff, 0x27, 0x10, 0x00, 0x32, 0x00, 0x00,
|
abe00makoto |
0:e939856c1939
|
59
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
abe00makoto |
0:e939856c1939
|
60
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
|
abe00makoto |
0:e939856c1939
|
61
|
memcpy(ledrumble,abuffer,48);
|
abe00makoto |
0:e939856c1939
|
62
|
|
abe00makoto |
0:e939856c1939
|
63
|
EndpointDescriptor* ep;
|
abe00makoto |
0:e939856c1939
|
64
|
|
abe00makoto |
0:e939856c1939
|
65
|
u8 buffer[255];
|
abe00makoto |
0:e939856c1939
|
66
|
err = GetDescriptor(_device,DESCRIPTOR_TYPE_CONFIGURATION,0,buffer,255);
|
abe00makoto |
0:e939856c1939
|
67
|
if (err < 0)
|
abe00makoto |
0:e939856c1939
|
68
|
printf("Failed to get descriptor\r\n");
|
abe00makoto |
0:e939856c1939
|
69
|
|
abe00makoto |
0:e939856c1939
|
70
|
|
abe00makoto |
0:e939856c1939
|
71
|
int len = buffer[2] | (buffer[3] << 8);
|
abe00makoto |
0:e939856c1939
|
72
|
u8* d = buffer;
|
abe00makoto |
0:e939856c1939
|
73
|
u8* end = d + len;
|
abe00makoto |
0:e939856c1939
|
74
|
while (d < end)
|
abe00makoto |
0:e939856c1939
|
75
|
{
|
abe00makoto |
0:e939856c1939
|
76
|
if (d[1] == DESCRIPTOR_TYPE_INTERFACE)
|
abe00makoto |
0:e939856c1939
|
77
|
{
|
abe00makoto |
0:e939856c1939
|
78
|
InterfaceDescriptor* id = (InterfaceDescriptor*)d;
|
abe00makoto |
0:e939856c1939
|
79
|
if (id->bInterfaceNumber == _interfaceNumber)
|
abe00makoto |
0:e939856c1939
|
80
|
{
|
abe00makoto |
0:e939856c1939
|
81
|
d += d[0];
|
abe00makoto |
0:e939856c1939
|
82
|
while (d < end && d[1] != DESCRIPTOR_TYPE_INTERFACE)
|
abe00makoto |
0:e939856c1939
|
83
|
{
|
abe00makoto |
0:e939856c1939
|
84
|
if (d[1] == DESCRIPTOR_TYPE_ENDPOINT)
|
abe00makoto |
0:e939856c1939
|
85
|
ep = (EndpointDescriptor*)d;
|
abe00makoto |
0:e939856c1939
|
86
|
|
abe00makoto |
0:e939856c1939
|
87
|
if (ep->bEndpointAddress == 0x02) {
|
abe00makoto |
0:e939856c1939
|
88
|
printf("PS3 input endpoint (0x02) found\r\n");
|
abe00makoto |
0:e939856c1939
|
89
|
input_ep = 0x02;
|
abe00makoto |
0:e939856c1939
|
90
|
|
abe00makoto |
0:e939856c1939
|
91
|
}
|
abe00makoto |
0:e939856c1939
|
92
|
if (ep->bEndpointAddress == 0x81) {
|
abe00makoto |
0:e939856c1939
|
93
|
printf("PS3 output endpoint (0x81) found\r\n");
|
abe00makoto |
0:e939856c1939
|
94
|
output_ep = 0x81;
|
abe00makoto |
0:e939856c1939
|
95
|
//AddAutoEvent(device,id,(EndpointDescriptor*)d);
|
abe00makoto |
0:e939856c1939
|
96
|
}
|
abe00makoto |
0:e939856c1939
|
97
|
d += d[0];
|
abe00makoto |
0:e939856c1939
|
98
|
}
|
abe00makoto |
0:e939856c1939
|
99
|
}
|
abe00makoto |
0:e939856c1939
|
100
|
}
|
abe00makoto |
0:e939856c1939
|
101
|
d += d[0];
|
abe00makoto |
0:e939856c1939
|
102
|
}
|
abe00makoto |
0:e939856c1939
|
103
|
|
abe00makoto |
0:e939856c1939
|
104
|
}
|
abe00makoto |
0:e939856c1939
|
105
|
|
abe00makoto |
0:e939856c1939
|
106
|
int Ps3USB::Enable()
|
abe00makoto |
0:e939856c1939
|
107
|
{
|
abe00makoto |
0:e939856c1939
|
108
|
//int err;
|
abe00makoto |
0:e939856c1939
|
109
|
|
abe00makoto |
0:e939856c1939
|
110
|
u8 enable[4] = {0x42,0x0c,0x00,0x00};
|
abe00makoto |
0:e939856c1939
|
111
|
|
abe00makoto |
0:e939856c1939
|
112
|
|
abe00makoto |
0:e939856c1939
|
113
|
/*err =*/ USBControlTransfer(_device, HOST_TO_DEVICE|REQUEST_TYPE_CLASS|RECIPIENT_INTERFACE, HID_REQUEST_SET_REPORT, 0x03f4,0, enable, sizeof(enable), 0, 0 );
|
abe00makoto |
0:e939856c1939
|
114
|
//printf("set report result = %d\r\n", err);
|
abe00makoto |
0:e939856c1939
|
115
|
_count ++;
|
abe00makoto |
0:e939856c1939
|
116
|
if (_count == 25) _count = 1;
|
abe00makoto |
0:e939856c1939
|
117
|
|
abe00makoto |
0:e939856c1939
|
118
|
/*err = */USBInterruptTransfer(_device,output_ep,ps3_data,sizeof(ps3_data),PS3EventCallback,this);
|
abe00makoto |
0:e939856c1939
|
119
|
wait_ms(4);
|
abe00makoto |
0:e939856c1939
|
120
|
|
abe00makoto |
0:e939856c1939
|
121
|
return 0;
|
abe00makoto |
0:e939856c1939
|
122
|
|
abe00makoto |
0:e939856c1939
|
123
|
}
|
abe00makoto |
0:e939856c1939
|
124
|
|
abe00makoto |
0:e939856c1939
|
125
|
|
abe00makoto |
0:e939856c1939
|
126
|
|
abe00makoto |
0:e939856c1939
|
127
|
|
abe00makoto |
0:e939856c1939
|
128
|
int Ps3USB::SetPair(u8* bdAddr)
|
abe00makoto |
0:e939856c1939
|
129
|
{
|
abe00makoto |
0:e939856c1939
|
130
|
int err;
|
abe00makoto |
0:e939856c1939
|
131
|
|
abe00makoto |
0:e939856c1939
|
132
|
u8 buf[8];
|
abe00makoto |
0:e939856c1939
|
133
|
u8 buf2[6];
|
abe00makoto |
0:e939856c1939
|
134
|
|
abe00makoto |
0:e939856c1939
|
135
|
memcpy(buf2,bdAddr,6);
|
abe00makoto |
0:e939856c1939
|
136
|
|
abe00makoto |
0:e939856c1939
|
137
|
buf[0] = 0x01;
|
abe00makoto |
0:e939856c1939
|
138
|
buf[1] = 0x00;
|
abe00makoto |
0:e939856c1939
|
139
|
buf[2] = buf2[0];
|
abe00makoto |
0:e939856c1939
|
140
|
buf[3] = buf2[1];
|
abe00makoto |
0:e939856c1939
|
141
|
buf[4] = buf2[2];
|
abe00makoto |
0:e939856c1939
|
142
|
buf[5] = buf2[3];
|
abe00makoto |
0:e939856c1939
|
143
|
buf[6] = buf2[4];
|
abe00makoto |
0:e939856c1939
|
144
|
buf[7] = buf2[5];
|
abe00makoto |
0:e939856c1939
|
145
|
|
abe00makoto |
0:e939856c1939
|
146
|
//set Mac address
|
abe00makoto |
0:e939856c1939
|
147
|
err = USBControlTransfer(_device, HOST_TO_DEVICE|REQUEST_TYPE_CLASS|RECIPIENT_INTERFACE, HID_REQUEST_SET_REPORT, 0x03f5, 0, buf, sizeof(buf), 0, 0 );
|
abe00makoto |
0:e939856c1939
|
148
|
wait_ms(4);
|
abe00makoto |
0:e939856c1939
|
149
|
printf("set Mac address to %02X:%02X:%02X:%02X:%02X:%02X , result = %d\r\n", buf[2], buf[3], buf[4], buf[5], buf[6], buf[7], err);
|
abe00makoto |
0:e939856c1939
|
150
|
|
abe00makoto |
0:e939856c1939
|
151
|
return 0;
|
abe00makoto |
0:e939856c1939
|
152
|
}
|
abe00makoto |
0:e939856c1939
|
153
|
|
abe00makoto |
0:e939856c1939
|
154
|
int Ps3USB::ShowPair()
|
abe00makoto |
0:e939856c1939
|
155
|
{
|
abe00makoto |
0:e939856c1939
|
156
|
int err;
|
abe00makoto |
0:e939856c1939
|
157
|
|
abe00makoto |
0:e939856c1939
|
158
|
u8 buf[8];
|
abe00makoto |
0:e939856c1939
|
159
|
//get Mac address
|
abe00makoto |
0:e939856c1939
|
160
|
err = USBControlTransfer(_device, DEVICE_TO_HOST|REQUEST_TYPE_CLASS|RECIPIENT_INTERFACE, HID_REQUEST_GET_REPORT, 0x03f5, 0, buf, sizeof(buf), 0, 0 );
|
abe00makoto |
0:e939856c1939
|
161
|
wait_ms(4);
|
abe00makoto |
0:e939856c1939
|
162
|
printf("Mac address is set to %02X:%02X:%02X:%02X:%02X:%02X , result = %d\r\n",buf[2], buf[3], buf[4], buf[5], buf[6], buf[7], err);
|
abe00makoto |
0:e939856c1939
|
163
|
|
abe00makoto |
0:e939856c1939
|
164
|
|
abe00makoto |
0:e939856c1939
|
165
|
return 0;
|
abe00makoto |
0:e939856c1939
|
166
|
}
|
abe00makoto |
0:e939856c1939
|
167
|
|
abe00makoto |
0:e939856c1939
|
168
|
int Ps3USB::Led(int i)
|
abe00makoto |
0:e939856c1939
|
169
|
{
|
abe00makoto |
0:e939856c1939
|
170
|
// int err;
|
abe00makoto |
0:e939856c1939
|
171
|
u8 ledpattern[7] = {0x02, 0x04, 0x08, 0x10, 0x12, 0x14, 0x18 };
|
abe00makoto |
0:e939856c1939
|
172
|
u8 buf[48];
|
abe00makoto |
0:e939856c1939
|
173
|
|
abe00makoto |
0:e939856c1939
|
174
|
if (i < 7) ledrumble[9] = ledpattern[i];
|
abe00makoto |
0:e939856c1939
|
175
|
memcpy(buf, ledrumble, 48);
|
abe00makoto |
0:e939856c1939
|
176
|
|
abe00makoto |
0:e939856c1939
|
177
|
/*err = */USBControlTransfer(_device, HOST_TO_DEVICE|REQUEST_TYPE_CLASS|RECIPIENT_INTERFACE, HID_REQUEST_SET_REPORT, 0x0201,0, buf, sizeof(buf), 0, 0 );
|
abe00makoto |
0:e939856c1939
|
178
|
wait_ms(4);
|
abe00makoto |
0:e939856c1939
|
179
|
|
abe00makoto |
0:e939856c1939
|
180
|
return 0;
|
abe00makoto |
0:e939856c1939
|
181
|
}
|
abe00makoto |
0:e939856c1939
|
182
|
|
abe00makoto |
0:e939856c1939
|
183
|
// left and right: duration and power, both from 0 to 255
|
abe00makoto |
0:e939856c1939
|
184
|
int Ps3USB::Rumble(u8 duration_right, u8 power_right, u8 duration_left, u8 power_left)
|
abe00makoto |
0:e939856c1939
|
185
|
{
|
abe00makoto |
0:e939856c1939
|
186
|
//int err;
|
abe00makoto |
0:e939856c1939
|
187
|
u8 buf[48];
|
abe00makoto |
0:e939856c1939
|
188
|
|
abe00makoto |
0:e939856c1939
|
189
|
memcpy(buf, ledrumble, 48);
|
abe00makoto |
0:e939856c1939
|
190
|
buf[1] = duration_right;
|
abe00makoto |
0:e939856c1939
|
191
|
buf[2] = power_right;
|
abe00makoto |
0:e939856c1939
|
192
|
buf[3] = duration_left;
|
abe00makoto |
0:e939856c1939
|
193
|
buf[4] = power_left;
|
abe00makoto |
0:e939856c1939
|
194
|
|
abe00makoto |
0:e939856c1939
|
195
|
/*err = */USBControlTransfer(_device, HOST_TO_DEVICE|REQUEST_TYPE_CLASS|RECIPIENT_INTERFACE, HID_REQUEST_SET_REPORT, 0x0201,0, buf, sizeof(buf), 0, 0 );
|
abe00makoto |
0:e939856c1939
|
196
|
wait_ms(4);
|
abe00makoto |
0:e939856c1939
|
197
|
|
abe00makoto |
0:e939856c1939
|
198
|
return 0;
|
abe00makoto |
0:e939856c1939
|
199
|
}
|
abe00makoto |
0:e939856c1939
|
200
|
|
abe00makoto |
0:e939856c1939
|
201
|
|
abe00makoto |
0:e939856c1939
|
202
|
void PS3EventCallback(int device, int endpoint, int status, u8* data, int len, void* userData)
|
abe00makoto |
0:e939856c1939
|
203
|
{
|
abe00makoto |
0:e939856c1939
|
204
|
Ps3USB* t = (Ps3USB*)userData;
|
abe00makoto |
0:e939856c1939
|
205
|
|
abe00makoto |
0:e939856c1939
|
206
|
t->_count ++;
|
abe00makoto |
0:e939856c1939
|
207
|
if (t->_count == 25) t->_count = 1;
|
abe00makoto |
0:e939856c1939
|
208
|
|
abe00makoto |
0:e939856c1939
|
209
|
ParsePs3Result(data, sizeof(ps3report),t->_count);
|
abe00makoto |
0:e939856c1939
|
210
|
USBInterruptTransfer(device, endpoint , data, len, PS3EventCallback, userData);
|
abe00makoto |
0:e939856c1939
|
211
|
wait_ms(4);
|
abe00makoto |
0:e939856c1939
|
212
|
|
abe00makoto |
0:e939856c1939
|
213
|
}
|
abe00makoto |
0:e939856c1939
|
214
|
|
abe00makoto |
0:e939856c1939
|
215
|
int ParsePs3Result(const u8* data,int len,int count)
|
abe00makoto |
0:e939856c1939
|
216
|
{
|
abe00makoto |
0:e939856c1939
|
217
|
ps3report* _ps3report = (ps3report*)data;
|
abe00makoto |
0:e939856c1939
|
218
|
if (count == 24) printf("LSX LSY RSX RSY UPA RPA DPA RPA L2 R2 L1 R1 TRI CIR CRO SQU ACX ACY ACZ GYZ \r\n");
|
abe00makoto |
0:e939856c1939
|
219
|
printf("%3d %3d %3d %3d %3d %3d %3d %3d %3d %3d %3d %3d %3d %3d %3d %3d %4d %4d %4d %4d \r\n",
|
abe00makoto |
0:e939856c1939
|
220
|
_ps3report->LeftStickX,
|
abe00makoto |
0:e939856c1939
|
221
|
_ps3report->LeftStickY,
|
abe00makoto |
0:e939856c1939
|
222
|
_ps3report->RightStickX,
|
abe00makoto |
0:e939856c1939
|
223
|
_ps3report->RightStickY,
|
abe00makoto |
0:e939856c1939
|
224
|
_ps3report->PressureUp,
|
abe00makoto |
0:e939856c1939
|
225
|
_ps3report->PressureRight,
|
abe00makoto |
0:e939856c1939
|
226
|
_ps3report->PressureDown,
|
abe00makoto |
0:e939856c1939
|
227
|
_ps3report->PressureLeft,
|
abe00makoto |
0:e939856c1939
|
228
|
_ps3report->PressureL2,
|
abe00makoto |
0:e939856c1939
|
229
|
_ps3report->PressureR2,
|
abe00makoto |
0:e939856c1939
|
230
|
_ps3report->PressureL1,
|
abe00makoto |
0:e939856c1939
|
231
|
_ps3report->PressureR1,
|
abe00makoto |
0:e939856c1939
|
232
|
_ps3report->PressureTriangle,
|
abe00makoto |
0:e939856c1939
|
233
|
_ps3report->PressureCircle,
|
abe00makoto |
0:e939856c1939
|
234
|
_ps3report->PressureCross,
|
abe00makoto |
0:e939856c1939
|
235
|
_ps3report->PressureSquare,
|
abe00makoto |
0:e939856c1939
|
236
|
(_ps3report->AccelX),
|
abe00makoto |
0:e939856c1939
|
237
|
(_ps3report->AccelY),
|
abe00makoto |
0:e939856c1939
|
238
|
(_ps3report->AccelZ),
|
abe00makoto |
0:e939856c1939
|
239
|
(_ps3report->GyroZ));
|
abe00makoto |
0:e939856c1939
|
240
|
//printfBytes("data",data,len);
|
abe00makoto |
0:e939856c1939
|
241
|
}
|
abe00makoto |
0:e939856c1939
|
242
|
|
abe00makoto |
0:e939856c1939
|
243
|
|