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;
57 bool click = (ButtonClickState & button);
58 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 float accXval, accYval, accZval;
93 const float zeroG = 511.5f;
99 const uint16_t zeroG = 0x8000;
110 return (atan2f(accYval, accZval) + PI) * RAD_TO_DEG;
112 return (atan2f(accXval, accZval) + PI) * RAD_TO_DEG;
122 return (
float)value / 3.2f;
128 return (
float)value / 442.0f;
135 return (
float)value / 11.6f;
137 return (
float)value / 11.2f;
139 return (
float)value / 9.6f;
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[102];
211 activeConnection =
false;
232 activeConnection =
true;
236 #ifdef DEBUG_USB_HOST
238 Notify(
PSTR(
"\r\nYour dongle may not support reading the analog buttons, sensors and status\r\nYour HCI Version is: "), 0x80);
240 Notify(
PSTR(
"\r\nBut should be at least 3\r\nThis means that it doesn't support Bluetooth Version 2.0+EDR"), 0x80);
249 if((l2capinbuf[6] | (l2capinbuf[7] << 8)) == 0x0001U) {
251 #ifdef DEBUG_USB_HOST
252 Notify(
PSTR(
"\r\nL2CAP Command Rejected - Reason: "), 0x80);
253 D_PrintHex<uint8_t > (l2capinbuf[13], 0x80);
255 D_PrintHex<uint8_t > (l2capinbuf[12], 0x80);
257 D_PrintHex<uint8_t > (l2capinbuf[17], 0x80);
259 D_PrintHex<uint8_t > (l2capinbuf[16], 0x80);
261 D_PrintHex<uint8_t > (l2capinbuf[15], 0x80);
263 D_PrintHex<uint8_t > (l2capinbuf[14], 0x80);
267 Notify(
PSTR(
"\r\nL2CAP Connection Request - PSM: "), 0x80);
268 D_PrintHex<uint8_t > (l2capinbuf[13], 0x80);
270 D_PrintHex<uint8_t > (l2capinbuf[12], 0x80);
272 D_PrintHex<uint8_t > (l2capinbuf[15], 0x80);
274 D_PrintHex<uint8_t > (l2capinbuf[14], 0x80);
276 D_PrintHex<uint8_t > (l2capinbuf[9], 0x80);
278 if((l2capinbuf[12] | (l2capinbuf[13] << 8)) ==
HID_CTRL_PSM) {
280 control_scid[0] = l2capinbuf[14];
281 control_scid[1] = l2capinbuf[15];
283 }
else if((l2capinbuf[12] | (l2capinbuf[13] << 8)) ==
HID_INTR_PSM) {
285 interrupt_scid[0] = l2capinbuf[14];
286 interrupt_scid[1] = l2capinbuf[15];
290 if((l2capinbuf[16] | (l2capinbuf[17] << 8)) == 0x0000) {
291 if(l2capinbuf[12] == control_dcid[0] && l2capinbuf[13] == control_dcid[1]) {
294 }
else if(l2capinbuf[12] == interrupt_dcid[0] && l2capinbuf[13] == interrupt_dcid[1]) {
300 if(l2capinbuf[12] == control_dcid[0] && l2capinbuf[13] == control_dcid[1]) {
303 }
else if(l2capinbuf[12] == interrupt_dcid[0] && l2capinbuf[13] == interrupt_dcid[1]) {
308 if(l2capinbuf[12] == control_dcid[0] && l2capinbuf[13] == control_dcid[1]) {
309 #ifdef DEBUG_USB_HOST
310 Notify(
PSTR(
"\r\nDisconnect Request: Control Channel"), 0x80);
315 }
else if(l2capinbuf[12] == interrupt_dcid[0] && l2capinbuf[13] == interrupt_dcid[1]) {
316 #ifdef DEBUG_USB_HOST
317 Notify(
PSTR(
"\r\nDisconnect Request: Interrupt Channel"), 0x80);
324 if(l2capinbuf[12] == control_scid[0] && l2capinbuf[13] == control_scid[1]) {
328 }
else if(l2capinbuf[12] == interrupt_scid[0] && l2capinbuf[13] == interrupt_scid[1]) {
336 Notify(
PSTR(
"\r\nL2CAP Unknown Signaling Command: "), 0x80);
337 D_PrintHex<uint8_t > (l2capinbuf[8], 0x80);
340 }
else if(l2capinbuf[6] == interrupt_dcid[0] && l2capinbuf[7] == interrupt_dcid[1]) {
344 if(l2capinbuf[8] == 0xA1) {
345 lastMessageTime = (uint32_t)millis();
348 ButtonState = (uint32_t)(l2capinbuf[11] | ((uint16_t)l2capinbuf[12] << 8) | ((uint32_t)l2capinbuf[13] << 16));
350 ButtonState = (uint32_t)(l2capinbuf[10] | ((uint16_t)l2capinbuf[11] << 8) | ((uint32_t)l2capinbuf[12] << 16));
355 if(ButtonState != OldButtonState) {
356 ButtonClickState = ButtonState & ~OldButtonState;
357 OldButtonState = ButtonState;
361 for(uint8_t i = 10; i < 58; i++) {
362 D_PrintHex<uint8_t > (l2capinbuf[i], 0x80);
374 void PS3BT::L2CAP_task() {
375 switch(l2cap_state) {
378 #ifdef DEBUG_USB_HOST
379 Notify(
PSTR(
"\r\nHID Control Incoming Connection Request"), 0x80);
393 #ifdef DEBUG_USB_HOST
394 Notify(
PSTR(
"\r\nHID Control Successfully Configured"), 0x80);
402 #ifdef DEBUG_USB_HOST
403 Notify(
PSTR(
"\r\nHID Interrupt Incoming Connection Request"), 0x80);
418 #ifdef DEBUG_USB_HOST
419 Notify(
PSTR(
"\r\nHID Interrupt Successfully Configured"), 0x80);
421 if(remote_name_first ==
'M') {
426 timer = (uint32_t)millis();
434 #ifdef DEBUG_USB_HOST
435 Notify(
PSTR(
"\r\nDisconnected Interrupt Channel"), 0x80);
445 #ifdef DEBUG_USB_HOST
446 Notify(
PSTR(
"\r\nDisconnected Control Channel"), 0x80);
458 switch(l2cap_state) {
460 if((int32_t)((uint32_t)millis() - timer) > 1000) {
462 for(uint8_t i = 15; i < 19; i++)
463 l2capinbuf[i] = 0x7F;
466 timer = (uint32_t)millis();
471 if((int32_t)((uint32_t)millis() - timer) > 1000) {
472 if(remote_name_first ==
'P') {
473 #ifdef DEBUG_USB_HOST
474 Notify(
PSTR(
"\r\nDualshock 3 Controller Enabled\r\n"), 0x80);
477 }
else if(remote_name_first ==
'N') {
478 #ifdef DEBUG_USB_HOST
479 Notify(
PSTR(
"\r\nNavigation Controller Enabled\r\n"), 0x80);
482 }
else if(remote_name_first ==
'M') {
483 timer = (uint32_t)millis();
484 #ifdef DEBUG_USB_HOST
485 Notify(
PSTR(
"\r\nMotion Controller Enabled\r\n"), 0x80);
491 ButtonClickState = 0;
500 if((int32_t)((uint32_t)millis() - timer) > 4000) {
502 timer = (uint32_t)millis();
515 void PS3BT::HID_Command(uint8_t* data, uint8_t nbytes) {
516 if((int32_t)((uint32_t)millis() - timerHID) <= 150)
517 delay((uint32_t)(150 - ((uint32_t)millis() - timerHID)));
519 timerHID = (uint32_t)millis();
528 HIDBuffer[11] = 0x00;
544 uint8_t power[2] = {0xff, 0x00};
552 void PS3BT::setRumbleOn(uint8_t rightDuration, uint8_t rightPower, uint8_t leftDuration, uint8_t leftPower) {
555 rumbleBuf[3] = rightDuration;
556 rumbleBuf[4] = rightPower;
557 rumbleBuf[5] = leftDuration;
558 rumbleBuf[6] = leftPower;
563 HIDBuffer[11] = value << 1;
586 void PS3BT::enable_sixaxis() {
595 HID_Command(cmd_buf, 6);
600 void PS3BT::HIDMove_Command(uint8_t* data, uint8_t nbytes) {
601 if((int32_t)((uint32_t)millis() - timerHID) <= 150)
602 delay((uint32_t)(150 - ((uint32_t)millis() - timerHID)));
604 timerHID = (uint32_t)millis();
609 HIDMoveBuffer[3] = r;
610 HIDMoveBuffer[4] = g;
611 HIDMoveBuffer[5] = b;
617 moveSetBulb((uint8_t)(color >> 16), (uint8_t)(color >> 8), (uint8_t)(color));
621 #ifdef DEBUG_USB_HOST
622 if(rumble < 64 && rumble != 0)
623 Notify(
PSTR(
"\r\nThe rumble value has to at least 64, or approximately 25%"), 0x80);
626 HIDMoveBuffer[7] = rumble;
#define L2CAP_FLAG_CONNECTION_INTERRUPT_REQUEST
#define L2CAP_FLAG_CONFIG_CONTROL_SUCCESS
#define L2CAP_FLAG_DISCONNECT_CONTROL_RESPONSE
#define L2CAP_FLAG_CONFIG_INTERRUPT_SUCCESS
#define L2CAP_CMD_DISCONNECT_REQUEST
#define L2CAP_CMD_CONFIG_REQUEST
#define L2CAP_CMD_DISCONNECT_RESPONSE
#define l2cap_check_flag(flag)
#define l2cap_set_flag(flag)
#define L2CAP_CMD_COMMAND_REJECT
#define L2CAP_INTERRUPT_CONFIG_REQUEST
#define L2CAP_CMD_CONFIG_RESPONSE
#define L2CAP_FLAG_CONNECTION_CONTROL_REQUEST
#define L2CAP_CONTROL_DISCONNECT
#define PS3_ENABLE_SIXAXIS
#define L2CAP_INTERRUPT_DISCONNECT
#define L2CAP_CONTROL_SUCCESS
#define L2CAP_CMD_CONNECTION_REQUEST
#define L2CAP_INTERRUPT_SETUP
#define L2CAP_FLAG_DISCONNECT_INTERRUPT_RESPONSE
#define PS3_REPORT_BUFFER_SIZE
int8_t getButtonIndexPS3(ButtonEnum b)
const uint32_t PS3_BUTTONS[]
const uint8_t PS3_REPORT_BUFFER[PS3_REPORT_BUFFER_SIZE]
const uint8_t PS3_ANALOG_BUTTONS[]
bool l2capConnectionClaimed
void hci_disconnect(uint16_t handle)
void l2cap_disconnection_response(uint16_t handle, uint8_t rxid, uint8_t *dcid, uint8_t *scid)
void l2cap_config_response(uint16_t handle, uint8_t rxid, uint8_t *scid)
void l2cap_connection_response(uint16_t handle, uint8_t rxid, uint8_t *dcid, uint8_t *scid, uint8_t result)
void L2CAP_Command(uint16_t handle, uint8_t *data, uint8_t nbytes, uint8_t channelLow=0x01, uint8_t channelHigh=0x00)
void l2cap_config_request(uint16_t handle, uint8_t rxid, uint8_t *dcid)
void l2cap_disconnection_request(uint16_t handle, uint8_t rxid, uint8_t *dcid, uint8_t *scid)
bool checkHciHandle(uint8_t *buf, uint16_t handle)
void(* pFuncOnInit)(void)
uint32_t l2cap_event_flag
int16_t getSensor(SensorEnum a)
void setLedRaw(uint8_t value)
float get9DOFValues(SensorEnum a)
bool getButtonClick(ButtonEnum b)
bool getStatus(StatusEnum c)
bool getButtonPress(ButtonEnum b)
uint8_t getAnalogHat(AnalogHatEnum a)
uint8_t getAnalogButton(ButtonEnum a)
void setRumbleOn(RumbleEnum mode)
void ACLData(uint8_t *ACLData)
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 PS3NavigationConnected
float getAngle(AngleEnum a)
void moveSetRumble(uint8_t rumble)
void moveSetBulb(uint8_t r, uint8_t g, uint8_t b)
void setLedToggle(LEDEnum a)
#define strcat_P(dest, src)
#define pgm_read_byte(addr)
#define pgm_read_dword(addr)
#define strcpy_P(dest, src)