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(&
PS3_BUTTONS[(uint8_t)b]));
57 uint32_t button = pgm_read_dword(&
PS3_BUTTONS[(uint8_t)b]);
58 bool click = (ButtonClickState & button);
59 ButtonClickState &= ~button;
68 return (uint8_t)(l2capinbuf[(uint8_t)a + 15]);
73 if(a ==
aX || a ==
aY || a ==
aZ || a ==
gZ)
74 return ((l2capinbuf[(uint16_t)a] << 8) | l2capinbuf[(uint16_t)a + 1]);
79 return (((l2capinbuf[(uint16_t)a] & 0x0F) << 8) | (l2capinbuf[(uint16_t)a + 1]));
81 return ((l2capinbuf[(uint16_t)a] << 4) | ((l2capinbuf[(uint16_t)a + 1] & 0xF0) >> 4));
83 return (l2capinbuf[(uint16_t)a] | (l2capinbuf[(uint16_t)a + 1] << 8));
89 double accXval, accYval, accZval;
93 const double zeroG = 511.5;
99 const uint16_t zeroG = 0x8000;
110 return (atan2(accYval, accZval) + PI) * RAD_TO_DEG;
112 return (atan2(accXval, accZval) + PI) * RAD_TO_DEG;
122 return (
double)value / 3.2;
128 return (
double)value / 442.0;
135 return (
double)value / 11.6;
137 return (
double)value / 11.2;
139 return (
double)value / 9.6;
148 String output = String(input / 100);
152 output += String(input % 100);
160 return (l2capinbuf[(uint16_t)c >> 8] == ((uint8_t)c & 0xff));
164 char statusOutput[100];
166 strcpy_P(statusOutput, PSTR(
"ConnectionStatus: "));
170 else strcat_P(statusOutput, PSTR(
"Error"));
172 strcat_P(statusOutput, PSTR(
" - PowerRating: "));
178 else if(
getStatus(
Low)) strcat_P(statusOutput, PSTR(
"Low"));
179 else if(
getStatus(
High)) strcat_P(statusOutput, PSTR(
"High"));
180 else if(
getStatus(
Full)) strcat_P(statusOutput, PSTR(
"Full"));
181 else strcat_P(statusOutput, PSTR(
"Error"));
183 strcat_P(statusOutput, PSTR(
" - WirelessStatus: "));
186 else if(
getStatus(
Cable)) strcat_P(statusOutput, PSTR(
"Cable - Rumble is off"));
188 else if(
getStatus(
Bluetooth)) strcat_P(statusOutput, PSTR(
"Bluetooth - Rumble is off"));
189 else strcat_P(statusOutput, PSTR(
"Error"));
191 strcpy_P(statusOutput, PSTR(
"PowerRating: "));
200 else strcat_P(statusOutput, PSTR(
"Error"));
202 strcpy_P(statusOutput, PSTR(
"Error"));
211 activeConnection =
false;
212 l2cap_event_flag = 0;
230 if((ACLData[12] | (ACLData[13] << 8)) ==
HID_CTRL_PSM) {
232 activeConnection =
true;
235 for(uint8_t i = 0; i < 30; i++)
237 #ifdef DEBUG_USB_HOST
239 Notify(PSTR(
"\r\nYour dongle may not support reading the analog buttons, sensors and status\r\nYour HCI Version is: "), 0x80);
241 Notify(PSTR(
"\r\nBut should be at least 3\r\nThis means that it doesn't support Bluetooth Version 2.0+EDR"), 0x80);
250 if((l2capinbuf[6] | (l2capinbuf[7] << 8)) == 0x0001U) {
252 #ifdef DEBUG_USB_HOST
253 Notify(PSTR(
"\r\nL2CAP Command Rejected - Reason: "), 0x80);
254 D_PrintHex<uint8_t > (l2capinbuf[13], 0x80);
256 D_PrintHex<uint8_t > (l2capinbuf[12], 0x80);
257 Notify(PSTR(
" Data: "), 0x80);
258 D_PrintHex<uint8_t > (l2capinbuf[17], 0x80);
260 D_PrintHex<uint8_t > (l2capinbuf[16], 0x80);
262 D_PrintHex<uint8_t > (l2capinbuf[15], 0x80);
264 D_PrintHex<uint8_t > (l2capinbuf[14], 0x80);
268 Notify(PSTR(
"\r\nL2CAP Connection Request - PSM: "), 0x80);
269 D_PrintHex<uint8_t > (l2capinbuf[13], 0x80);
271 D_PrintHex<uint8_t > (l2capinbuf[12], 0x80);
272 Notify(PSTR(
" SCID: "), 0x80);
273 D_PrintHex<uint8_t > (l2capinbuf[15], 0x80);
275 D_PrintHex<uint8_t > (l2capinbuf[14], 0x80);
276 Notify(PSTR(
" Identifier: "), 0x80);
277 D_PrintHex<uint8_t > (l2capinbuf[9], 0x80);
279 if((l2capinbuf[12] | (l2capinbuf[13] << 8)) ==
HID_CTRL_PSM) {
280 identifier = l2capinbuf[9];
281 control_scid[0] = l2capinbuf[14];
282 control_scid[1] = l2capinbuf[15];
284 }
else if((l2capinbuf[12] | (l2capinbuf[13] << 8)) ==
HID_INTR_PSM) {
285 identifier = l2capinbuf[9];
286 interrupt_scid[0] = l2capinbuf[14];
287 interrupt_scid[1] = l2capinbuf[15];
291 if((l2capinbuf[16] | (l2capinbuf[17] << 8)) == 0x0000) {
292 if(l2capinbuf[12] == control_dcid[0] && l2capinbuf[13] == control_dcid[1]) {
295 }
else if(l2capinbuf[12] == interrupt_dcid[0] && l2capinbuf[13] == interrupt_dcid[1]) {
301 if(l2capinbuf[12] == control_dcid[0] && l2capinbuf[13] == control_dcid[1]) {
304 }
else if(l2capinbuf[12] == interrupt_dcid[0] && l2capinbuf[13] == interrupt_dcid[1]) {
309 if(l2capinbuf[12] == control_dcid[0] && l2capinbuf[13] == control_dcid[1]) {
310 #ifdef DEBUG_USB_HOST
311 Notify(PSTR(
"\r\nDisconnect Request: Control Channel"), 0x80);
313 identifier = l2capinbuf[9];
316 }
else if(l2capinbuf[12] == interrupt_dcid[0] && l2capinbuf[13] == interrupt_dcid[1]) {
317 #ifdef DEBUG_USB_HOST
318 Notify(PSTR(
"\r\nDisconnect Request: Interrupt Channel"), 0x80);
320 identifier = l2capinbuf[9];
325 if(l2capinbuf[12] == control_scid[0] && l2capinbuf[13] == control_scid[1]) {
327 identifier = l2capinbuf[9];
329 }
else if(l2capinbuf[12] == interrupt_scid[0] && l2capinbuf[13] == interrupt_scid[1]) {
331 identifier = l2capinbuf[9];
337 Notify(PSTR(
"\r\nL2CAP Unknown Signaling Command: "), 0x80);
338 D_PrintHex<uint8_t > (l2capinbuf[8], 0x80);
341 }
else if(l2capinbuf[6] == interrupt_dcid[0] && l2capinbuf[7] == interrupt_dcid[1]) {
345 if(l2capinbuf[8] == 0xA1) {
347 ButtonState = (uint32_t)(l2capinbuf[11] | ((uint16_t)l2capinbuf[12] << 8) | ((uint32_t)l2capinbuf[13] << 16));
349 ButtonState = (uint32_t)(l2capinbuf[10] | ((uint16_t)l2capinbuf[11] << 8) | ((uint32_t)l2capinbuf[12] << 16));
354 if(ButtonState != OldButtonState) {
355 ButtonClickState = ButtonState & ~OldButtonState;
356 OldButtonState = ButtonState;
359 #ifdef PRINTREPORT // Uncomment "#define PRINTREPORT" to print the report send by the PS3 Controllers
360 for(uint8_t i = 10; i < 58; i++) {
361 D_PrintHex<uint8_t > (l2capinbuf[i], 0x80);
364 Notify(PSTR(
"\r\n"), 0x80);
373 void PS3BT::L2CAP_task() {
374 switch(l2cap_state) {
377 #ifdef DEBUG_USB_HOST
378 Notify(PSTR(
"\r\nHID Control Incoming Connection Request"), 0x80);
392 #ifdef DEBUG_USB_HOST
393 Notify(PSTR(
"\r\nHID Control Successfully Configured"), 0x80);
401 #ifdef DEBUG_USB_HOST
402 Notify(PSTR(
"\r\nHID Interrupt Incoming Connection Request"), 0x80);
417 #ifdef DEBUG_USB_HOST
418 Notify(PSTR(
"\r\nHID Interrupt Successfully Configured"), 0x80);
420 if(remote_name[0] ==
'M') {
433 #ifdef DEBUG_USB_HOST
434 Notify(PSTR(
"\r\nDisconnected Interrupt Channel"), 0x80);
444 #ifdef DEBUG_USB_HOST
445 Notify(PSTR(
"\r\nDisconnected Control Channel"), 0x80);
449 l2cap_event_flag = 0;
457 switch(l2cap_state) {
459 if(millis() - timer > 1000) {
461 for(uint8_t i = 15; i < 19; i++)
462 l2capinbuf[i] = 0x7F;
470 if(millis() - timer > 1000) {
471 if(remote_name[0] ==
'P') {
472 #ifdef DEBUG_USB_HOST
473 Notify(PSTR(
"\r\nDualshock 3 Controller Enabled\r\n"), 0x80);
476 }
else if(remote_name[0] ==
'N') {
477 #ifdef DEBUG_USB_HOST
478 Notify(PSTR(
"\r\nNavigation Controller Enabled\r\n"), 0x80);
481 }
else if(remote_name[0] ==
'M') {
482 timerBulbRumble = millis();
483 #ifdef DEBUG_USB_HOST
484 Notify(PSTR(
"\r\nMotion Controller Enabled\r\n"), 0x80);
490 ButtonClickState = 0;
499 if(millis() - timerBulbRumble > 4000) {
501 timerBulbRumble = millis();
514 void PS3BT::HID_Command(uint8_t* data, uint8_t nbytes) {
515 if(millis() - timerHID <= 150)
516 delay((uint32_t)(150 - (millis() - timerHID)));
517 pBtd->
L2CAP_Command(hci_handle, data, nbytes, control_scid[0], control_scid[1]);
527 HIDBuffer[11] = 0x00;
542 uint8_t power[2] = {0xff, 0x00};
550 void PS3BT::setRumbleOn(uint8_t rightDuration, uint8_t rightPower, uint8_t leftDuration, uint8_t leftPower) {
551 HIDBuffer[3] = rightDuration;
552 HIDBuffer[4] = rightPower;
553 HIDBuffer[5] = leftDuration;
554 HIDBuffer[6] = leftPower;
559 HIDBuffer[11] = value << 1;
564 HIDBuffer[11] &= ~((uint8_t)((pgm_read_byte(&
PS3_LEDS[(uint8_t)a]) & 0x0f) << 1));
572 HIDBuffer[11] |= (uint8_t)((pgm_read_byte(&
PS3_LEDS[(uint8_t)a]) & 0x0f) << 1);
578 HIDBuffer[11] ^= (uint8_t)((pgm_read_byte(&
PS3_LEDS[(uint8_t)a]) & 0x0f) << 1);
582 void PS3BT::enable_sixaxis() {
591 HID_Command(cmd_buf, 6);
596 void PS3BT::HIDMove_Command(uint8_t* data, uint8_t nbytes) {
597 if(millis() - timerHID <= 150)
598 delay((uint32_t)(150 - (millis() - timerHID)));
599 pBtd->
L2CAP_Command(hci_handle, data, nbytes, interrupt_scid[0], interrupt_scid[1]);
605 HIDMoveBuffer[3] = r;
606 HIDMoveBuffer[4] = g;
607 HIDMoveBuffer[5] = b;
613 moveSetBulb((uint8_t)(color >> 16), (uint8_t)(color >> 8), (uint8_t)(color));
617 #ifdef DEBUG_USB_HOST
618 if(rumble < 64 && rumble != 0)
619 Notify(PSTR(
"\r\nThe rumble value has to at least 64, or approximately 25%"), 0x80);
622 HIDMoveBuffer[7] = rumble;
627 void PS3BT::onInit() {
#define L2CAP_FLAG_DISCONNECT_CONTROL_RESPONSE
#define UHS_ACL_HANDLE_OK(x, y)
bool PS3NavigationConnected
#define L2CAP_FLAG_CONFIG_INTERRUPT_SUCCESS
#define L2CAP_INTERRUPT_CONFIG_REQUEST
#define L2CAP_INTERRUPT_SETUP
bool getStatus(StatusEnum c)
void l2cap_connection_response(uint16_t handle, uint8_t rxid, uint8_t *dcid, uint8_t *scid, uint8_t result)
#define L2CAP_FLAG_CONNECTION_INTERRUPT_REQUEST
void l2cap_disconnection_request(uint16_t handle, uint8_t rxid, uint8_t *dcid, uint8_t *scid)
void moveSetRumble(uint8_t rumble)
#define L2CAP_CONTROL_SUCCESS
const uint32_t PS3_BUTTONS[]
bool getButtonPress(ButtonEnum b)
int16_t getSensor(SensorEnum a)
void l2cap_disconnection_response(uint16_t handle, uint8_t rxid, uint8_t *dcid, uint8_t *scid)
double getAngle(AngleEnum a)
uint8_t getAnalogHat(AnalogHatEnum a)
void hci_disconnect(uint16_t handle)
#define L2CAP_FLAG_DISCONNECT_INTERRUPT_RESPONSE
void moveSetBulb(uint8_t r, uint8_t g, uint8_t b)
void setRumbleOn(RumbleEnum mode)
#define l2cap_check_flag(flag)
#define L2CAP_CMD_CONFIG_REQUEST
#define L2CAP_CMD_DISCONNECT_REQUEST
#define L2CAP_CONTROL_DISCONNECT
#define L2CAP_FLAG_CONNECTION_CONTROL_REQUEST
const uint8_t PS3_ANALOG_BUTTONS[]
int8_t registerServiceClass(BluetoothService *pService)
bool l2capConnectionClaimed
#define PS3_ENABLE_SIXAXIS
#define L2CAP_CMD_DISCONNECT_RESPONSE
virtual void ACLData(uint8_t *ACLData)
#define L2CAP_CMD_CONFIG_RESPONSE
void setLedToggle(LEDEnum a)
#define PS3_REPORT_BUFFER_SIZE
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)
#define l2cap_set_flag(flag)
void l2cap_config_request(uint16_t handle, uint8_t rxid, uint8_t *dcid)
#define L2CAP_FLAG_CONFIG_CONTROL_SUCCESS
#define L2CAP_CMD_CONNECTION_REQUEST
double get9DOFValues(SensorEnum a)
uint8_t getAnalogButton(ButtonEnum 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)
#define L2CAP_INTERRUPT_DISCONNECT
bool getButtonClick(ButtonEnum b)
const uint8_t PS3_REPORT_BUFFER[PS3_REPORT_BUFFER_SIZE]
#define L2CAP_CMD_COMMAND_REJECT