23 PS3BT::PS3BT(
BTD *p, uint8_t btadr5, uint8_t btadr4, uint8_t btadr3, uint8_t btadr2, uint8_t btadr1, uint8_t btadr0) :
37 HIDMoveBuffer[0] = 0xA2;
38 HIDMoveBuffer[1] = 0x02;
41 control_dcid[0] = 0x40;
42 control_dcid[1] = 0x00;
43 interrupt_dcid[0] = 0x41;
44 interrupt_dcid[1] = 0x00;
55 bool click = (ButtonClickState & button);
56 ButtonClickState &= ~button;
65 return (uint8_t)(l2capinbuf[(uint8_t)a + 15]);
70 if(a ==
aX || a ==
aY || a ==
aZ || a ==
gZ)
71 return ((l2capinbuf[(uint16_t)a] << 8) | l2capinbuf[(uint16_t)a + 1]);
76 return (((l2capinbuf[(uint16_t)a] & 0x0F) << 8) | (l2capinbuf[(uint16_t)a + 1]));
78 return ((l2capinbuf[(uint16_t)a] << 4) | ((l2capinbuf[(uint16_t)a + 1] & 0xF0) >> 4));
80 return (l2capinbuf[(uint16_t)a] | (l2capinbuf[(uint16_t)a + 1] << 8));
86 float accXval, accYval, accZval;
90 const float zeroG = 511.5f;
96 const uint16_t zeroG = 0x8000;
107 return (atan2f(accYval, accZval) + PI) * RAD_TO_DEG;
109 return (atan2f(accXval, accZval) + PI) * RAD_TO_DEG;
119 return (
float)value / 3.2f;
125 return (
float)value / 442.0f;
132 return (
float)value / 11.6f;
134 return (
float)value / 11.2f;
136 return (
float)value / 9.6f;
145 String output = String(input / 100);
149 output += String(input % 100);
157 return (l2capinbuf[(uint16_t)c >> 8] == ((uint8_t)c & 0xff));
161 char statusOutput[102];
208 activeConnection =
false;
227 if((ACLData[12] | (ACLData[13] << 8)) ==
HID_CTRL_PSM) {
229 activeConnection =
true;
233 #ifdef DEBUG_USB_HOST
235 Notify(
PSTR(
"\r\nYour dongle may not support reading the analog buttons, sensors and status\r\nYour HCI Version is: "), 0x80);
237 Notify(
PSTR(
"\r\nBut should be at least 3\r\nThis means that it doesn't support Bluetooth Version 2.0+EDR"), 0x80);
246 if((l2capinbuf[6] | (l2capinbuf[7] << 8)) == 0x0001U) {
248 #ifdef DEBUG_USB_HOST
249 Notify(
PSTR(
"\r\nL2CAP Command Rejected - Reason: "), 0x80);
250 D_PrintHex<uint8_t > (l2capinbuf[13], 0x80);
252 D_PrintHex<uint8_t > (l2capinbuf[12], 0x80);
254 D_PrintHex<uint8_t > (l2capinbuf[17], 0x80);
256 D_PrintHex<uint8_t > (l2capinbuf[16], 0x80);
258 D_PrintHex<uint8_t > (l2capinbuf[15], 0x80);
260 D_PrintHex<uint8_t > (l2capinbuf[14], 0x80);
264 Notify(
PSTR(
"\r\nL2CAP Connection Request - PSM: "), 0x80);
265 D_PrintHex<uint8_t > (l2capinbuf[13], 0x80);
267 D_PrintHex<uint8_t > (l2capinbuf[12], 0x80);
269 D_PrintHex<uint8_t > (l2capinbuf[15], 0x80);
271 D_PrintHex<uint8_t > (l2capinbuf[14], 0x80);
273 D_PrintHex<uint8_t > (l2capinbuf[9], 0x80);
275 if((l2capinbuf[12] | (l2capinbuf[13] << 8)) ==
HID_CTRL_PSM) {
277 control_scid[0] = l2capinbuf[14];
278 control_scid[1] = l2capinbuf[15];
280 }
else if((l2capinbuf[12] | (l2capinbuf[13] << 8)) ==
HID_INTR_PSM) {
282 interrupt_scid[0] = l2capinbuf[14];
283 interrupt_scid[1] = l2capinbuf[15];
287 if((l2capinbuf[16] | (l2capinbuf[17] << 8)) == 0x0000) {
288 if(l2capinbuf[12] == control_dcid[0] && l2capinbuf[13] == control_dcid[1]) {
291 }
else if(l2capinbuf[12] == interrupt_dcid[0] && l2capinbuf[13] == interrupt_dcid[1]) {
297 if(l2capinbuf[12] == control_dcid[0] && l2capinbuf[13] == control_dcid[1]) {
300 }
else if(l2capinbuf[12] == interrupt_dcid[0] && l2capinbuf[13] == interrupt_dcid[1]) {
305 if(l2capinbuf[12] == control_dcid[0] && l2capinbuf[13] == control_dcid[1]) {
306 #ifdef DEBUG_USB_HOST
307 Notify(
PSTR(
"\r\nDisconnect Request: Control Channel"), 0x80);
312 }
else if(l2capinbuf[12] == interrupt_dcid[0] && l2capinbuf[13] == interrupt_dcid[1]) {
313 #ifdef DEBUG_USB_HOST
314 Notify(
PSTR(
"\r\nDisconnect Request: Interrupt Channel"), 0x80);
321 if(l2capinbuf[12] == control_scid[0] && l2capinbuf[13] == control_scid[1]) {
325 }
else if(l2capinbuf[12] == interrupt_scid[0] && l2capinbuf[13] == interrupt_scid[1]) {
333 Notify(
PSTR(
"\r\nL2CAP Unknown Signaling Command: "), 0x80);
334 D_PrintHex<uint8_t > (l2capinbuf[8], 0x80);
337 }
else if(l2capinbuf[6] == interrupt_dcid[0] && l2capinbuf[7] == interrupt_dcid[1]) {
341 if(l2capinbuf[8] == 0xA1) {
342 lastMessageTime = (uint32_t)millis();
345 ButtonState = (uint32_t)(l2capinbuf[11] | ((uint16_t)l2capinbuf[12] << 8) | ((uint32_t)l2capinbuf[13] << 16));
347 ButtonState = (uint32_t)(l2capinbuf[10] | ((uint16_t)l2capinbuf[11] << 8) | ((uint32_t)l2capinbuf[12] << 16));
352 if(ButtonState != OldButtonState) {
353 ButtonClickState = ButtonState & ~OldButtonState;
354 OldButtonState = ButtonState;
357 #ifdef PRINTREPORT // Uncomment "#define PRINTREPORT" to print the report send by the PS3 Controllers
358 for(uint8_t i = 10; i < 58; i++) {
359 D_PrintHex<uint8_t > (l2capinbuf[i], 0x80);
371 void PS3BT::L2CAP_task() {
372 switch(l2cap_state) {
375 #ifdef DEBUG_USB_HOST
376 Notify(
PSTR(
"\r\nHID Control Incoming Connection Request"), 0x80);
390 #ifdef DEBUG_USB_HOST
391 Notify(
PSTR(
"\r\nHID Control Successfully Configured"), 0x80);
399 #ifdef DEBUG_USB_HOST
400 Notify(
PSTR(
"\r\nHID Interrupt Incoming Connection Request"), 0x80);
415 #ifdef DEBUG_USB_HOST
416 Notify(
PSTR(
"\r\nHID Interrupt Successfully Configured"), 0x80);
418 if(remote_name_first ==
'M') {
423 timer = (uint32_t)millis();
431 #ifdef DEBUG_USB_HOST
432 Notify(
PSTR(
"\r\nDisconnected Interrupt Channel"), 0x80);
442 #ifdef DEBUG_USB_HOST
443 Notify(
PSTR(
"\r\nDisconnected Control Channel"), 0x80);
455 switch(l2cap_state) {
457 if((int32_t)((uint32_t)millis() - timer) > 1000) {
459 for(uint8_t i = 15; i < 19; i++)
460 l2capinbuf[i] = 0x7F;
463 timer = (uint32_t)millis();
468 if((int32_t)((uint32_t)millis() - timer) > 1000) {
469 if(remote_name_first ==
'P') {
470 #ifdef DEBUG_USB_HOST
471 Notify(
PSTR(
"\r\nDualshock 3 Controller Enabled\r\n"), 0x80);
474 }
else if(remote_name_first ==
'N') {
475 #ifdef DEBUG_USB_HOST
476 Notify(
PSTR(
"\r\nNavigation Controller Enabled\r\n"), 0x80);
479 }
else if(remote_name_first ==
'M') {
480 timer = (uint32_t)millis();
481 #ifdef DEBUG_USB_HOST
482 Notify(
PSTR(
"\r\nMotion Controller Enabled\r\n"), 0x80);
488 ButtonClickState = 0;
497 if((int32_t)((uint32_t)millis() - timer) > 4000) {
499 timer = (uint32_t)millis();
512 void PS3BT::HID_Command(uint8_t* data, uint8_t nbytes) {
513 if((int32_t)((uint32_t)millis() - timerHID) <= 150)
514 delay((uint32_t)(150 - ((uint32_t)millis() - timerHID)));
516 timerHID = (uint32_t)millis();
525 HIDBuffer[11] = 0x00;
541 uint8_t power[2] = {0xff, 0x00};
549 void PS3BT::setRumbleOn(uint8_t rightDuration, uint8_t rightPower, uint8_t leftDuration, uint8_t leftPower) {
552 rumbleBuf[3] = rightDuration;
553 rumbleBuf[4] = rightPower;
554 rumbleBuf[5] = leftDuration;
555 rumbleBuf[6] = leftPower;
560 HIDBuffer[11] = value << 1;
583 void PS3BT::enable_sixaxis() {
592 HID_Command(cmd_buf, 6);
597 void PS3BT::HIDMove_Command(uint8_t* data, uint8_t nbytes) {
598 if((int32_t)((uint32_t)millis() - timerHID) <= 150)
599 delay((uint32_t)(150 - ((uint32_t)millis() - timerHID)));
601 timerHID = (uint32_t)millis();
606 HIDMoveBuffer[3] = r;
607 HIDMoveBuffer[4] = g;
608 HIDMoveBuffer[5] = b;
614 moveSetBulb((uint8_t)(color >> 16), (uint8_t)(color >> 8), (uint8_t)(color));
618 #ifdef DEBUG_USB_HOST
619 if(rumble < 64 && rumble != 0)
620 Notify(
PSTR(
"\r\nThe rumble value has to at least 64, or approximately 25%"), 0x80);
623 HIDMoveBuffer[7] = rumble;
#define L2CAP_FLAG_DISCONNECT_CONTROL_RESPONSE
void(* pFuncOnInit)(void)
#define pgm_read_dword(addr)
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 strcpy_P(dest, src)
#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
#define pgm_read_byte(addr)
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)
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)
float get9DOFValues(SensorEnum a)
#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[]
bool l2capConnectionClaimed
#define PS3_ENABLE_SIXAXIS
#define L2CAP_CMD_DISCONNECT_RESPONSE
void ACLData(uint8_t *ACLData)
#define L2CAP_CMD_CONFIG_RESPONSE
#define strcat_P(dest, src)
void setLedToggle(LEDEnum a)
uint32_t l2cap_event_flag
#define PS3_REPORT_BUFFER_SIZE
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
uint8_t getAnalogButton(ButtonEnum a)
float getAngle(AngleEnum 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 checkHciHandle(uint8_t *buf, uint16_t handle)
#define L2CAP_INTERRUPT_DISCONNECT
bool getButtonClick(ButtonEnum b)
const uint8_t PS3_REPORT_BUFFER[PS3_REPORT_BUFFER_SIZE]
#define L2CAP_CMD_COMMAND_REJECT