23 PS3BT::PS3BT(
BTD *p, uint8_t btadr5, uint8_t btadr4, uint8_t btadr3, uint8_t btadr2, uint8_t btadr1, uint8_t btadr0) :
40 HIDMoveBuffer[0] = 0xA2;
41 HIDMoveBuffer[1] = 0x02;
44 control_dcid[0] = 0x40;
45 control_dcid[1] = 0x00;
46 interrupt_dcid[0] = 0x41;
47 interrupt_dcid[1] = 0x00;
53 return (ButtonState & pgm_read_dword(&
BUTTONS[(uint8_t)b]));
57 uint32_t button = pgm_read_dword(&
BUTTONS[(uint8_t)b]);
58 bool click = (ButtonClickState & button);
59 ButtonClickState &= ~button;
64 if (l2capinbuf == NULL)
66 return (uint8_t)(l2capinbuf[pgm_read_byte(&
ANALOGBUTTONS[(uint8_t)a])]);
70 if (l2capinbuf == NULL)
72 return (uint8_t)(l2capinbuf[(uint8_t)a + 15]);
76 if (l2capinbuf == NULL)
79 if (a ==
aX || a ==
aY || a ==
aZ || a ==
gZ)
80 return ((l2capinbuf[(uint16_t)a] << 8) | l2capinbuf[(uint16_t)a + 1]);
85 return (((l2capinbuf[(uint16_t)a] & 0x0F) << 8) | (l2capinbuf[(uint16_t)a + 1]));
87 return ((l2capinbuf[(uint16_t)a] << 4) | ((l2capinbuf[(uint16_t)a + 1] & 0xF0) >> 4));
89 return (l2capinbuf[(uint16_t)a] | (l2capinbuf[(uint16_t)a + 1] << 8));
101 const double zeroG = 511.5;
107 const uint16_t zeroG = 0x8000;
118 double angle = (atan2(accYval, accZval) + PI) * RAD_TO_DEG;
121 double angle = (atan2(accXval, accZval) + PI) * RAD_TO_DEG;
133 return (
double)value / 3.2;
139 return (
double)value / 442.0;
146 return (
double)value / 11.6;
148 return (
double)value / 11.2;
150 return (
double)value / 9.6;
159 String output = String(input / 100);
161 if (input % 100 < 10)
163 output += String(input % 100);
171 if (l2capinbuf == NULL)
173 if (l2capinbuf[(uint16_t)c >> 8] == ((uint8_t)c & 0xff))
180 char statusOutput[100];
182 strcpy(statusOutput,
"ConnectionStatus: ");
186 else strcat(statusOutput,
"Error");
189 strcat(statusOutput,
" - PowerRating: ");
197 else strcat(statusOutput,
"Error");
199 strcat(statusOutput,
" - WirelessStatus: ");
202 else if (
getStatus(
Cable)) strcat(statusOutput,
"Cable - Rumble is off");
205 else strcat(statusOutput,
"Error");
210 char statusOutput[50];
212 strcpy(statusOutput,
"PowerRating: ");
221 else strcat(statusOutput,
"Error");
232 activeConnection =
false;
233 l2cap_event_flag = 0;
251 if ((ACLData[12] | (ACLData[13] << 8)) ==
HID_CTRL_PSM) {
253 activeConnection =
true;
256 for (uint8_t i = 0; i < 30; i++)
258 #ifdef DEBUG_USB_HOST
260 Notify(PSTR(
"\r\nYour dongle may not support reading the analog buttons, sensors and status\r\nYour HCI Version is: "), 0x80);
262 Notify(PSTR(
"\r\nBut should be at least 3\r\nThis means that it doesn't support Bluetooth Version 2.0+EDR"), 0x80);
268 if (((ACLData[0] | (ACLData[1] << 8)) == (hci_handle | 0x2000))) {
270 l2capinbuf[i] = ACLData[i];
271 if ((l2capinbuf[6] | (l2capinbuf[7] << 8)) == 0x0001) {
273 #ifdef DEBUG_USB_HOST
274 Notify(PSTR(
"\r\nL2CAP Command Rejected - Reason: "), 0x80);
275 D_PrintHex<uint8_t > (l2capinbuf[13], 0x80);
277 D_PrintHex<uint8_t > (l2capinbuf[12], 0x80);
278 Notify(PSTR(
" Data: "), 0x80);
279 D_PrintHex<uint8_t > (l2capinbuf[17], 0x80);
281 D_PrintHex<uint8_t > (l2capinbuf[16], 0x80);
283 D_PrintHex<uint8_t > (l2capinbuf[15], 0x80);
285 D_PrintHex<uint8_t > (l2capinbuf[14], 0x80);
289 Notify(PSTR(
"\r\nL2CAP Connection Request - PSM: "), 0x80);
290 D_PrintHex<uint8_t > (l2capinbuf[13], 0x80);
292 D_PrintHex<uint8_t > (l2capinbuf[12], 0x80);
293 Notify(PSTR(
" SCID: "), 0x80);
294 D_PrintHex<uint8_t > (l2capinbuf[15], 0x80);
296 D_PrintHex<uint8_t > (l2capinbuf[14], 0x80);
297 Notify(PSTR(
" Identifier: "), 0x80);
298 D_PrintHex<uint8_t > (l2capinbuf[9], 0x80);
300 if ((l2capinbuf[12] | (l2capinbuf[13] << 8)) ==
HID_CTRL_PSM) {
301 identifier = l2capinbuf[9];
302 control_scid[0] = l2capinbuf[14];
303 control_scid[1] = l2capinbuf[15];
305 }
else if ((l2capinbuf[12] | (l2capinbuf[13] << 8)) ==
HID_INTR_PSM) {
306 identifier = l2capinbuf[9];
307 interrupt_scid[0] = l2capinbuf[14];
308 interrupt_scid[1] = l2capinbuf[15];
312 if ((l2capinbuf[16] | (l2capinbuf[17] << 8)) == 0x0000) {
313 if (l2capinbuf[12] == control_dcid[0] && l2capinbuf[13] == control_dcid[1]) {
316 }
else if (l2capinbuf[12] == interrupt_dcid[0] && l2capinbuf[13] == interrupt_dcid[1]) {
322 if (l2capinbuf[12] == control_dcid[0] && l2capinbuf[13] == control_dcid[1]) {
324 identifier = l2capinbuf[9];
326 }
else if (l2capinbuf[12] == interrupt_dcid[0] && l2capinbuf[13] == interrupt_dcid[1]) {
328 identifier = l2capinbuf[9];
332 if (l2capinbuf[12] == control_dcid[0] && l2capinbuf[13] == control_dcid[1]) {
333 #ifdef DEBUG_USB_HOST
334 Notify(PSTR(
"\r\nDisconnect Request: Control Channel"), 0x80);
336 identifier = l2capinbuf[9];
339 }
else if (l2capinbuf[12] == interrupt_dcid[0] && l2capinbuf[13] == interrupt_dcid[1]) {
340 #ifdef DEBUG_USB_HOST
341 Notify(PSTR(
"\r\nDisconnect Request: Interrupt Channel"), 0x80);
343 identifier = l2capinbuf[9];
348 if (l2capinbuf[12] == control_scid[0] && l2capinbuf[13] == control_scid[1]) {
350 identifier = l2capinbuf[9];
352 }
else if (l2capinbuf[12] == interrupt_scid[0] && l2capinbuf[13] == interrupt_scid[1]) {
354 identifier = l2capinbuf[9];
360 Notify(PSTR(
"\r\nL2CAP Unknown Signaling Command: "), 0x80);
361 D_PrintHex<uint8_t > (l2capinbuf[8], 0x80);
364 }
else if (l2capinbuf[6] == interrupt_dcid[0] && l2capinbuf[7] == interrupt_dcid[1]) {
368 if (l2capinbuf[8] == 0xA1) {
370 ButtonState = (uint32_t)(l2capinbuf[11] | ((uint16_t)l2capinbuf[12] << 8) | ((uint32_t)l2capinbuf[13] << 16));
372 ButtonState = (uint32_t)(l2capinbuf[10] | ((uint16_t)l2capinbuf[11] << 8) | ((uint32_t)l2capinbuf[12] << 16));
377 if (ButtonState != OldButtonState) {
378 ButtonClickState = ButtonState & ~OldButtonState;
379 OldButtonState = ButtonState;
382 #ifdef PRINTREPORT // Uncomment "#define PRINTREPORT" to print the report send by the PS3 Controllers
383 for (uint8_t i = 10; i < 58; i++) {
384 D_PrintHex<uint8_t > (l2capinbuf[i], 0x80);
387 Notify(PSTR(
"\r\n"), 0x80);
396 void PS3BT::L2CAP_task() {
397 switch (l2cap_state) {
400 #ifdef DEBUG_USB_HOST
401 Notify(PSTR(
"\r\nHID Control Incoming Connection Request"), 0x80);
414 #ifdef DEBUG_USB_HOST
415 Notify(PSTR(
"\r\nHID Control Configuration Request"), 0x80);
424 #ifdef DEBUG_USB_HOST
425 Notify(PSTR(
"\r\nHID Control Successfully Configured"), 0x80);
432 #ifdef DEBUG_USB_HOST
433 Notify(PSTR(
"\r\nHID Interrupt Incoming Connection Request"), 0x80);
447 #ifdef DEBUG_USB_HOST
448 Notify(PSTR(
"\r\nHID Interrupt Configuration Request"), 0x80);
456 #ifdef DEBUG_USB_HOST
457 Notify(PSTR(
"\r\nHID Interrupt Successfully Configured"), 0x80);
459 if (remote_name[0] ==
'M') {
473 #ifdef DEBUG_USB_HOST
474 Notify(PSTR(
"\r\nDisconnected Interrupt Channel"), 0x80);
484 #ifdef DEBUG_USB_HOST
485 Notify(PSTR(
"\r\nDisconnected Control Channel"), 0x80);
489 l2cap_event_flag = 0;
497 switch (l2cap_state) {
499 if (millis() - timer > 1000) {
502 for (uint8_t i = 15; i < 19; i++)
503 l2capinbuf[i] = 0x7F;
511 if (millis() - timer > 1000) {
512 if (remote_name[0] ==
'P') {
513 #ifdef DEBUG_USB_HOST
514 Notify(PSTR(
"\r\nDualshock 3 Controller Enabled\r\n"), 0x80);
517 }
else if (remote_name[0] ==
'N') {
518 #ifdef DEBUG_USB_HOST
519 Notify(PSTR(
"\r\nNavigation Controller Enabled\r\n"), 0x80);
522 }
else if (remote_name[0] ==
'M') {
523 timerBulbRumble = millis();
524 #ifdef DEBUG_USB_HOST
525 Notify(PSTR(
"\r\nMotion Controller Enabled\r\n"), 0x80);
531 ButtonClickState = 0;
540 if (millis() - timerBulbRumble > 4000) {
542 timerBulbRumble = millis();
555 void PS3BT::HID_Command(uint8_t* data, uint8_t nbytes) {
556 if (millis() - timerHID <= 250)
557 delay((uint32_t)(250 - (millis() - timerHID)));
558 pBtd->
L2CAP_Command(hci_handle, data, nbytes, control_scid[0], control_scid[1]);
579 uint8_t power[2] = { 0xff, 0x00 };
587 void PS3BT::setRumbleOn(uint8_t rightDuration, uint8_t rightPower, uint8_t leftDuration, uint8_t leftPower) {
588 HIDBuffer[3] = rightDuration;
589 HIDBuffer[4] = rightPower;
590 HIDBuffer[5] = leftDuration;
591 HIDBuffer[6] = leftPower;
596 HIDBuffer[11] = value << 1;
600 HIDBuffer[11] &= ~((uint8_t)((pgm_read_byte(&
LEDS[(uint8_t)a]) & 0x0f) << 1));
605 HIDBuffer[11] |= (uint8_t)((pgm_read_byte(&
LEDS[(uint8_t)a]) & 0x0f) << 1);
610 HIDBuffer[11] ^= (uint8_t)((pgm_read_byte(&
LEDS[(uint8_t)a]) & 0x0f) << 1);
614 void PS3BT::enable_sixaxis() {
623 HID_Command(cmd_buf, 6);
628 void PS3BT::HIDMove_Command(uint8_t* data, uint8_t nbytes) {
629 if (millis() - timerHID <= 250)
630 delay((uint32_t)(250 - (millis() - timerHID)));
631 pBtd->
L2CAP_Command(hci_handle, data, nbytes, interrupt_scid[0], interrupt_scid[1]);
637 HIDMoveBuffer[3] = r;
638 HIDMoveBuffer[4] = g;
639 HIDMoveBuffer[5] = b;
645 moveSetBulb((uint8_t)(color >> 16), (uint8_t)(color >> 8), (uint8_t)(color));
649 #ifdef DEBUG_USB_HOST
650 if (rumble < 64 && rumble != 0)
651 Notify(PSTR(
"\r\nThe rumble value has to at least 64, or approximately 25%"), 0x80);
654 HIDMoveBuffer[7] = rumble;
659 void PS3BT::onInit() {
#define L2CAP_FLAG_CONFIG_CONTROL_REQUEST
uint8_t getAnalogHat(AnalogHat a)
bool getButtonClick(Button b)
bool PS3NavigationConnected
#define L2CAP_FLAG_DISCONNECT_CONTROL_RESPONSE
void l2cap_connection_response(uint16_t handle, uint8_t rxid, uint8_t *dcid, uint8_t *scid, uint8_t result)
void l2cap_disconnection_request(uint16_t handle, uint8_t rxid, uint8_t *dcid, uint8_t *scid)
#define l2cap_config_request_interrupt_flag
const uint8_t PS3_REPORT_BUFFER[]
#define L2CAP_INTERRUPT_REQUEST
void moveSetRumble(uint8_t rumble)
const uint8_t ANALOGBUTTONS[]
#define l2cap_connection_request_control_flag
int16_t getSensor(Sensor a)
double get9DOFValues(Sensor a)
#define L2CAP_INTERRUPT_SETUP
#define L2CAP_INTERRUPT_SUCCESS
#define l2cap_config_request_control_flag
void l2cap_disconnection_response(uint16_t handle, uint8_t rxid, uint8_t *dcid, uint8_t *scid)
#define L2CAP_FLAG_CONFIG_INTERRUPT_REQUEST
#define L2CAP_CONTROL_DISCONNECT
#define L2CAP_CONTROL_REQUEST
#define l2cap_disconnect_response_control_flag
#define L2CAP_FLAG_DISCONNECT_INTERRUPT_RESPONSE
#define L2CAP_INTERRUPT_DISCONNECT
void hci_disconnect(uint16_t handle)
void moveSetBulb(uint8_t r, uint8_t g, uint8_t b)
#define L2CAP_FLAG_CONNECTION_CONTROL_REQUEST
#define l2cap_disconnect_response_interrupt_flag
#define l2cap_connection_request_interrupt_flag
#define L2CAP_CMD_CONFIG_REQUEST
#define L2CAP_CMD_DISCONNECT_REQUEST
#define L2CAP_FLAG_CONFIG_INTERRUPT_SUCCESS
#define L2CAP_FLAG_CONNECTION_INTERRUPT_REQUEST
int8_t registerServiceClass(BluetoothService *pService)
bool l2capConnectionClaimed
#define L2CAP_CMD_DISCONNECT_RESPONSE
virtual void ACLData(uint8_t *ACLData)
#define L2CAP_CMD_CONFIG_RESPONSE
#define L2CAP_HID_ENABLE_SIXAXIS
#define l2cap_config_success_interrupt_flag
#define l2cap_config_success_control_flag
#define L2CAP_HID_PS3_LED
void setRumbleOn(Rumble mode)
#define PS3_REPORT_BUFFER_SIZE
#define L2CAP_CONTROL_SUCCESS
virtual void disconnect()
void L2CAP_Command(uint16_t handle, uint8_t *data, uint8_t nbytes, uint8_t channelLow=0x01, uint8_t channelHigh=0x00)
void l2cap_config_response(uint16_t handle, uint8_t rxid, uint8_t *scid)
void l2cap_config_request(uint16_t handle, uint8_t rxid, uint8_t *dcid)
#define L2CAP_CMD_CONNECTION_REQUEST
uint8_t getAnalogButton(Button a)
void setLedRaw(uint8_t value)
PS3BT(BTD *pBtd, uint8_t btadr5=0, uint8_t btadr4=0, uint8_t btadr3=0, uint8_t btadr2=0, uint8_t btadr1=0, uint8_t btadr0=0)
bool getButtonPress(Button b)
#define L2CAP_FLAG_CONFIG_CONTROL_SUCCESS
#define L2CAP_CMD_COMMAND_REJECT