Clean up code formatting to industry standards.

This commit is contained in:
Andrew J. Kroll 2013-03-28 04:46:43 -04:00
parent 9b224b9899
commit 904f2ff25a
42 changed files with 5429 additions and 5202 deletions

21
BTD.h
View file

@ -178,16 +178,22 @@ public:
* @return 0 on success. * @return 0 on success.
*/ */
virtual uint8_t Poll(); virtual uint8_t Poll();
/** /**
* Get the device address. * Get the device address.
* @return The device address. * @return The device address.
*/ */
virtual uint8_t GetAddress() { return bAddress; }; virtual uint8_t GetAddress() {
return bAddress;
};
/** /**
* Used to check if the dongle has been initialized. * Used to check if the dongle has been initialized.
* @return True if it's ready. * @return True if it's ready.
*/ */
virtual bool isReady() { return bPollEnable; }; virtual bool isReady() {
return bPollEnable;
};
/**@}*/ /**@}*/
/** @name UsbConfigXtracter implementation */ /** @name UsbConfigXtracter implementation */
@ -208,6 +214,7 @@ public:
if(btService[i]) if(btService[i])
btService[i]->disconnect(); btService[i]->disconnect();
}; };
/** /**
* Register bluetooth dongle members/services. * Register bluetooth dongle members/services.
* @param pService Pointer to BluetoothService class instance. * @param pService Pointer to BluetoothService class instance.
@ -373,8 +380,12 @@ public:
* it should be at least 3 to work properly with the library. * it should be at least 3 to work properly with the library.
*/ */
uint8_t hci_version; uint8_t hci_version;
/** Call this function to pair with a Wiimote */ /** Call this function to pair with a Wiimote */
void pairWithWiimote() { pairWithWii = true; hci_state = HCI_CHECK_WII_SERVICE; }; void pairWithWiimote() {
pairWithWii = true;
hci_state = HCI_CHECK_WII_SERVICE;
};
/** Used to only send the ACL data to the wiimote. */ /** Used to only send the ACL data to the wiimote. */
bool connectToWii; bool connectToWii;
/** True if a Wiimote is connecting. */ /** True if a Wiimote is connecting. */
@ -390,7 +401,9 @@ public:
* Read the poll interval taken from the endpoint descriptors. * Read the poll interval taken from the endpoint descriptors.
* @return The poll interval in ms. * @return The poll interval in ms.
*/ */
uint8_t readPollInterval() { return pollInterval; }; uint8_t readPollInterval() {
return pollInterval;
};
protected: protected:
/** Pointer to USB class instance. */ /** Pointer to USB class instance. */

View file

@ -60,25 +60,30 @@ pBtd(p) // pointer to USB class instance - mandatory
Reset(); Reset();
} }
bool PS3BT::getButtonPress(Button b) { bool PS3BT::getButtonPress(Button b) {
return (ButtonState & pgm_read_dword(&BUTTONS[(uint8_t)b])); return (ButtonState & pgm_read_dword(&BUTTONS[(uint8_t)b]));
} }
bool PS3BT::getButtonClick(Button b) { bool PS3BT::getButtonClick(Button b) {
uint32_t button = pgm_read_dword(&BUTTONS[(uint8_t)b]); uint32_t button = pgm_read_dword(&BUTTONS[(uint8_t)b]);
bool click = (ButtonClickState & button); bool click = (ButtonClickState & button);
ButtonClickState &= ~button; // clear "click" event ButtonClickState &= ~button; // clear "click" event
return click; return click;
} }
uint8_t PS3BT::getAnalogButton(Button a) { uint8_t PS3BT::getAnalogButton(Button a) {
if (l2capinbuf == NULL) if (l2capinbuf == NULL)
return 0; return 0;
return (uint8_t)(l2capinbuf[pgm_read_byte(&ANALOGBUTTONS[(uint8_t)a])]); return (uint8_t)(l2capinbuf[pgm_read_byte(&ANALOGBUTTONS[(uint8_t)a])]);
} }
uint8_t PS3BT::getAnalogHat(AnalogHat a) { uint8_t PS3BT::getAnalogHat(AnalogHat a) {
if (l2capinbuf == NULL) if (l2capinbuf == NULL)
return 0; return 0;
return (uint8_t)(l2capinbuf[(uint8_t)a + 15]); return (uint8_t)(l2capinbuf[(uint8_t)a + 15]);
} }
int16_t PS3BT::getSensor(Sensor a) { int16_t PS3BT::getSensor(Sensor a) {
if (l2capinbuf == NULL) if (l2capinbuf == NULL)
return 0; return 0;
@ -97,6 +102,7 @@ int16_t PS3BT::getSensor(Sensor a) {
} else } else
return 0; return 0;
} }
double PS3BT::getAngle(Angle a) { double PS3BT::getAngle(Angle a) {
double accXval; double accXval;
double accYval; double accYval;
@ -127,6 +133,7 @@ double PS3BT::getAngle(Angle a) {
return angle; return angle;
} }
} }
double PS3BT::get9DOFValues(Sensor a) { // Thanks to Manfred Piendl double PS3BT::get9DOFValues(Sensor a) { // Thanks to Manfred Piendl
if (!PS3MoveConnected) if (!PS3MoveConnected)
return 0; return 0;
@ -155,6 +162,7 @@ double PS3BT::get9DOFValues(Sensor a) { // Thanks to Manfred Piendl
} else } else
return 0; return 0;
} }
String PS3BT::getTemperature() { String PS3BT::getTemperature() {
if (PS3MoveConnected) { if (PS3MoveConnected) {
int16_t input = getSensor(tempMove); int16_t input = getSensor(tempMove);
@ -168,6 +176,7 @@ String PS3BT::getTemperature() {
return output; return output;
} }
} }
bool PS3BT::getStatus(Status c) { bool PS3BT::getStatus(Status c) {
if (l2capinbuf == NULL) if (l2capinbuf == NULL)
return false; return false;
@ -175,6 +184,7 @@ bool PS3BT::getStatus(Status c) {
return true; return true;
return false; return false;
} }
String PS3BT::getStatusString() { String PS3BT::getStatusString() {
if (PS3Connected || PS3NavigationConnected) { if (PS3Connected || PS3NavigationConnected) {
char statusOutput[100]; char statusOutput[100];
@ -206,8 +216,7 @@ String PS3BT::getStatusString() {
return statusOutput; return statusOutput;
} } else if (PS3MoveConnected) {
else if(PS3MoveConnected) {
char statusOutput[50]; char statusOutput[50];
strcpy(statusOutput, "PowerRating: "); strcpy(statusOutput, "PowerRating: ");
@ -224,6 +233,7 @@ String PS3BT::getStatusString() {
return statusOutput; return statusOutput;
} }
} }
void PS3BT::Reset() { void PS3BT::Reset() {
PS3Connected = false; PS3Connected = false;
PS3MoveConnected = false; PS3MoveConnected = false;
@ -283,8 +293,7 @@ void PS3BT::ACLData(uint8_t* ACLData) {
Serial.print(" "); Serial.print(" ");
PrintHex<uint8_t > (l2capinbuf[14], 0x80); PrintHex<uint8_t > (l2capinbuf[14], 0x80);
#endif #endif
} } else if (l2capinbuf[8] == L2CAP_CMD_CONNECTION_REQUEST) {
else if (l2capinbuf[8] == L2CAP_CMD_CONNECTION_REQUEST) {
#ifdef EXTRADEBUG #ifdef EXTRADEBUG
Notify(PSTR("\r\nL2CAP Connection Request - PSM: "), 0x80); Notify(PSTR("\r\nL2CAP Connection Request - PSM: "), 0x80);
PrintHex<uint8_t > (l2capinbuf[13], 0x80); PrintHex<uint8_t > (l2capinbuf[13], 0x80);
@ -302,39 +311,33 @@ void PS3BT::ACLData(uint8_t* ACLData) {
control_scid[0] = l2capinbuf[14]; control_scid[0] = l2capinbuf[14];
control_scid[1] = l2capinbuf[15]; control_scid[1] = l2capinbuf[15];
l2cap_event_flag |= L2CAP_FLAG_CONNECTION_CONTROL_REQUEST; l2cap_event_flag |= L2CAP_FLAG_CONNECTION_CONTROL_REQUEST;
} } else if ((l2capinbuf[12] | (l2capinbuf[13] << 8)) == HID_INTR_PSM) {
else if ((l2capinbuf[12] | (l2capinbuf[13] << 8)) == HID_INTR_PSM) {
identifier = l2capinbuf[9]; identifier = l2capinbuf[9];
interrupt_scid[0] = l2capinbuf[14]; interrupt_scid[0] = l2capinbuf[14];
interrupt_scid[1] = l2capinbuf[15]; interrupt_scid[1] = l2capinbuf[15];
l2cap_event_flag |= L2CAP_FLAG_CONNECTION_INTERRUPT_REQUEST; l2cap_event_flag |= L2CAP_FLAG_CONNECTION_INTERRUPT_REQUEST;
} }
} } else if (l2capinbuf[8] == L2CAP_CMD_CONFIG_RESPONSE) {
else if (l2capinbuf[8] == L2CAP_CMD_CONFIG_RESPONSE) {
if ((l2capinbuf[16] | (l2capinbuf[17] << 8)) == 0x0000) { // Success if ((l2capinbuf[16] | (l2capinbuf[17] << 8)) == 0x0000) { // Success
if (l2capinbuf[12] == control_dcid[0] && l2capinbuf[13] == control_dcid[1]) { if (l2capinbuf[12] == control_dcid[0] && l2capinbuf[13] == control_dcid[1]) {
//Serial.print("\r\nHID Control Configuration Complete"); //Serial.print("\r\nHID Control Configuration Complete");
l2cap_event_flag |= L2CAP_FLAG_CONFIG_CONTROL_SUCCESS; l2cap_event_flag |= L2CAP_FLAG_CONFIG_CONTROL_SUCCESS;
} } else if (l2capinbuf[12] == interrupt_dcid[0] && l2capinbuf[13] == interrupt_dcid[1]) {
else if (l2capinbuf[12] == interrupt_dcid[0] && l2capinbuf[13] == interrupt_dcid[1]) {
//Serial.print("\r\nHID Interrupt Configuration Complete"); //Serial.print("\r\nHID Interrupt Configuration Complete");
l2cap_event_flag |= L2CAP_FLAG_CONFIG_INTERRUPT_SUCCESS; l2cap_event_flag |= L2CAP_FLAG_CONFIG_INTERRUPT_SUCCESS;
} }
} }
} } else if (l2capinbuf[8] == L2CAP_CMD_CONFIG_REQUEST) {
else if (l2capinbuf[8] == L2CAP_CMD_CONFIG_REQUEST) {
if (l2capinbuf[12] == control_dcid[0] && l2capinbuf[13] == control_dcid[1]) { if (l2capinbuf[12] == control_dcid[0] && l2capinbuf[13] == control_dcid[1]) {
//Serial.print("\r\nHID Control Configuration Request"); //Serial.print("\r\nHID Control Configuration Request");
identifier = l2capinbuf[9]; identifier = l2capinbuf[9];
l2cap_event_flag |= L2CAP_FLAG_CONFIG_CONTROL_REQUEST; l2cap_event_flag |= L2CAP_FLAG_CONFIG_CONTROL_REQUEST;
} } else if (l2capinbuf[12] == interrupt_dcid[0] && l2capinbuf[13] == interrupt_dcid[1]) {
else if (l2capinbuf[12] == interrupt_dcid[0] && l2capinbuf[13] == interrupt_dcid[1]) {
//Serial.print("\r\nHID Interrupt Configuration Request"); //Serial.print("\r\nHID Interrupt Configuration Request");
identifier = l2capinbuf[9]; identifier = l2capinbuf[9];
l2cap_event_flag |= L2CAP_FLAG_CONFIG_INTERRUPT_REQUEST; l2cap_event_flag |= L2CAP_FLAG_CONFIG_INTERRUPT_REQUEST;
} }
} } else if (l2capinbuf[8] == L2CAP_CMD_DISCONNECT_REQUEST) {
else if (l2capinbuf[8] == L2CAP_CMD_DISCONNECT_REQUEST) {
if (l2capinbuf[12] == control_dcid[0] && l2capinbuf[13] == control_dcid[1]) { if (l2capinbuf[12] == control_dcid[0] && l2capinbuf[13] == control_dcid[1]) {
#ifdef DEBUG #ifdef DEBUG
Notify(PSTR("\r\nDisconnect Request: Control Channel"), 0x80); Notify(PSTR("\r\nDisconnect Request: Control Channel"), 0x80);
@ -342,8 +345,7 @@ void PS3BT::ACLData(uint8_t* ACLData) {
identifier = l2capinbuf[9]; identifier = l2capinbuf[9];
pBtd->l2cap_disconnection_response(hci_handle, identifier, control_dcid, control_scid); pBtd->l2cap_disconnection_response(hci_handle, identifier, control_dcid, control_scid);
Reset(); Reset();
} } else if (l2capinbuf[12] == interrupt_dcid[0] && l2capinbuf[13] == interrupt_dcid[1]) {
else if (l2capinbuf[12] == interrupt_dcid[0] && l2capinbuf[13] == interrupt_dcid[1]) {
#ifdef DEBUG #ifdef DEBUG
Notify(PSTR("\r\nDisconnect Request: Interrupt Channel"), 0x80); Notify(PSTR("\r\nDisconnect Request: Interrupt Channel"), 0x80);
#endif #endif
@ -351,14 +353,12 @@ void PS3BT::ACLData(uint8_t* ACLData) {
pBtd->l2cap_disconnection_response(hci_handle, identifier, interrupt_dcid, interrupt_scid); pBtd->l2cap_disconnection_response(hci_handle, identifier, interrupt_dcid, interrupt_scid);
Reset(); Reset();
} }
} } else if (l2capinbuf[8] == L2CAP_CMD_DISCONNECT_RESPONSE) {
else if (l2capinbuf[8] == L2CAP_CMD_DISCONNECT_RESPONSE) {
if (l2capinbuf[12] == control_scid[0] && l2capinbuf[13] == control_scid[1]) { if (l2capinbuf[12] == control_scid[0] && l2capinbuf[13] == control_scid[1]) {
//Serial.print("\r\nDisconnect Response: Control Channel"); //Serial.print("\r\nDisconnect Response: Control Channel");
identifier = l2capinbuf[9]; identifier = l2capinbuf[9];
l2cap_event_flag |= L2CAP_FLAG_DISCONNECT_CONTROL_RESPONSE; l2cap_event_flag |= L2CAP_FLAG_DISCONNECT_CONTROL_RESPONSE;
} } else if (l2capinbuf[12] == interrupt_scid[0] && l2capinbuf[13] == interrupt_scid[1]) {
else if (l2capinbuf[12] == interrupt_scid[0] && l2capinbuf[13] == interrupt_scid[1]) {
//Serial.print("\r\nDisconnect Response: Interrupt Channel"); //Serial.print("\r\nDisconnect Response: Interrupt Channel");
identifier = l2capinbuf[9]; identifier = l2capinbuf[9];
l2cap_event_flag |= L2CAP_FLAG_DISCONNECT_INTERRUPT_RESPONSE; l2cap_event_flag |= L2CAP_FLAG_DISCONNECT_INTERRUPT_RESPONSE;
@ -401,6 +401,7 @@ void PS3BT::ACLData(uint8_t* ACLData) {
L2CAP_task(); L2CAP_task();
} }
} }
void PS3BT::L2CAP_task() { void PS3BT::L2CAP_task() {
switch (l2cap_state) { switch (l2cap_state) {
case L2CAP_WAIT: case L2CAP_WAIT:
@ -503,6 +504,7 @@ void PS3BT::L2CAP_task() {
break; break;
} }
} }
void PS3BT::Run() { void PS3BT::Run() {
switch (l2cap_state) { switch (l2cap_state) {
case L2CAP_HID_ENABLE_SIXAXIS: case L2CAP_HID_ENABLE_SIXAXIS:
@ -562,18 +564,21 @@ void PS3BT::Run() {
/************************************************************/ /************************************************************/
//Playstation Sixaxis Dualshock and Navigation Controller commands //Playstation Sixaxis Dualshock and Navigation Controller commands
void PS3BT::HID_Command(uint8_t* data, uint8_t nbytes) { void PS3BT::HID_Command(uint8_t* data, uint8_t nbytes) {
if (millis() - timerHID <= 250)// Check if is has been more than 250ms since last command if (millis() - timerHID <= 250)// Check if is has been more than 250ms since last command
delay((uint32_t)(250 - (millis() - timerHID))); //There have to be a delay between commands delay((uint32_t)(250 - (millis() - timerHID))); //There have to be a delay between commands
pBtd->L2CAP_Command(hci_handle, data, nbytes, control_scid[0], control_scid[1]); // Both the Navigation and Dualshock controller sends data via the control channel pBtd->L2CAP_Command(hci_handle, data, nbytes, control_scid[0], control_scid[1]); // Both the Navigation and Dualshock controller sends data via the control channel
timerHID = millis(); timerHID = millis();
} }
void PS3BT::setAllOff() { void PS3BT::setAllOff() {
for (uint8_t i = 0; i < OUTPUT_REPORT_BUFFER_SIZE; i++) for (uint8_t i = 0; i < OUTPUT_REPORT_BUFFER_SIZE; i++)
HIDBuffer[i + 2] = pgm_read_byte(&OUTPUT_REPORT_BUFFER[i]); //First two bytes reserved for report type and ID HIDBuffer[i + 2] = pgm_read_byte(&OUTPUT_REPORT_BUFFER[i]); //First two bytes reserved for report type and ID
HID_Command(HIDBuffer, HID_BUFFERSIZE); HID_Command(HIDBuffer, HID_BUFFERSIZE);
} }
void PS3BT::setRumbleOff() { void PS3BT::setRumbleOff() {
HIDBuffer[3] = 0x00; HIDBuffer[3] = 0x00;
HIDBuffer[4] = 0x00; //low mode off HIDBuffer[4] = 0x00; //low mode off
@ -582,6 +587,7 @@ void PS3BT::setRumbleOff() {
HID_Command(HIDBuffer, HID_BUFFERSIZE); HID_Command(HIDBuffer, HID_BUFFERSIZE);
} }
void PS3BT::setRumbleOn(Rumble mode) { void PS3BT::setRumbleOn(Rumble mode) {
/* Still not totally sure how it works, maybe something like this instead? /* Still not totally sure how it works, maybe something like this instead?
* 3 - duration_right * 3 - duration_right
@ -595,26 +601,29 @@ void PS3BT::setRumbleOn(Rumble mode) {
if (mode == RumbleHigh) { if (mode == RumbleHigh) {
HIDBuffer[4] = 0; //low mode off HIDBuffer[4] = 0; //low mode off
HIDBuffer[6] = 0xff; //high mode on HIDBuffer[6] = 0xff; //high mode on
} } else {
else {
HIDBuffer[4] = 0xff; //low mode on HIDBuffer[4] = 0xff; //low mode on
HIDBuffer[6] = 0; //high mode off HIDBuffer[6] = 0; //high mode off
} }
HID_Command(HIDBuffer, HID_BUFFERSIZE); HID_Command(HIDBuffer, HID_BUFFERSIZE);
} }
} }
void PS3BT::setLedOff(LED a) { void PS3BT::setLedOff(LED a) {
HIDBuffer[11] &= ~((uint8_t)((pgm_read_byte(&LEDS[(uint8_t)a]) & 0x0f) << 1)); HIDBuffer[11] &= ~((uint8_t)((pgm_read_byte(&LEDS[(uint8_t)a]) & 0x0f) << 1));
HID_Command(HIDBuffer, HID_BUFFERSIZE); HID_Command(HIDBuffer, HID_BUFFERSIZE);
} }
void PS3BT::setLedOn(LED a) { void PS3BT::setLedOn(LED a) {
HIDBuffer[11] |= (uint8_t)((pgm_read_byte(&LEDS[(uint8_t)a]) & 0x0f) << 1); HIDBuffer[11] |= (uint8_t)((pgm_read_byte(&LEDS[(uint8_t)a]) & 0x0f) << 1);
HID_Command(HIDBuffer, HID_BUFFERSIZE); HID_Command(HIDBuffer, HID_BUFFERSIZE);
} }
void PS3BT::setLedToggle(LED a) { void PS3BT::setLedToggle(LED a) {
HIDBuffer[11] ^= (uint8_t)((pgm_read_byte(&LEDS[(uint8_t)a]) & 0x0f) << 1); HIDBuffer[11] ^= (uint8_t)((pgm_read_byte(&LEDS[(uint8_t)a]) & 0x0f) << 1);
HID_Command(HIDBuffer, HID_BUFFERSIZE); HID_Command(HIDBuffer, HID_BUFFERSIZE);
} }
void PS3BT::enable_sixaxis() { //Command used to enable the Dualshock 3 and Navigation controller to send data via USB void PS3BT::enable_sixaxis() { //Command used to enable the Dualshock 3 and Navigation controller to send data via USB
uint8_t cmd_buf[6]; uint8_t cmd_buf[6];
cmd_buf[0] = 0x53; // HID BT Set_report (0x50) | Report Type (Feature 0x03) cmd_buf[0] = 0x53; // HID BT Set_report (0x50) | Report Type (Feature 0x03)
@ -628,12 +637,14 @@ void PS3BT::enable_sixaxis() { //Command used to enable the Dualshock 3 and Navi
} }
//Playstation Move Controller commands //Playstation Move Controller commands
void PS3BT::HIDMove_Command(uint8_t* data, uint8_t nbytes) { void PS3BT::HIDMove_Command(uint8_t* data, uint8_t nbytes) {
if (millis() - timerHID <= 250)// Check if is has been less than 200ms since last command if (millis() - timerHID <= 250)// Check if is has been less than 200ms since last command
delay((uint32_t)(250 - (millis() - timerHID))); //There have to be a delay between commands delay((uint32_t)(250 - (millis() - timerHID))); //There have to be a delay between commands
pBtd->L2CAP_Command(hci_handle, data, nbytes, interrupt_scid[0], interrupt_scid[1]); // The Move controller sends it's data via the intterrupt channel pBtd->L2CAP_Command(hci_handle, data, nbytes, interrupt_scid[0], interrupt_scid[1]); // The Move controller sends it's data via the intterrupt channel
timerHID = millis(); timerHID = millis();
} }
void PS3BT::moveSetBulb(uint8_t r, uint8_t g, uint8_t b) { //Use this to set the Color using RGB values void PS3BT::moveSetBulb(uint8_t r, uint8_t g, uint8_t b) { //Use this to set the Color using RGB values
//set the Bulb's values into the write buffer //set the Bulb's values into the write buffer
HIDMoveBuffer[3] = r; HIDMoveBuffer[3] = r;
@ -642,9 +653,11 @@ void PS3BT::moveSetBulb(uint8_t r, uint8_t g, uint8_t b) { //Use this to set the
HIDMove_Command(HIDMoveBuffer, HID_BUFFERSIZE); HIDMove_Command(HIDMoveBuffer, HID_BUFFERSIZE);
} }
void PS3BT::moveSetBulb(Colors color) { //Use this to set the Color using the predefined colors in enum void PS3BT::moveSetBulb(Colors color) { //Use this to set the Color using the predefined colors in enum
moveSetBulb((uint8_t)(color >> 16), (uint8_t)(color >> 8), (uint8_t)(color)); moveSetBulb((uint8_t)(color >> 16), (uint8_t)(color >> 8), (uint8_t)(color));
} }
void PS3BT::moveSetRumble(uint8_t rumble) { void PS3BT::moveSetRumble(uint8_t rumble) {
#ifdef DEBUG #ifdef DEBUG
if (rumble < 64 && rumble != 0) // The rumble value has to at least 64, or approximately 25% (64/255*100) if (rumble < 64 && rumble != 0) // The rumble value has to at least 64, or approximately 25% (64/255*100)

View file

@ -153,11 +153,13 @@ enum Sensor {
/** Magnetometer y-axis */ /** Magnetometer y-axis */
mYmove = 50, mYmove = 50,
}; };
/** Used to get the angle calculated using the accelerometer. */ /** Used to get the angle calculated using the accelerometer. */
enum Angle { enum Angle {
Pitch = 0x01, Pitch = 0x01,
Roll = 0x02, Roll = 0x02,
}; };
enum Status { enum Status {
// Note that the location is shiftet 9 when it's connected via USB // Note that the location is shiftet 9 when it's connected via USB
// Byte location | bit location // Byte location | bit location
@ -185,6 +187,7 @@ enum Status {
BluetoothRumble = (40 << 8) | 0x14, //Opperating by bluetooth and rumble is turned on BluetoothRumble = (40 << 8) | 0x14, //Opperating by bluetooth and rumble is turned on
Bluetooth = (40 << 8) | 0x16, //Opperating by bluetooth and rumble is turned off Bluetooth = (40 << 8) | 0x16, //Opperating by bluetooth and rumble is turned off
}; };
enum Rumble { enum Rumble {
RumbleHigh = 0x10, RumbleHigh = 0x10,
RumbleLow = 0x20, RumbleLow = 0x20,

View file

@ -212,8 +212,7 @@ uint8_t PS3USB::Init(uint8_t parent, uint8_t port, bool lowspeed) {
for (uint8_t i = 6; i < 10; i++) for (uint8_t i = 6; i < 10; i++)
readBuf[i] = 0x7F; // Set the analog joystick values to center position readBuf[i] = 0x7F; // Set the analog joystick values to center position
} } else { // must be a Motion controller
else { // must be a Motion controller
#ifdef DEBUG #ifdef DEBUG
Notify(PSTR("\r\nMotion Controller Connected"), 0x80); Notify(PSTR("\r\nMotion Controller Connected"), 0x80);
#endif #endif
@ -275,6 +274,7 @@ uint8_t PS3USB::Release() {
bPollEnable = false; bPollEnable = false;
return 0; return 0;
} }
uint8_t PS3USB::Poll() { uint8_t PS3USB::Poll() {
if (!bPollEnable) if (!bPollEnable)
return 0; return 0;
@ -288,8 +288,7 @@ uint8_t PS3USB::Poll() {
printReport(); // Uncomment "#define PRINTREPORT" to print the report send by the PS3 Controllers printReport(); // Uncomment "#define PRINTREPORT" to print the report send by the PS3 Controllers
#endif #endif
} }
} } else if (PS3MoveConnected) { // One can only set the color of the bulb, set the rumble, set and get the bluetooth address and calibrate the magnetometer via USB
else if(PS3MoveConnected) { // One can only set the color of the bulb, set the rumble, set and get the bluetooth address and calibrate the magnetometer via USB
if (millis() - timer > 4000) // Send at least every 4th second if (millis() - timer > 4000) // Send at least every 4th second
{ {
Move_Command(writeBuf, MOVE_REPORT_BUFFER_SIZE); // The Bulb and rumble values, has to be written again and again, for it to stay turned on Move_Command(writeBuf, MOVE_REPORT_BUFFER_SIZE); // The Bulb and rumble values, has to be written again and again, for it to stay turned on
@ -329,27 +328,32 @@ void PS3USB::printReport() { //Uncomment "#define PRINTREPORT" to print the repo
bool PS3USB::getButtonPress(Button b) { bool PS3USB::getButtonPress(Button b) {
return (ButtonState & pgm_read_dword(&BUTTONS[(uint8_t)b])); return (ButtonState & pgm_read_dword(&BUTTONS[(uint8_t)b]));
} }
bool PS3USB::getButtonClick(Button b) { bool PS3USB::getButtonClick(Button b) {
uint32_t button = pgm_read_dword(&BUTTONS[(uint8_t)b]); uint32_t button = pgm_read_dword(&BUTTONS[(uint8_t)b]);
bool click = (ButtonClickState & button); bool click = (ButtonClickState & button);
ButtonClickState &= ~button; // clear "click" event ButtonClickState &= ~button; // clear "click" event
return click; return click;
} }
uint8_t PS3USB::getAnalogButton(Button a) { uint8_t PS3USB::getAnalogButton(Button a) {
if (readBuf == NULL) if (readBuf == NULL)
return 0; return 0;
return (uint8_t)(readBuf[(pgm_read_byte(&ANALOGBUTTONS[(uint8_t)a])) - 9]); return (uint8_t)(readBuf[(pgm_read_byte(&ANALOGBUTTONS[(uint8_t)a])) - 9]);
} }
uint8_t PS3USB::getAnalogHat(AnalogHat a) { uint8_t PS3USB::getAnalogHat(AnalogHat a) {
if (readBuf == NULL) if (readBuf == NULL)
return 0; return 0;
return (uint8_t)(readBuf[((uint8_t)a + 6)]); return (uint8_t)(readBuf[((uint8_t)a + 6)]);
} }
uint16_t PS3USB::getSensor(Sensor a) { uint16_t PS3USB::getSensor(Sensor a) {
if (readBuf == NULL) if (readBuf == NULL)
return 0; return 0;
return ((readBuf[((uint16_t)a) - 9] << 8) | readBuf[((uint16_t)a + 1) - 9]); return ((readBuf[((uint16_t)a) - 9] << 8) | readBuf[((uint16_t)a + 1) - 9]);
} }
double PS3USB::getAngle(Angle a) { double PS3USB::getAngle(Angle a) {
if (PS3Connected) { if (PS3Connected) {
double accXval; double accXval;
@ -375,6 +379,7 @@ double PS3USB::getAngle(Angle a) {
} else } else
return 0; return 0;
} }
bool PS3USB::getStatus(Status c) { bool PS3USB::getStatus(Status c) {
if (readBuf == NULL) if (readBuf == NULL)
return false; return false;
@ -382,6 +387,7 @@ bool PS3USB::getStatus(Status c) {
return true; return true;
return false; return false;
} }
String PS3USB::getStatusString() { String PS3USB::getStatusString() {
if (PS3Connected || PS3NavigationConnected) { if (PS3Connected || PS3NavigationConnected) {
char statusOutput[100]; char statusOutput[100];
@ -421,12 +427,14 @@ void PS3USB::PS3_Command(uint8_t* data, uint16_t nbytes) {
//bmRequest = Host to device (0x00) | Class (0x20) | Interface (0x01) = 0x21, bRequest = Set Report (0x09), Report ID (0x01), Report Type (Output 0x02), interface (0x00), datalength, datalength, data) //bmRequest = Host to device (0x00) | Class (0x20) | Interface (0x01) = 0x21, bRequest = Set Report (0x09), Report ID (0x01), Report Type (Output 0x02), interface (0x00), datalength, datalength, data)
pUsb->ctrlReq(bAddress, epInfo[PS3_CONTROL_PIPE].epAddr, bmREQ_HID_OUT, HID_REQUEST_SET_REPORT, 0x01, 0x02, 0x00, nbytes, nbytes, data, NULL); pUsb->ctrlReq(bAddress, epInfo[PS3_CONTROL_PIPE].epAddr, bmREQ_HID_OUT, HID_REQUEST_SET_REPORT, 0x01, 0x02, 0x00, nbytes, nbytes, data, NULL);
} }
void PS3USB::setAllOff() { void PS3USB::setAllOff() {
for (uint8_t i = 0; i < PS3_REPORT_BUFFER_SIZE; i++) for (uint8_t i = 0; i < PS3_REPORT_BUFFER_SIZE; i++)
writeBuf[i] = pgm_read_byte(&PS3_REPORT_BUFFER[i]); // Reset buffer writeBuf[i] = pgm_read_byte(&PS3_REPORT_BUFFER[i]); // Reset buffer
PS3_Command(writeBuf, PS3_REPORT_BUFFER_SIZE); PS3_Command(writeBuf, PS3_REPORT_BUFFER_SIZE);
} }
void PS3USB::setRumbleOff() { void PS3USB::setRumbleOff() {
writeBuf[1] = 0x00; writeBuf[1] = 0x00;
writeBuf[2] = 0x00; //low mode off writeBuf[2] = 0x00; //low mode off
@ -435,6 +443,7 @@ void PS3USB::setRumbleOff() {
PS3_Command(writeBuf, PS3_REPORT_BUFFER_SIZE); PS3_Command(writeBuf, PS3_REPORT_BUFFER_SIZE);
} }
void PS3USB::setRumbleOn(Rumble mode) { void PS3USB::setRumbleOn(Rumble mode) {
/* Still not totally sure how it works, maybe something like this instead? /* Still not totally sure how it works, maybe something like this instead?
* 3 - duration_right * 3 - duration_right
@ -448,26 +457,29 @@ void PS3USB::setRumbleOn(Rumble mode) {
if (mode == RumbleHigh) { if (mode == RumbleHigh) {
writeBuf[2] = 0; //low mode off writeBuf[2] = 0; //low mode off
writeBuf[4] = 0xff; //high mode on writeBuf[4] = 0xff; //high mode on
} } else {
else {
writeBuf[2] = 0xff; //low mode on writeBuf[2] = 0xff; //low mode on
writeBuf[4] = 0; //high mode off writeBuf[4] = 0; //high mode off
} }
PS3_Command(writeBuf, PS3_REPORT_BUFFER_SIZE); PS3_Command(writeBuf, PS3_REPORT_BUFFER_SIZE);
} }
} }
void PS3USB::setLedOff(LED a) { void PS3USB::setLedOff(LED a) {
writeBuf[9] &= ~((uint8_t)((pgm_read_byte(&LEDS[(uint8_t)a]) & 0x0f) << 1)); writeBuf[9] &= ~((uint8_t)((pgm_read_byte(&LEDS[(uint8_t)a]) & 0x0f) << 1));
PS3_Command(writeBuf, PS3_REPORT_BUFFER_SIZE); PS3_Command(writeBuf, PS3_REPORT_BUFFER_SIZE);
} }
void PS3USB::setLedOn(LED a) { void PS3USB::setLedOn(LED a) {
writeBuf[9] |= (uint8_t)((pgm_read_byte(&LEDS[(uint8_t)a]) & 0x0f) << 1); writeBuf[9] |= (uint8_t)((pgm_read_byte(&LEDS[(uint8_t)a]) & 0x0f) << 1);
PS3_Command(writeBuf, PS3_REPORT_BUFFER_SIZE); PS3_Command(writeBuf, PS3_REPORT_BUFFER_SIZE);
} }
void PS3USB::setLedToggle(LED a) { void PS3USB::setLedToggle(LED a) {
writeBuf[9] ^= (uint8_t)((pgm_read_byte(&LEDS[(uint8_t)a]) & 0x0f) << 1); writeBuf[9] ^= (uint8_t)((pgm_read_byte(&LEDS[(uint8_t)a]) & 0x0f) << 1);
PS3_Command(writeBuf, PS3_REPORT_BUFFER_SIZE); PS3_Command(writeBuf, PS3_REPORT_BUFFER_SIZE);
} }
void PS3USB::setBdaddr(uint8_t* BDADDR) { void PS3USB::setBdaddr(uint8_t* BDADDR) {
/* Set the internal bluetooth address */ /* Set the internal bluetooth address */
uint8_t buf[8]; uint8_t buf[8];
@ -488,6 +500,7 @@ void PS3USB::setBdaddr(uint8_t* BDADDR) {
#endif #endif
return; return;
} }
void PS3USB::enable_sixaxis() { //Command used to enable the Dualshock 3 and Navigation controller to send data via USB void PS3USB::enable_sixaxis() { //Command used to enable the Dualshock 3 and Navigation controller to send data via USB
uint8_t cmd_buf[4]; uint8_t cmd_buf[4];
cmd_buf[0] = 0x42; // Special PS3 Controller enable commands cmd_buf[0] = 0x42; // Special PS3 Controller enable commands
@ -512,9 +525,11 @@ void PS3USB::moveSetBulb(uint8_t r, uint8_t g, uint8_t b) { //Use this to set th
Move_Command(writeBuf, MOVE_REPORT_BUFFER_SIZE); Move_Command(writeBuf, MOVE_REPORT_BUFFER_SIZE);
} }
void PS3USB::moveSetBulb(Colors color) { //Use this to set the Color using the predefined colors in "enums.h" void PS3USB::moveSetBulb(Colors color) { //Use this to set the Color using the predefined colors in "enums.h"
moveSetBulb((uint8_t)(color >> 16), (uint8_t)(color >> 8), (uint8_t)(color)); moveSetBulb((uint8_t)(color >> 16), (uint8_t)(color >> 8), (uint8_t)(color));
} }
void PS3USB::moveSetRumble(uint8_t rumble) { void PS3USB::moveSetRumble(uint8_t rumble) {
#ifdef DEBUG #ifdef DEBUG
if (rumble < 64 && rumble != 0) // The rumble value has to at least 64, or approximately 25% (64/255*100) if (rumble < 64 && rumble != 0) // The rumble value has to at least 64, or approximately 25% (64/255*100)
@ -525,6 +540,7 @@ void PS3USB::moveSetRumble(uint8_t rumble) {
Move_Command(writeBuf, MOVE_REPORT_BUFFER_SIZE); Move_Command(writeBuf, MOVE_REPORT_BUFFER_SIZE);
} }
void PS3USB::setMoveBdaddr(uint8_t* BDADDR) { void PS3USB::setMoveBdaddr(uint8_t* BDADDR) {
/* Set the internal bluetooth address */ /* Set the internal bluetooth address */
uint8_t buf[11]; uint8_t buf[11];

View file

@ -91,16 +91,22 @@ public:
* @return 0 on success. * @return 0 on success.
*/ */
virtual uint8_t Poll(); virtual uint8_t Poll();
/** /**
* Get the device address. * Get the device address.
* @return The device address. * @return The device address.
*/ */
virtual uint8_t GetAddress() { return bAddress; }; virtual uint8_t GetAddress() {
return bAddress;
};
/** /**
* Used to check if the controller has been initialized. * Used to check if the controller has been initialized.
* @return True if it's ready. * @return True if it's ready.
*/ */
virtual bool isReady() { return bPollEnable; }; virtual bool isReady() {
return bPollEnable;
};
/**@}*/ /**@}*/
/** /**

55
SPP.cpp
View file

@ -59,6 +59,7 @@ pBtd(p) // Pointer to BTD class instance - mandatory
Reset(); Reset();
} }
void SPP::Reset() { void SPP::Reset() {
connected = false; connected = false;
RFCOMMConnected = false; RFCOMMConnected = false;
@ -67,6 +68,7 @@ void SPP::Reset() {
l2cap_rfcomm_state = L2CAP_RFCOMM_WAIT; l2cap_rfcomm_state = L2CAP_RFCOMM_WAIT;
l2cap_event_flag = 0; l2cap_event_flag = 0;
} }
void SPP::disconnect() { void SPP::disconnect() {
connected = false; connected = false;
// First the two L2CAP channels has to be disconencted and then the HCI connection // First the two L2CAP channels has to be disconencted and then the HCI connection
@ -78,6 +80,7 @@ void SPP::disconnect(){
pBtd->l2cap_disconnection_request(hci_handle, 0x0B, sdp_scid, sdp_dcid); pBtd->l2cap_disconnection_request(hci_handle, 0x0B, sdp_scid, sdp_dcid);
l2cap_sdp_state = L2CAP_DISCONNECT_RESPONSE; l2cap_sdp_state = L2CAP_DISCONNECT_RESPONSE;
} }
void SPP::ACLData(uint8_t* l2capinbuf) { void SPP::ACLData(uint8_t* l2capinbuf) {
if (!connected) { if (!connected) {
if (l2capinbuf[8] == L2CAP_CMD_CONNECTION_REQUEST) { if (l2capinbuf[8] == L2CAP_CMD_CONNECTION_REQUEST) {
@ -138,8 +141,7 @@ void SPP::ACLData(uint8_t* l2capinbuf) {
if (l2capinbuf[12] == sdp_dcid[0] && l2capinbuf[13] == sdp_dcid[1]) { if (l2capinbuf[12] == sdp_dcid[0] && l2capinbuf[13] == sdp_dcid[1]) {
//Serial.print("\r\nSDP Configuration Complete"); //Serial.print("\r\nSDP Configuration Complete");
l2cap_event_flag |= L2CAP_FLAG_CONFIG_SDP_SUCCESS; l2cap_event_flag |= L2CAP_FLAG_CONFIG_SDP_SUCCESS;
} } else if (l2capinbuf[12] == rfcomm_dcid[0] && l2capinbuf[13] == rfcomm_dcid[1]) {
else if (l2capinbuf[12] == rfcomm_dcid[0] && l2capinbuf[13] == rfcomm_dcid[1]) {
//Serial.print("\r\nRFCOMM Configuration Complete"); //Serial.print("\r\nRFCOMM Configuration Complete");
l2cap_event_flag |= L2CAP_FLAG_CONFIG_RFCOMM_SUCCESS; l2cap_event_flag |= L2CAP_FLAG_CONFIG_RFCOMM_SUCCESS;
} }
@ -149,8 +151,7 @@ void SPP::ACLData(uint8_t* l2capinbuf) {
//Serial.print("\r\nSDP Configuration Request"); //Serial.print("\r\nSDP Configuration Request");
identifier = l2capinbuf[9]; identifier = l2capinbuf[9];
l2cap_event_flag |= L2CAP_FLAG_CONFIG_SDP_REQUEST; l2cap_event_flag |= L2CAP_FLAG_CONFIG_SDP_REQUEST;
} } else if (l2capinbuf[12] == rfcomm_dcid[0] && l2capinbuf[13] == rfcomm_dcid[1]) {
else if (l2capinbuf[12] == rfcomm_dcid[0] && l2capinbuf[13] == rfcomm_dcid[1]) {
//Serial.print("\r\nRFCOMM Configuration Request"); //Serial.print("\r\nRFCOMM Configuration Request");
identifier = l2capinbuf[9]; identifier = l2capinbuf[9];
l2cap_event_flag |= L2CAP_FLAG_CONFIG_RFCOMM_REQUEST; l2cap_event_flag |= L2CAP_FLAG_CONFIG_RFCOMM_REQUEST;
@ -391,6 +392,7 @@ void SPP::ACLData(uint8_t* l2capinbuf) {
RFCOMM_task(); RFCOMM_task();
} }
} }
void SPP::Run() { void SPP::Run() {
if (waitForLastCommand && (millis() - timer) > 100) { // We will only wait 100ms and see if the UIH Remote Port Negotiation Command is send, as some deviced don't send it if (waitForLastCommand && (millis() - timer) > 100) { // We will only wait 100ms and see if the UIH Remote Port Negotiation Command is send, as some deviced don't send it
#ifdef DEBUG #ifdef DEBUG
@ -401,9 +403,9 @@ void SPP::Run() {
connected = true; // The RFCOMM channel is now established connected = true; // The RFCOMM channel is now established
} }
} }
void SPP::SDP_task() { void SPP::SDP_task() {
switch (l2cap_sdp_state) switch (l2cap_sdp_state) {
{
case L2CAP_SDP_WAIT: case L2CAP_SDP_WAIT:
if (l2cap_connection_request_sdp_flag) { if (l2cap_connection_request_sdp_flag) {
l2cap_event_flag &= ~L2CAP_FLAG_CONNECTION_SDP_REQUEST; // Clear flag l2cap_event_flag &= ~L2CAP_FLAG_CONNECTION_SDP_REQUEST; // Clear flag
@ -468,10 +470,9 @@ void SPP::SDP_task() {
break; break;
} }
} }
void SPP::RFCOMM_task()
{ void SPP::RFCOMM_task() {
switch (l2cap_rfcomm_state) switch (l2cap_rfcomm_state) {
{
case L2CAP_RFCOMM_WAIT: case L2CAP_RFCOMM_WAIT:
if (l2cap_connection_request_rfcomm_flag) { if (l2cap_connection_request_rfcomm_flag) {
l2cap_event_flag &= ~L2CAP_FLAG_CONNECTION_RFCOMM_REQUEST; // Clear flag l2cap_event_flag &= ~L2CAP_FLAG_CONNECTION_RFCOMM_REQUEST; // Clear flag
@ -526,10 +527,12 @@ void SPP::RFCOMM_task()
} }
/************************************************************/ /************************************************************/
/* SDP Commands */ /* SDP Commands */
/************************************************************/ /************************************************************/
void SPP::SDP_Command(uint8_t* data, uint8_t nbytes) { // See page 223 in the Bluetooth specs void SPP::SDP_Command(uint8_t* data, uint8_t nbytes) { // See page 223 in the Bluetooth specs
pBtd->L2CAP_Command(hci_handle, data, nbytes, sdp_scid[0], sdp_scid[1]); pBtd->L2CAP_Command(hci_handle, data, nbytes, sdp_scid[0], sdp_scid[1]);
} }
void SPP::serviceNotSupported(uint8_t transactionIDHigh, uint8_t transactionIDLow) { // See page 235 in the Bluetooth specs void SPP::serviceNotSupported(uint8_t transactionIDHigh, uint8_t transactionIDLow) { // See page 235 in the Bluetooth specs
l2capoutbuf[0] = SDP_SERVICE_SEARCH_ATTRIBUTE_RESPONSE_PDU; l2capoutbuf[0] = SDP_SERVICE_SEARCH_ATTRIBUTE_RESPONSE_PDU;
l2capoutbuf[1] = transactionIDHigh; l2capoutbuf[1] = transactionIDHigh;
@ -546,6 +549,7 @@ void SPP::serviceNotSupported(uint8_t transactionIDHigh, uint8_t transactionIDLo
SDP_Command(l2capoutbuf, 10); SDP_Command(l2capoutbuf, 10);
} }
void SPP::serialPortResponse1(uint8_t transactionIDHigh, uint8_t transactionIDLow) { void SPP::serialPortResponse1(uint8_t transactionIDHigh, uint8_t transactionIDLow) {
l2capoutbuf[0] = SDP_SERVICE_SEARCH_ATTRIBUTE_RESPONSE_PDU; l2capoutbuf[0] = SDP_SERVICE_SEARCH_ATTRIBUTE_RESPONSE_PDU;
l2capoutbuf[1] = transactionIDHigh; l2capoutbuf[1] = transactionIDHigh;
@ -603,6 +607,7 @@ void SPP::serialPortResponse1(uint8_t transactionIDHigh, uint8_t transactionIDLo
SDP_Command(l2capoutbuf, 48); SDP_Command(l2capoutbuf, 48);
} }
void SPP::serialPortResponse2(uint8_t transactionIDHigh, uint8_t transactionIDLow) { void SPP::serialPortResponse2(uint8_t transactionIDHigh, uint8_t transactionIDLow) {
l2capoutbuf[0] = SDP_SERVICE_SEARCH_ATTRIBUTE_RESPONSE_PDU; l2capoutbuf[0] = SDP_SERVICE_SEARCH_ATTRIBUTE_RESPONSE_PDU;
l2capoutbuf[1] = transactionIDHigh; l2capoutbuf[1] = transactionIDHigh;
@ -644,14 +649,17 @@ void SPP::serialPortResponse2(uint8_t transactionIDHigh, uint8_t transactionIDLo
SDP_Command(l2capoutbuf, 33); SDP_Command(l2capoutbuf, 33);
} }
void SPP::l2capResponse1(uint8_t transactionIDHigh, uint8_t transactionIDLow) { void SPP::l2capResponse1(uint8_t transactionIDHigh, uint8_t transactionIDLow) {
serialPortResponse1(transactionIDHigh, transactionIDLow); // These has to send all the supported functions, since it only supports virtual serialport it just sends the message again serialPortResponse1(transactionIDHigh, transactionIDLow); // These has to send all the supported functions, since it only supports virtual serialport it just sends the message again
} }
void SPP::l2capResponse2(uint8_t transactionIDHigh, uint8_t transactionIDLow) { void SPP::l2capResponse2(uint8_t transactionIDHigh, uint8_t transactionIDLow) {
serialPortResponse2(transactionIDHigh, transactionIDLow); // Same data as serialPortResponse2 serialPortResponse2(transactionIDHigh, transactionIDLow); // Same data as serialPortResponse2
} }
/************************************************************/ /************************************************************/
/* RFCOMM Commands */ /* RFCOMM Commands */
/************************************************************/ /************************************************************/
void SPP::RFCOMM_Command(uint8_t* data, uint8_t nbytes) { void SPP::RFCOMM_Command(uint8_t* data, uint8_t nbytes) {
pBtd->L2CAP_Command(hci_handle, data, nbytes, rfcomm_scid[0], rfcomm_scid[1]); pBtd->L2CAP_Command(hci_handle, data, nbytes, rfcomm_scid[0], rfcomm_scid[1]);
@ -711,7 +719,8 @@ void SPP::print(const String &str) {
uint8_t length = str.length(); uint8_t length = str.length();
if (length > (sizeof (l2capoutbuf) - 4)) if (length > (sizeof (l2capoutbuf) - 4))
length = sizeof (l2capoutbuf) - 4; length = sizeof (l2capoutbuf) - 4;
l2capoutbuf[0] = rfcommChannelConnection | 0 | 0 | extendAddress;; // RFCOMM Address l2capoutbuf[0] = rfcommChannelConnection | 0 | 0 | extendAddress;
; // RFCOMM Address
l2capoutbuf[1] = RFCOMM_UIH; // RFCOMM Control l2capoutbuf[1] = RFCOMM_UIH; // RFCOMM Control
l2capoutbuf[2] = length << 1 | 1; // Length l2capoutbuf[2] = length << 1 | 1; // Length
uint8_t i = 0; uint8_t i = 0;
@ -721,13 +730,15 @@ void SPP::print(const String &str) {
RFCOMM_Command(l2capoutbuf, length + 4); RFCOMM_Command(l2capoutbuf, length + 4);
} }
void SPP::print(const char* str) { void SPP::print(const char* str) {
if (!connected) if (!connected)
return; return;
uint8_t length = strlen(str); uint8_t length = strlen(str);
if (length > (sizeof (l2capoutbuf) - 4)) if (length > (sizeof (l2capoutbuf) - 4))
length = sizeof (l2capoutbuf) - 4; length = sizeof (l2capoutbuf) - 4;
l2capoutbuf[0] = rfcommChannelConnection | 0 | 0 | extendAddress;; // RFCOMM Address l2capoutbuf[0] = rfcommChannelConnection | 0 | 0 | extendAddress;
; // RFCOMM Address
l2capoutbuf[1] = RFCOMM_UIH; // RFCOMM Control l2capoutbuf[1] = RFCOMM_UIH; // RFCOMM Control
l2capoutbuf[2] = length << 1 | 1; // Length l2capoutbuf[2] = length << 1 | 1; // Length
uint8_t i = 0; uint8_t i = 0;
@ -737,12 +748,14 @@ void SPP::print(const char* str) {
RFCOMM_Command(l2capoutbuf, length + 4); RFCOMM_Command(l2capoutbuf, length + 4);
} }
void SPP::print(uint8_t* array, uint8_t length) { void SPP::print(uint8_t* array, uint8_t length) {
if (!connected) if (!connected)
return; return;
if (length > (sizeof (l2capoutbuf) - 4)) if (length > (sizeof (l2capoutbuf) - 4))
length = sizeof (l2capoutbuf) - 4; length = sizeof (l2capoutbuf) - 4;
l2capoutbuf[0] = rfcommChannelConnection | 0 | 0 | extendAddress;; // RFCOMM Address l2capoutbuf[0] = rfcommChannelConnection | 0 | 0 | extendAddress;
; // RFCOMM Address
l2capoutbuf[1] = RFCOMM_UIH; // RFCOMM Control l2capoutbuf[1] = RFCOMM_UIH; // RFCOMM Control
l2capoutbuf[2] = length << 1 | 1; // Length l2capoutbuf[2] = length << 1 | 1; // Length
uint8_t i = 0; uint8_t i = 0;
@ -752,20 +765,24 @@ void SPP::print(uint8_t* array, uint8_t length) {
RFCOMM_Command(l2capoutbuf, length + 4); RFCOMM_Command(l2capoutbuf, length + 4);
} }
void SPP::println(const String &str) { void SPP::println(const String &str) {
String output = str + "\r\n"; String output = str + "\r\n";
print(output); print(output);
} }
void SPP::println(const char* str) { void SPP::println(const char* str) {
char output[strlen(str) + 3]; char output[strlen(str) + 3];
strcpy(output, str); strcpy(output, str);
strcat(output, "\r\n"); strcat(output, "\r\n");
print(output); print(output);
} }
void SPP::println(uint8_t data) { void SPP::println(uint8_t data) {
uint8_t buf[3] = {data, '\r', '\n'}; uint8_t buf[3] = {data, '\r', '\n'};
print(buf, 3); print(buf, 3);
} }
void SPP::println(uint8_t* array, uint8_t length) { void SPP::println(uint8_t* array, uint8_t length) {
uint8_t buf[length + 2]; uint8_t buf[length + 2];
memcpy(buf, array, length); memcpy(buf, array, length);
@ -773,6 +790,7 @@ void SPP::println(uint8_t* array, uint8_t length) {
buf[length + 1] = '\n'; buf[length + 1] = '\n';
print(buf, length + 2); print(buf, length + 2);
} }
void SPP::printFlashString(const __FlashStringHelper *ifsh, bool newline) { void SPP::printFlashString(const __FlashStringHelper *ifsh, bool newline) {
const char PROGMEM *p = (const char PROGMEM *)ifsh; const char PROGMEM *p = (const char PROGMEM *)ifsh;
uint8_t size = 0; uint8_t size = 0;
@ -794,6 +812,7 @@ void SPP::printFlashString(const __FlashStringHelper *ifsh, bool newline) {
} else } else
print(buf, size); print(buf, size);
} }
void SPP::println(void) { void SPP::println(void) {
uint8_t buf[2] = {'\r', '\n'}; uint8_t buf[2] = {'\r', '\n'};
print(buf, 2); print(buf, 2);
@ -805,23 +824,27 @@ void SPP::printNumber(uint32_t n) {
intToString(n, output); intToString(n, output);
print(output); print(output);
} }
void SPP::printNumberln(uint32_t n) { void SPP::printNumberln(uint32_t n) {
char output[13]; char output[13];
intToString(n, output); intToString(n, output);
strcat(output, "\r\n"); strcat(output, "\r\n");
print(output); print(output);
} }
void SPP::printNumber(int32_t n) { void SPP::printNumber(int32_t n) {
char output[12]; char output[12];
intToString(n, output); intToString(n, output);
print(output); print(output);
} }
void SPP::printNumberln(int32_t n) { void SPP::printNumberln(int32_t n) {
char output[14]; char output[14];
intToString(n, output); intToString(n, output);
strcat(output, "\r\n"); strcat(output, "\r\n");
print(output); print(output);
} }
void SPP::intToString(int32_t input, char* output) { void SPP::intToString(int32_t input, char* output) {
if (input < 0) { if (input < 0) {
char buf[11]; char buf[11];
@ -831,6 +854,7 @@ void SPP::intToString(int32_t input, char* output) {
} else } else
intToString((uint32_t)input, output); intToString((uint32_t)input, output);
} }
void SPP::intToString(uint32_t input, char* output) { void SPP::intToString(uint32_t input, char* output) {
uint32_t temp = input; uint32_t temp = input;
uint8_t digits = 0; uint8_t digits = 0;
@ -854,19 +878,20 @@ void SPP::printNumber(double n, uint8_t digits) {
doubleToString(n, output, digits); doubleToString(n, output, digits);
print(output); print(output);
} }
void SPP::printNumberln(double n, uint8_t digits) { void SPP::printNumberln(double n, uint8_t digits) {
char output[15 + digits]; char output[15 + digits];
doubleToString(n, output, digits); doubleToString(n, output, digits);
strcat(output, "\r\n"); strcat(output, "\r\n");
print(output); print(output);
} }
void SPP::doubleToString(double input, char* output, uint8_t digits) { void SPP::doubleToString(double input, char* output, uint8_t digits) {
char buffer[13 + digits]; char buffer[13 + digits];
if (input < 0) { if (input < 0) {
strcpy(output, "-"); strcpy(output, "-");
input = -input; input = -input;
} } else
else
strcpy(output, ""); strcpy(output, "");
// Round correctly // Round correctly

60
SPP.h
View file

@ -144,7 +144,9 @@ public:
* Used to send single bytes. * Used to send single bytes.
* @param data Data to send. * @param data Data to send.
*/ */
void print(uint8_t data) { print(&data,1); }; void print(uint8_t data) {
print(&data, 1);
};
/** /**
* Same as print(uint8_t data), but will include newline and carriage return. * Same as print(uint8_t data), but will include newline and carriage return.
* @param data Data to send. * @param data Data to send.
@ -169,12 +171,17 @@ public:
* Use "SerialBT.print(F("String"));" to print a string stored in flash. * Use "SerialBT.print(F("String"));" to print a string stored in flash.
* @param ifsh String to send - see: http://playground.arduino.cc/Learning/Memory. * @param ifsh String to send - see: http://playground.arduino.cc/Learning/Memory.
*/ */
void print(const __FlashStringHelper *ifsh) { printFlashString(ifsh,false); }; void print(const __FlashStringHelper *ifsh) {
printFlashString(ifsh, false);
};
/** /**
* Same as print(const __FlashStringHelper *ifsh), but will include newline and carriage return. * Same as print(const __FlashStringHelper *ifsh), but will include newline and carriage return.
* @param ifsh String to send - see: http://playground.arduino.cc/Learning/Memory. * @param ifsh String to send - see: http://playground.arduino.cc/Learning/Memory.
*/ */
void println(const __FlashStringHelper *ifsh) { printFlashString(ifsh,true); }; void println(const __FlashStringHelper *ifsh) {
printFlashString(ifsh, true);
};
/** /**
* Helper function to print a string stored in flash. * Helper function to print a string stored in flash.
* @param ifsh String stored in flash you want to print. * @param ifsh String stored in flash you want to print.
@ -190,43 +197,65 @@ public:
* Used to print unsigned integers. * Used to print unsigned integers.
* @param n Unsigned integer to send. * @param n Unsigned integer to send.
*/ */
void printNumber(uint8_t n) { printNumber((uint32_t)n); }; void printNumber(uint8_t n) {
printNumber((uint32_t) n);
};
/** /**
* Same as printNumber(uint8_t n), but will include newline and carriage return. * Same as printNumber(uint8_t n), but will include newline and carriage return.
* @param n Unsigned integer to send. * @param n Unsigned integer to send.
*/ */
void printNumberln(uint8_t n) { printNumberln((uint32_t)n); }; void printNumberln(uint8_t n) {
printNumberln((uint32_t) n);
};
/** /**
* Used to print signed integers. * Used to print signed integers.
* @param n Signed integer to send. * @param n Signed integer to send.
*/ */
void printNumber(int8_t n) { printNumber((int32_t)n); }; void printNumber(int8_t n) {
printNumber((int32_t) n);
};
/** /**
* Same as printNumber(int8_t n), but will include newline and carriage return. * Same as printNumber(int8_t n), but will include newline and carriage return.
* @param n Signed integer to send. * @param n Signed integer to send.
*/ */
void printNumberln(int8_t n) { printNumberln((int32_t)n); }; void printNumberln(int8_t n) {
printNumberln((int32_t) n);
};
/** /**
* Used to print unsigned integers. * Used to print unsigned integers.
* @param n Unsigned integer to send. * @param n Unsigned integer to send.
*/ */
void printNumber(uint16_t n) { printNumber((uint32_t)n); }; void printNumber(uint16_t n) {
printNumber((uint32_t) n);
};
/** /**
* Same as printNumber(uint16_t n), but will include newline and carriage return. * Same as printNumber(uint16_t n), but will include newline and carriage return.
* @param n Unsigned integer to send. * @param n Unsigned integer to send.
*/ */
void printNumberln(uint16_t n) { printNumberln((uint32_t)n); }; void printNumberln(uint16_t n) {
printNumberln((uint32_t) n);
};
/** /**
* Used to print signed integers. * Used to print signed integers.
* @param n Signed integer to send. * @param n Signed integer to send.
*/ */
void printNumber(int16_t n) { printNumber((int32_t)n); }; void printNumber(int16_t n) {
printNumber((int32_t) n);
};
/** /**
* Same as printNumber(int16_t n), but will include newline and carriage return. * Same as printNumber(int16_t n), but will include newline and carriage return.
* @param n Signed integer to send. * @param n Signed integer to send.
*/ */
void printNumberln(int16_t n) { printNumberln((int32_t)n); }; void printNumberln(int16_t n) {
printNumberln((int32_t) n);
};
/** /**
* Used to print unsigned integers. * Used to print unsigned integers.
@ -287,14 +316,19 @@ public:
* Get number of bytes waiting to be read. * Get number of bytes waiting to be read.
* @return Return the number of bytes ready to be read. * @return Return the number of bytes ready to be read.
*/ */
uint8_t available() { return rfcommAvailable; }; uint8_t available() {
return rfcommAvailable;
};
/** /**
* Used to read the buffer. * Used to read the buffer.
* @return Return the byte. Will return 0 if no byte is available. * @return Return the byte. Will return 0 if no byte is available.
*/ */
uint8_t read(); uint8_t read();
/** Discard all the bytes in the buffer. */ /** Discard all the bytes in the buffer. */
void flush() { rfcommAvailable = 0; }; void flush() {
rfcommAvailable = 0;
};
/**@}*/ /**@}*/
private: private:

87
Wii.cpp
View file

@ -101,6 +101,7 @@ pBtd(p) // pointer to USB class instance - mandatory
Reset(); Reset();
} }
void WII::Reset() { void WII::Reset() {
wiimoteConnected = false; wiimoteConnected = false;
nunchuckConnected = false; nunchuckConnected = false;
@ -157,8 +158,7 @@ void WII::ACLData(uint8_t* l2capinbuf) {
Notify(PSTR(" "), 0x80); Notify(PSTR(" "), 0x80);
PrintHex<uint8_t > (l2capinbuf[14], 0x80); PrintHex<uint8_t > (l2capinbuf[14], 0x80);
#endif #endif
} } else if (l2capinbuf[8] == L2CAP_CMD_CONNECTION_RESPONSE) {
else if (l2capinbuf[8] == L2CAP_CMD_CONNECTION_RESPONSE) {
if (((l2capinbuf[16] | (l2capinbuf[17] << 8)) == 0x0000) && ((l2capinbuf[18] | (l2capinbuf[19] << 8)) == SUCCESSFUL)) { // Success if (((l2capinbuf[16] | (l2capinbuf[17] << 8)) == 0x0000) && ((l2capinbuf[18] | (l2capinbuf[19] << 8)) == SUCCESSFUL)) { // Success
if (l2capinbuf[14] == control_dcid[0] && l2capinbuf[15] == control_dcid[1]) { // Success if (l2capinbuf[14] == control_dcid[0] && l2capinbuf[15] == control_dcid[1]) { // Success
//Serial.print("\r\nHID Control Connection Complete"); //Serial.print("\r\nHID Control Connection Complete");
@ -166,8 +166,7 @@ void WII::ACLData(uint8_t* l2capinbuf) {
control_scid[0] = l2capinbuf[12]; control_scid[0] = l2capinbuf[12];
control_scid[1] = l2capinbuf[13]; control_scid[1] = l2capinbuf[13];
l2cap_event_flag |= L2CAP_FLAG_CONTROL_CONNECTED; l2cap_event_flag |= L2CAP_FLAG_CONTROL_CONNECTED;
} } else if (l2capinbuf[14] == interrupt_dcid[0] && l2capinbuf[15] == interrupt_dcid[1]) {
else if (l2capinbuf[14] == interrupt_dcid[0] && l2capinbuf[15] == interrupt_dcid[1]) {
//Serial.print("\r\nHID Interrupt Connection Complete"); //Serial.print("\r\nHID Interrupt Connection Complete");
identifier = l2capinbuf[9]; identifier = l2capinbuf[9];
interrupt_scid[0] = l2capinbuf[12]; interrupt_scid[0] = l2capinbuf[12];
@ -175,8 +174,7 @@ void WII::ACLData(uint8_t* l2capinbuf) {
l2cap_event_flag |= L2CAP_FLAG_INTERRUPT_CONNECTED; l2cap_event_flag |= L2CAP_FLAG_INTERRUPT_CONNECTED;
} }
} }
} } else if (l2capinbuf[8] == L2CAP_CMD_CONNECTION_REQUEST) {
else if (l2capinbuf[8] == L2CAP_CMD_CONNECTION_REQUEST) {
#ifdef EXTRADEBUG #ifdef EXTRADEBUG
Notify(PSTR("\r\nL2CAP Connection Request - PSM: "), 0x80); Notify(PSTR("\r\nL2CAP Connection Request - PSM: "), 0x80);
PrintHex<uint8_t > (l2capinbuf[13], 0x80); PrintHex<uint8_t > (l2capinbuf[13], 0x80);
@ -194,39 +192,33 @@ void WII::ACLData(uint8_t* l2capinbuf) {
control_scid[0] = l2capinbuf[14]; control_scid[0] = l2capinbuf[14];
control_scid[1] = l2capinbuf[15]; control_scid[1] = l2capinbuf[15];
l2cap_event_flag |= L2CAP_FLAG_CONNECTION_CONTROL_REQUEST; l2cap_event_flag |= L2CAP_FLAG_CONNECTION_CONTROL_REQUEST;
} } else if ((l2capinbuf[12] | (l2capinbuf[13] << 8)) == HID_INTR_PSM) {
else if ((l2capinbuf[12] | (l2capinbuf[13] << 8)) == HID_INTR_PSM) {
identifier = l2capinbuf[9]; identifier = l2capinbuf[9];
interrupt_scid[0] = l2capinbuf[14]; interrupt_scid[0] = l2capinbuf[14];
interrupt_scid[1] = l2capinbuf[15]; interrupt_scid[1] = l2capinbuf[15];
l2cap_event_flag |= L2CAP_FLAG_CONNECTION_INTERRUPT_REQUEST; l2cap_event_flag |= L2CAP_FLAG_CONNECTION_INTERRUPT_REQUEST;
} }
} } else if (l2capinbuf[8] == L2CAP_CMD_CONFIG_RESPONSE) {
else if (l2capinbuf[8] == L2CAP_CMD_CONFIG_RESPONSE) {
if ((l2capinbuf[16] | (l2capinbuf[17] << 8)) == 0x0000) { // Success if ((l2capinbuf[16] | (l2capinbuf[17] << 8)) == 0x0000) { // Success
if (l2capinbuf[12] == control_dcid[0] && l2capinbuf[13] == control_dcid[1]) { if (l2capinbuf[12] == control_dcid[0] && l2capinbuf[13] == control_dcid[1]) {
//Serial.print("\r\nHID Control Configuration Complete"); //Serial.print("\r\nHID Control Configuration Complete");
identifier = l2capinbuf[9]; identifier = l2capinbuf[9];
l2cap_event_flag |= L2CAP_FLAG_CONFIG_CONTROL_SUCCESS; l2cap_event_flag |= L2CAP_FLAG_CONFIG_CONTROL_SUCCESS;
} } else if (l2capinbuf[12] == interrupt_dcid[0] && l2capinbuf[13] == interrupt_dcid[1]) {
else if (l2capinbuf[12] == interrupt_dcid[0] && l2capinbuf[13] == interrupt_dcid[1]) {
//Serial.print("\r\nHID Interrupt Configuration Complete"); //Serial.print("\r\nHID Interrupt Configuration Complete");
identifier = l2capinbuf[9]; identifier = l2capinbuf[9];
l2cap_event_flag |= L2CAP_FLAG_CONFIG_INTERRUPT_SUCCESS; l2cap_event_flag |= L2CAP_FLAG_CONFIG_INTERRUPT_SUCCESS;
} }
} }
} } else if (l2capinbuf[8] == L2CAP_CMD_CONFIG_REQUEST) {
else if (l2capinbuf[8] == L2CAP_CMD_CONFIG_REQUEST) {
if (l2capinbuf[12] == control_dcid[0] && l2capinbuf[13] == control_dcid[1]) { if (l2capinbuf[12] == control_dcid[0] && l2capinbuf[13] == control_dcid[1]) {
//Serial.print("\r\nHID Control Configuration Request"); //Serial.print("\r\nHID Control Configuration Request");
pBtd->l2cap_config_response(hci_handle, l2capinbuf[9], control_scid); pBtd->l2cap_config_response(hci_handle, l2capinbuf[9], control_scid);
} } else if (l2capinbuf[12] == interrupt_dcid[0] && l2capinbuf[13] == interrupt_dcid[1]) {
else if (l2capinbuf[12] == interrupt_dcid[0] && l2capinbuf[13] == interrupt_dcid[1]) {
//Serial.print("\r\nHID Interrupt Configuration Request"); //Serial.print("\r\nHID Interrupt Configuration Request");
pBtd->l2cap_config_response(hci_handle, l2capinbuf[9], interrupt_scid); pBtd->l2cap_config_response(hci_handle, l2capinbuf[9], interrupt_scid);
} }
} } else if (l2capinbuf[8] == L2CAP_CMD_DISCONNECT_REQUEST) {
else if (l2capinbuf[8] == L2CAP_CMD_DISCONNECT_REQUEST) {
if (l2capinbuf[12] == control_dcid[0] && l2capinbuf[13] == control_dcid[1]) { if (l2capinbuf[12] == control_dcid[0] && l2capinbuf[13] == control_dcid[1]) {
#ifdef DEBUG #ifdef DEBUG
Notify(PSTR("\r\nDisconnect Request: Control Channel"), 0x80); Notify(PSTR("\r\nDisconnect Request: Control Channel"), 0x80);
@ -234,8 +226,7 @@ void WII::ACLData(uint8_t* l2capinbuf) {
identifier = l2capinbuf[9]; identifier = l2capinbuf[9];
pBtd->l2cap_disconnection_response(hci_handle, identifier, control_dcid, control_scid); pBtd->l2cap_disconnection_response(hci_handle, identifier, control_dcid, control_scid);
Reset(); Reset();
} } else if (l2capinbuf[12] == interrupt_dcid[0] && l2capinbuf[13] == interrupt_dcid[1]) {
else if (l2capinbuf[12] == interrupt_dcid[0] && l2capinbuf[13] == interrupt_dcid[1]) {
#ifdef DEBUG #ifdef DEBUG
Notify(PSTR("\r\nDisconnect Request: Interrupt Channel"), 0x80); Notify(PSTR("\r\nDisconnect Request: Interrupt Channel"), 0x80);
#endif #endif
@ -243,14 +234,12 @@ void WII::ACLData(uint8_t* l2capinbuf) {
pBtd->l2cap_disconnection_response(hci_handle, identifier, interrupt_dcid, interrupt_scid); pBtd->l2cap_disconnection_response(hci_handle, identifier, interrupt_dcid, interrupt_scid);
Reset(); Reset();
} }
} } else if (l2capinbuf[8] == L2CAP_CMD_DISCONNECT_RESPONSE) {
else if (l2capinbuf[8] == L2CAP_CMD_DISCONNECT_RESPONSE) {
if (l2capinbuf[12] == control_scid[0] && l2capinbuf[13] == control_scid[1]) { if (l2capinbuf[12] == control_scid[0] && l2capinbuf[13] == control_scid[1]) {
//Serial.print("\r\nDisconnect Response: Control Channel"); //Serial.print("\r\nDisconnect Response: Control Channel");
identifier = l2capinbuf[9]; identifier = l2capinbuf[9];
l2cap_event_flag |= L2CAP_FLAG_DISCONNECT_CONTROL_RESPONSE; l2cap_event_flag |= L2CAP_FLAG_DISCONNECT_CONTROL_RESPONSE;
} } else if (l2capinbuf[12] == interrupt_scid[0] && l2capinbuf[13] == interrupt_scid[1]) {
else if (l2capinbuf[12] == interrupt_scid[0] && l2capinbuf[13] == interrupt_scid[1]) {
//Serial.print("\r\nDisconnect Response: Interrupt Channel"); //Serial.print("\r\nDisconnect Response: Interrupt Channel");
identifier = l2capinbuf[9]; identifier = l2capinbuf[9];
l2cap_event_flag |= L2CAP_FLAG_DISCONNECT_INTERRUPT_RESPONSE; l2cap_event_flag |= L2CAP_FLAG_DISCONNECT_INTERRUPT_RESPONSE;
@ -278,8 +267,7 @@ void WII::ACLData(uint8_t* l2capinbuf) {
else if (nunchuckConnected) // Update if it's a report from the Nunchuck else if (nunchuckConnected) // Update if it's a report from the Nunchuck
ButtonState = (uint32_t)((l2capinbuf[10] & 0x1F) | ((uint16_t)(l2capinbuf[11] & 0x9F) << 8) | ((uint32_t)((~l2capinbuf[20]) & 0x0C) << 14)); ButtonState = (uint32_t)((l2capinbuf[10] & 0x1F) | ((uint16_t)(l2capinbuf[11] & 0x9F) << 8) | ((uint32_t)((~l2capinbuf[20]) & 0x0C) << 14));
//else if(classicControllerConnected) // Update if it's a report from the Classic Controller //else if(classicControllerConnected) // Update if it's a report from the Classic Controller
} } else if (nunchuckConnected) // The Nunchuck is directly connected
else if(nunchuckConnected) // The Nunchuck is directly connected
ButtonState = (uint32_t)((l2capinbuf[10] & 0x1F) | ((uint16_t)(l2capinbuf[11] & 0x9F) << 8) | ((uint32_t)((~l2capinbuf[20]) & 0x03) << 16)); ButtonState = (uint32_t)((l2capinbuf[10] & 0x1F) | ((uint16_t)(l2capinbuf[11] & 0x9F) << 8) | ((uint32_t)((~l2capinbuf[20]) & 0x03) << 16));
//else if(classicControllerConnected) // The Classic Controller is directly connected //else if(classicControllerConnected) // The Classic Controller is directly connected
else if (!unknownExtensionConnected) else if (!unknownExtensionConnected)
@ -320,8 +308,7 @@ void WII::ACLData(uint8_t* l2capinbuf) {
if (!isIRCameraEnabled()) // Don't activate the Motion Plus if we are trying to initialize the IR camera if (!isIRCameraEnabled()) // Don't activate the Motion Plus if we are trying to initialize the IR camera
#endif #endif
setReportMode(false, 0x35); // Also read the extension setReportMode(false, 0x35); // Also read the extension
} } else {
else {
#ifdef DEBUG #ifdef DEBUG
Notify(PSTR("\r\nExtension disconnected"), 0x80); Notify(PSTR("\r\nExtension disconnected"), 0x80);
#endif #endif
@ -333,8 +320,7 @@ void WII::ACLData(uint8_t* l2capinbuf) {
if (!activateNunchuck) // If it's already trying to initialize the Nunchuck don't set it to false if (!activateNunchuck) // If it's already trying to initialize the Nunchuck don't set it to false
nunchuckConnected = false; nunchuckConnected = false;
//else if(classicControllerConnected) //else if(classicControllerConnected)
} } else if (nunchuckConnected) {
else if(nunchuckConnected) {
#ifdef DEBUG #ifdef DEBUG
Notify(PSTR(" - Nunchuck"), 0x80); Notify(PSTR(" - Nunchuck"), 0x80);
#endif #endif
@ -549,8 +535,7 @@ void WII::ACLData(uint8_t* l2capinbuf) {
Notify(PSTR("\r\nExtension connected to Motion Plus"), 0x80); Notify(PSTR("\r\nExtension connected to Motion Plus"), 0x80);
#endif #endif
} }
} } else {
else {
if (extensionConnected && !unknownExtensionConnected) { if (extensionConnected && !unknownExtensionConnected) {
extensionConnected = false; extensionConnected = false;
unknownExtensionConnected = true; unknownExtensionConnected = true;
@ -592,6 +577,7 @@ void WII::ACLData(uint8_t* l2capinbuf) {
L2CAP_task(); L2CAP_task();
} }
} }
void WII::L2CAP_task() { void WII::L2CAP_task() {
switch (l2cap_state) { switch (l2cap_state) {
/* These states are used if the Wiimote is the host */ /* These states are used if the Wiimote is the host */
@ -693,6 +679,7 @@ void WII::L2CAP_task() {
break; break;
} }
} }
void WII::Run() { void WII::Run() {
switch (l2cap_state) { switch (l2cap_state) {
case L2CAP_WAIT: case L2CAP_WAIT:
@ -741,8 +728,7 @@ void WII::Run() {
activateNunchuck = true; // For we will just set this to true as this the only extension supported so far activateNunchuck = true; // For we will just set this to true as this the only extension supported so far
} }
} } else if (stateCounter == 601) { // We will try three times to check for the motion plus
else if(stateCounter == 601) { // We will try three times to check for the motion plus
#ifdef DEBUG #ifdef DEBUG
Notify(PSTR("\r\nNo Motion Plus was detected"), 0x80); Notify(PSTR("\r\nNo Motion Plus was detected"), 0x80);
#endif #endif
@ -825,8 +811,7 @@ void WII::Run() {
} }
if (!motionPlusConnected) if (!motionPlusConnected)
stateCounter = 449; stateCounter = 449;
} } else if (stateCounter == 300) {
else if (stateCounter == 300) {
if (motionPlusConnected) { if (motionPlusConnected) {
#ifdef DEBUG #ifdef DEBUG
Notify(PSTR("\r\nReactivating the Motion Plus"), 0x80); Notify(PSTR("\r\nReactivating the Motion Plus"), 0x80);
@ -834,8 +819,7 @@ void WII::Run() {
initMotionPlus(); initMotionPlus();
} else } else
stateCounter = 449; stateCounter = 449;
} } else if (stateCounter == 350)
else if(stateCounter == 350)
activateMotionPlus(); activateMotionPlus();
else if (stateCounter == 400) else if (stateCounter == 400)
readExtensionType(); // Check if it has been activated readExtensionType(); // Check if it has been activated
@ -852,6 +836,7 @@ void WII::Run() {
/************************************************************/ /************************************************************/
/* HID Commands */ /* HID Commands */
/************************************************************/ /************************************************************/
void WII::HID_Command(uint8_t* data, uint8_t nbytes) { void WII::HID_Command(uint8_t* data, uint8_t nbytes) {
if (pBtd->motionPlusInside) if (pBtd->motionPlusInside)
@ -859,41 +844,49 @@ void WII::HID_Command(uint8_t* data, uint8_t nbytes) {
else else
pBtd->L2CAP_Command(hci_handle, data, nbytes, control_scid[0], control_scid[1]); pBtd->L2CAP_Command(hci_handle, data, nbytes, control_scid[0], control_scid[1]);
} }
void WII::setAllOff() { void WII::setAllOff() {
HIDBuffer[1] = 0x11; HIDBuffer[1] = 0x11;
HIDBuffer[2] = 0x00; HIDBuffer[2] = 0x00;
HID_Command(HIDBuffer, 3); HID_Command(HIDBuffer, 3);
} }
void WII::setRumbleOff() { void WII::setRumbleOff() {
HIDBuffer[1] = 0x11; HIDBuffer[1] = 0x11;
HIDBuffer[2] &= ~0x01; // Bit 0 control the rumble HIDBuffer[2] &= ~0x01; // Bit 0 control the rumble
HID_Command(HIDBuffer, 3); HID_Command(HIDBuffer, 3);
} }
void WII::setRumbleOn() { void WII::setRumbleOn() {
HIDBuffer[1] = 0x11; HIDBuffer[1] = 0x11;
HIDBuffer[2] |= 0x01; // Bit 0 control the rumble HIDBuffer[2] |= 0x01; // Bit 0 control the rumble
HID_Command(HIDBuffer, 3); HID_Command(HIDBuffer, 3);
} }
void WII::setRumbleToggle() { void WII::setRumbleToggle() {
HIDBuffer[1] = 0x11; HIDBuffer[1] = 0x11;
HIDBuffer[2] ^= 0x01; // Bit 0 control the rumble HIDBuffer[2] ^= 0x01; // Bit 0 control the rumble
HID_Command(HIDBuffer, 3); HID_Command(HIDBuffer, 3);
} }
void WII::setLedOff(LED a) { void WII::setLedOff(LED a) {
HIDBuffer[1] = 0x11; HIDBuffer[1] = 0x11;
HIDBuffer[2] &= ~(pgm_read_byte(&LEDS[(uint8_t)a])); HIDBuffer[2] &= ~(pgm_read_byte(&LEDS[(uint8_t)a]));
HID_Command(HIDBuffer, 3); HID_Command(HIDBuffer, 3);
} }
void WII::setLedOn(LED a) { void WII::setLedOn(LED a) {
HIDBuffer[1] = 0x11; HIDBuffer[1] = 0x11;
HIDBuffer[2] |= pgm_read_byte(&LEDS[(uint8_t)a]); HIDBuffer[2] |= pgm_read_byte(&LEDS[(uint8_t)a]);
HID_Command(HIDBuffer, 3); HID_Command(HIDBuffer, 3);
} }
void WII::setLedToggle(LED a) { void WII::setLedToggle(LED a) {
HIDBuffer[1] = 0x11; HIDBuffer[1] = 0x11;
HIDBuffer[2] ^= pgm_read_byte(&LEDS[(uint8_t)a]); HIDBuffer[2] ^= pgm_read_byte(&LEDS[(uint8_t)a]);
HID_Command(HIDBuffer, 3); HID_Command(HIDBuffer, 3);
} }
void WII::setLedStatus() { void WII::setLedStatus() {
HIDBuffer[1] = 0x11; HIDBuffer[1] = 0x11;
HIDBuffer[2] = (HIDBuffer[2] & 0x01); // Keep the rumble bit HIDBuffer[2] = (HIDBuffer[2] & 0x01); // Keep the rumble bit
@ -906,6 +899,7 @@ void WII::setLedStatus() {
HID_Command(HIDBuffer, 3); HID_Command(HIDBuffer, 3);
} }
void WII::setReportMode(bool continuous, uint8_t mode) { void WII::setReportMode(bool continuous, uint8_t mode) {
uint8_t cmd_buf[4]; uint8_t cmd_buf[4];
cmd_buf[0] = 0xA2; // HID BT DATA_request (0xA0) | Report Type (Output 0x02) cmd_buf[0] = 0xA2; // HID BT DATA_request (0xA0) | Report Type (Output 0x02)
@ -917,6 +911,7 @@ void WII::setReportMode(bool continuous, uint8_t mode) {
cmd_buf[3] = mode; cmd_buf[3] = mode;
HID_Command(cmd_buf, 4); HID_Command(cmd_buf, 4);
} }
void WII::statusRequest() { void WII::statusRequest() {
uint8_t cmd_buf[3]; uint8_t cmd_buf[3];
cmd_buf[0] = 0xA2; // HID BT DATA_request (0xA0) | Report Type (Output 0x02) cmd_buf[0] = 0xA2; // HID BT DATA_request (0xA0) | Report Type (Output 0x02)
@ -927,6 +922,7 @@ void WII::statusRequest() {
/************************************************************/ /************************************************************/
/* Memmory Commands */ /* Memmory Commands */
/************************************************************/ /************************************************************/
void WII::writeData(uint32_t offset, uint8_t size, uint8_t* data) { void WII::writeData(uint32_t offset, uint8_t size, uint8_t* data) {
uint8_t cmd_buf[23]; uint8_t cmd_buf[23];
@ -944,21 +940,25 @@ void WII::writeData(uint32_t offset, uint8_t size, uint8_t* data) {
cmd_buf[7 + i] = 0x00; cmd_buf[7 + i] = 0x00;
HID_Command(cmd_buf, 23); HID_Command(cmd_buf, 23);
} }
void WII::initExtension1() { void WII::initExtension1() {
uint8_t buf[1]; uint8_t buf[1];
buf[0] = 0x55; buf[0] = 0x55;
writeData(0xA400F0, 1, buf); writeData(0xA400F0, 1, buf);
} }
void WII::initExtension2() { void WII::initExtension2() {
uint8_t buf[1]; uint8_t buf[1];
buf[0] = 0x00; buf[0] = 0x00;
writeData(0xA400FB, 1, buf); writeData(0xA400FB, 1, buf);
} }
void WII::initMotionPlus() { void WII::initMotionPlus() {
uint8_t buf[1]; uint8_t buf[1];
buf[0] = 0x55; buf[0] = 0x55;
writeData(0xA600F0, 1, buf); writeData(0xA600F0, 1, buf);
} }
void WII::activateMotionPlus() { void WII::activateMotionPlus() {
uint8_t buf[1]; uint8_t buf[1];
if (pBtd->wiiUProController) { if (pBtd->wiiUProController) {
@ -971,8 +971,7 @@ void WII::activateMotionPlus() {
Notify(PSTR("\r\nActivating Motion Plus in pass-through mode"), 0x80); Notify(PSTR("\r\nActivating Motion Plus in pass-through mode"), 0x80);
#endif #endif
buf[0] = 0x05; // Activate nunchuck pass-through mode buf[0] = 0x05; // Activate nunchuck pass-through mode
} } //else if(classicControllerConnected && extensionConnected)
//else if(classicControllerConnected && extensionConnected)
//buf[0] = 0x07; //buf[0] = 0x07;
else { else {
#ifdef DEBUG #ifdef DEBUG
@ -982,6 +981,7 @@ void WII::activateMotionPlus() {
} }
writeData(0xA600FE, 1, buf); writeData(0xA600FE, 1, buf);
} }
void WII::readData(uint32_t offset, uint16_t size, bool EEPROM) { void WII::readData(uint32_t offset, uint16_t size, bool EEPROM) {
uint8_t cmd_buf[8]; uint8_t cmd_buf[8];
cmd_buf[0] = 0xA2; // HID BT DATA_request (0xA0) | Report Type (Output 0x02) cmd_buf[0] = 0xA2; // HID BT DATA_request (0xA0) | Report Type (Output 0x02)
@ -998,18 +998,22 @@ void WII::readData(uint32_t offset, uint16_t size, bool EEPROM) {
HID_Command(cmd_buf, 8); HID_Command(cmd_buf, 8);
} }
void WII::readExtensionType() { void WII::readExtensionType() {
readData(0xA400FA, 6, false); readData(0xA400FA, 6, false);
} }
void WII::readCalData() { void WII::readCalData() {
readData(0x0016, 8, true); readData(0x0016, 8, true);
} }
void WII::checkMotionPresent() { void WII::checkMotionPresent() {
readData(0xA600FA, 6, false); readData(0xA600FA, 6, false);
} }
/************************************************************/ /************************************************************/
/* WII Commands */ /* WII Commands */
/************************************************************/ /************************************************************/
bool WII::getButtonPress(Button b) { // Return true when a button is pressed bool WII::getButtonPress(Button b) { // Return true when a button is pressed
@ -1018,6 +1022,7 @@ bool WII::getButtonPress(Button b) { // Return true when a button is pressed
else else
return (ButtonState & pgm_read_dword(&BUTTONS[(uint8_t)b])); return (ButtonState & pgm_read_dword(&BUTTONS[(uint8_t)b]));
} }
bool WII::getButtonClick(Button b) { // Only return true when a button is clicked bool WII::getButtonClick(Button b) { // Only return true when a button is clicked
uint32_t button; uint32_t button;
if (wiiUProControllerConnected) if (wiiUProControllerConnected)
@ -1028,6 +1033,7 @@ bool WII::getButtonClick(Button b) { // Only return true when a button is clicke
ButtonClickState &= ~button; // clear "click" event ButtonClickState &= ~button; // clear "click" event
return click; return click;
} }
uint8_t WII::getAnalogHat(Hat a) { uint8_t WII::getAnalogHat(Hat a) {
if (!nunchuckConnected) if (!nunchuckConnected)
return 127; // Return center position return 127; // Return center position
@ -1039,6 +1045,7 @@ uint8_t WII::getAnalogHat(Hat a) {
return output; return output;
} }
} }
uint16_t WII::getAnalogHat(AnalogHat a) { uint16_t WII::getAnalogHat(AnalogHat a) {
if (!wiiUProControllerConnected) if (!wiiUProControllerConnected)
return 2000; return 2000;

83
Wii.h
View file

@ -148,19 +148,27 @@ public:
* Pitch calculated from the Wiimote. A complimentary filter is used if the Motion Plus is connected. * Pitch calculated from the Wiimote. A complimentary filter is used if the Motion Plus is connected.
* @return Pitch in the range from 0-360. * @return Pitch in the range from 0-360.
*/ */
double getPitch() { return pitch; }; double getPitch() {
return pitch;
};
/** /**
* Roll calculated from the Wiimote. A complimentary filter is used if the Motion Plus is connected. * Roll calculated from the Wiimote. A complimentary filter is used if the Motion Plus is connected.
* @return Roll in the range from 0-360. * @return Roll in the range from 0-360.
*/ */
double getRoll() { return roll; }; double getRoll() {
return roll;
};
/** /**
* This is the yaw calculated by the gyro. * This is the yaw calculated by the gyro.
* *
* <B>NOTE:</B> This angle will drift a lot and is only available if the Motion Plus extension is connected. * <B>NOTE:</B> This angle will drift a lot and is only available if the Motion Plus extension is connected.
* @return The angle calculated using the gyro. * @return The angle calculated using the gyro.
*/ */
double getYaw() { return gyroYaw; }; double getYaw() {
return gyroYaw;
};
/** Used to set all LEDs and rumble off. */ /** Used to set all LEDs and rumble off. */
void setAllOff(); void setAllOff();
@ -200,12 +208,17 @@ public:
* Return the battery level of the Wiimote. * Return the battery level of the Wiimote.
* @return The battery level in the range 0-255. * @return The battery level in the range 0-255.
*/ */
uint8_t getBatteryLevel() { return batteryLevel; }; uint8_t getBatteryLevel() {
return batteryLevel;
};
/** /**
* Return the Wiimote state. * Return the Wiimote state.
* @return See: http://wiibrew.org/wiki/Wiimote#0x20:_Status. * @return See: http://wiibrew.org/wiki/Wiimote#0x20:_Status.
*/ */
uint8_t getWiiState() { return wiiState; }; uint8_t getWiiState() {
return wiiState;
};
/**@}*/ /**@}*/
/**@{*/ /**@{*/
@ -287,72 +300,106 @@ public:
* IR object 1 x-position read from the Wii IR camera. * IR object 1 x-position read from the Wii IR camera.
* @return The x-position of the object in the range 0-1023. * @return The x-position of the object in the range 0-1023.
*/ */
uint16_t getIRx1() { return IR_object_x1; }; uint16_t getIRx1() {
return IR_object_x1;
};
/** /**
* IR object 1 y-position read from the Wii IR camera. * IR object 1 y-position read from the Wii IR camera.
* @return The y-position of the object in the range 0-767. * @return The y-position of the object in the range 0-767.
*/ */
uint16_t getIRy1() { return IR_object_y1; }; uint16_t getIRy1() {
return IR_object_y1;
};
/** /**
* IR object 1 size read from the Wii IR camera. * IR object 1 size read from the Wii IR camera.
* @return The size of the object in the range 0-15. * @return The size of the object in the range 0-15.
*/ */
uint8_t getIRs1() { return IR_object_s1; }; uint8_t getIRs1() {
return IR_object_s1;
};
/** /**
* IR object 2 x-position read from the Wii IR camera. * IR object 2 x-position read from the Wii IR camera.
* @return The x-position of the object in the range 0-1023. * @return The x-position of the object in the range 0-1023.
*/ */
uint16_t getIRx2() { return IR_object_x2; }; uint16_t getIRx2() {
return IR_object_x2;
};
/** /**
* IR object 2 y-position read from the Wii IR camera. * IR object 2 y-position read from the Wii IR camera.
* @return The y-position of the object in the range 0-767. * @return The y-position of the object in the range 0-767.
*/ */
uint16_t getIRy2() { return IR_object_y2; }; uint16_t getIRy2() {
return IR_object_y2;
};
/** /**
* IR object 2 size read from the Wii IR camera. * IR object 2 size read from the Wii IR camera.
* @return The size of the object in the range 0-15. * @return The size of the object in the range 0-15.
*/ */
uint8_t getIRs2() { return IR_object_s2; }; uint8_t getIRs2() {
return IR_object_s2;
};
/** /**
* IR object 3 x-position read from the Wii IR camera. * IR object 3 x-position read from the Wii IR camera.
* @return The x-position of the object in the range 0-1023. * @return The x-position of the object in the range 0-1023.
*/ */
uint16_t getIRx3() { return IR_object_x3; }; uint16_t getIRx3() {
return IR_object_x3;
};
/** /**
* IR object 3 y-position read from the Wii IR camera. * IR object 3 y-position read from the Wii IR camera.
* @return The y-position of the object in the range 0-767. * @return The y-position of the object in the range 0-767.
*/ */
uint16_t getIRy3() { return IR_object_y3; }; uint16_t getIRy3() {
return IR_object_y3;
};
/** /**
* IR object 3 size read from the Wii IR camera. * IR object 3 size read from the Wii IR camera.
* @return The size of the object in the range 0-15. * @return The size of the object in the range 0-15.
*/ */
uint8_t getIRs3() { return IR_object_s3; }; uint8_t getIRs3() {
return IR_object_s3;
};
/** /**
* IR object 4 x-position read from the Wii IR camera. * IR object 4 x-position read from the Wii IR camera.
* @return The x-position of the object in the range 0-1023. * @return The x-position of the object in the range 0-1023.
*/ */
uint16_t getIRx4() { return IR_object_x4; }; uint16_t getIRx4() {
return IR_object_x4;
};
/** /**
* IR object 4 y-position read from the Wii IR camera. * IR object 4 y-position read from the Wii IR camera.
* @return The y-position of the object in the range 0-767. * @return The y-position of the object in the range 0-767.
*/ */
uint16_t getIRy4() { return IR_object_y4; }; uint16_t getIRy4() {
return IR_object_y4;
};
/** /**
* IR object 4 size read from the Wii IR camera. * IR object 4 size read from the Wii IR camera.
* @return The size of the object in the range 0-15. * @return The size of the object in the range 0-15.
*/ */
uint8_t getIRs4() { return IR_object_s4; }; uint8_t getIRs4() {
return IR_object_s4;
};
/** /**
* Use this to check if the camera is enabled or not. * Use this to check if the camera is enabled or not.
* If not call WII#IRinitialize to initialize the IR camera. * If not call WII#IRinitialize to initialize the IR camera.
* @return True if it's enabled, false if not. * @return True if it's enabled, false if not.
*/ */
bool isIRCameraEnabled() { return (wiiState & 0x08); }; bool isIRCameraEnabled() {
return(wiiState & 0x08);
};
/**@}*/ /**@}*/
#endif #endif

View file

@ -260,6 +260,7 @@ uint8_t XBOXRECV::Release() {
bPollEnable = false; bPollEnable = false;
return 0; return 0;
} }
uint8_t XBOXRECV::Poll() { uint8_t XBOXRECV::Poll() {
if (!bPollEnable) if (!bPollEnable)
return 0; return 0;
@ -271,10 +272,14 @@ uint8_t XBOXRECV::Poll() {
uint16_t bufferSize; uint16_t bufferSize;
for (uint8_t i = 0; i < 4; i++) { for (uint8_t i = 0; i < 4; i++) {
switch (i) { switch (i) {
case 0: inputPipe = XBOX_INPUT_PIPE_1; break; case 0: inputPipe = XBOX_INPUT_PIPE_1;
case 1: inputPipe = XBOX_INPUT_PIPE_2; break; break;
case 2: inputPipe = XBOX_INPUT_PIPE_3; break; case 1: inputPipe = XBOX_INPUT_PIPE_2;
case 3: inputPipe = XBOX_INPUT_PIPE_4; break; break;
case 2: inputPipe = XBOX_INPUT_PIPE_3;
break;
case 3: inputPipe = XBOX_INPUT_PIPE_4;
break;
} }
bufferSize = EP_MAXPKTSIZE; // This is the maximum number of bytes we want to receive bufferSize = EP_MAXPKTSIZE; // This is the maximum number of bytes we want to receive
pUsb->inTransfer(bAddress, epInfo[ inputPipe ].epAddr, &bufferSize, readBuf); pUsb->inTransfer(bAddress, epInfo[ inputPipe ].epAddr, &bufferSize, readBuf);
@ -307,19 +312,26 @@ void XBOXRECV::readReport(uint8_t controller) {
#ifdef DEBUG #ifdef DEBUG
char* str = 0; char* str = 0;
switch (readBuf[1]) { switch (readBuf[1]) {
case 0x80: str = PSTR(" as controller\r\n"); break; case 0x80: str = PSTR(" as controller\r\n");
case 0x40: str = PSTR(" as headset\r\n"); break; break;
case 0xC0: str = PSTR(" as controller+headset\r\n"); break; case 0x40: str = PSTR(" as headset\r\n");
break;
case 0xC0: str = PSTR(" as controller+headset\r\n");
break;
} }
Notify(PSTR(": connected"), 0x80); Notify(PSTR(": connected"), 0x80);
Notify(str, 0x80); Notify(str, 0x80);
#endif #endif
LED led; LED led;
switch (controller) { switch (controller) {
case 0: led = LED1; break; case 0: led = LED1;
case 1: led = LED2; break; break;
case 2: led = LED3; break; case 1: led = LED2;
case 3: led = LED4; break; break;
case 2: led = LED3;
break;
case 3: led = LED4;
break;
} }
setLedOn(controller, led); setLedOn(controller, led);
} }
@ -376,6 +388,7 @@ void XBOXRECV::printReport(uint8_t controller, uint8_t nBytes) { //Uncomment "#d
Serial.println(); Serial.println();
#endif #endif
} }
uint8_t XBOXRECV::getButtonPress(uint8_t controller, Button b) { uint8_t XBOXRECV::getButtonPress(uint8_t controller, Button b) {
if (b == L2) // These are analog buttons if (b == L2) // These are analog buttons
return (uint8_t)(ButtonState[controller] >> 8); return (uint8_t)(ButtonState[controller] >> 8);
@ -383,6 +396,7 @@ uint8_t XBOXRECV::getButtonPress(uint8_t controller, Button b) {
return (uint8_t)ButtonState[controller]; return (uint8_t)ButtonState[controller];
return (ButtonState[controller] & ((uint32_t)pgm_read_word(&XBOXBUTTONS[(uint8_t)b]) << 16)); return (ButtonState[controller] & ((uint32_t)pgm_read_word(&XBOXBUTTONS[(uint8_t)b]) << 16));
} }
bool XBOXRECV::getButtonClick(uint8_t controller, Button b) { bool XBOXRECV::getButtonClick(uint8_t controller, Button b) {
if (b == L2) { if (b == L2) {
if (L2Clicked[controller]) { if (L2Clicked[controller]) {
@ -390,8 +404,7 @@ bool XBOXRECV::getButtonClick(uint8_t controller, Button b) {
return true; return true;
} }
return false; return false;
} } else if (b == R2) {
else if(b == R2) {
if (R2Clicked[controller]) { if (R2Clicked[controller]) {
R2Clicked[controller] = false; R2Clicked[controller] = false;
return true; return true;
@ -403,14 +416,17 @@ bool XBOXRECV::getButtonClick(uint8_t controller, Button b) {
ButtonClickState[controller] &= ~button; // clear "click" event ButtonClickState[controller] &= ~button; // clear "click" event
return click; return click;
} }
int16_t XBOXRECV::getAnalogHat(uint8_t controller, AnalogHat a) { int16_t XBOXRECV::getAnalogHat(uint8_t controller, AnalogHat a) {
return hatValue[controller][a]; return hatValue[controller][a];
} }
bool XBOXRECV::buttonChanged(uint8_t controller) { bool XBOXRECV::buttonChanged(uint8_t controller) {
bool state = buttonStateChanged[controller]; bool state = buttonStateChanged[controller];
buttonStateChanged[controller] = false; buttonStateChanged[controller] = false;
return state; return state;
} }
/* /*
ControllerStatus Breakdown ControllerStatus Breakdown
ControllerStatus[controller] & 0x0001 // 0 ControllerStatus[controller] & 0x0001 // 0
@ -441,10 +457,14 @@ void XBOXRECV::XboxCommand(uint8_t controller, uint8_t* data, uint16_t nbytes) {
uint8_t rcode; uint8_t rcode;
uint8_t outputPipe; uint8_t outputPipe;
switch (controller) { switch (controller) {
case 0: outputPipe = XBOX_OUTPUT_PIPE_1; break; case 0: outputPipe = XBOX_OUTPUT_PIPE_1;
case 1: outputPipe = XBOX_OUTPUT_PIPE_2; break; break;
case 2: outputPipe = XBOX_OUTPUT_PIPE_3; break; case 1: outputPipe = XBOX_OUTPUT_PIPE_2;
case 3: outputPipe = XBOX_OUTPUT_PIPE_4; break; break;
case 2: outputPipe = XBOX_OUTPUT_PIPE_3;
break;
case 3: outputPipe = XBOX_OUTPUT_PIPE_4;
break;
} }
rcode = pUsb->outTransfer(bAddress, epInfo[ outputPipe ].epAddr, nbytes, data); rcode = pUsb->outTransfer(bAddress, epInfo[ outputPipe ].epAddr, nbytes, data);
#ifdef EXTRADEBUG #ifdef EXTRADEBUG
@ -452,6 +472,7 @@ void XBOXRECV::XboxCommand(uint8_t controller, uint8_t* data, uint16_t nbytes) {
Notify(PSTR("Error sending Xbox message\r\n"), 0x80); Notify(PSTR("Error sending Xbox message\r\n"), 0x80);
#endif #endif
} }
void XBOXRECV::setLedRaw(uint8_t controller, uint8_t value) { void XBOXRECV::setLedRaw(uint8_t controller, uint8_t value) {
writeBuf[0] = 0x00; writeBuf[0] = 0x00;
writeBuf[1] = 0x00; writeBuf[1] = 0x00;
@ -460,16 +481,20 @@ void XBOXRECV::setLedRaw(uint8_t controller, uint8_t value) {
XboxCommand(controller, writeBuf, 4); XboxCommand(controller, writeBuf, 4);
} }
void XBOXRECV::setLedOn(uint8_t controller, LED led) { void XBOXRECV::setLedOn(uint8_t controller, LED led) {
if (led != ALL) // All LEDs can't be on a the same time if (led != ALL) // All LEDs can't be on a the same time
setLedRaw(controller, (pgm_read_byte(&XBOXLEDS[(uint8_t)led])) + 4); setLedRaw(controller, (pgm_read_byte(&XBOXLEDS[(uint8_t)led])) + 4);
} }
void XBOXRECV::setLedBlink(uint8_t controller, LED led) { void XBOXRECV::setLedBlink(uint8_t controller, LED led) {
setLedRaw(controller, pgm_read_byte(&XBOXLEDS[(uint8_t)led])); setLedRaw(controller, pgm_read_byte(&XBOXLEDS[(uint8_t)led]));
} }
void XBOXRECV::setLedMode(uint8_t controller, LEDMode ledMode) { // This function is used to do some speciel LED stuff the controller supports void XBOXRECV::setLedMode(uint8_t controller, LEDMode ledMode) { // This function is used to do some speciel LED stuff the controller supports
setLedRaw(controller, (uint8_t)ledMode); setLedRaw(controller, (uint8_t)ledMode);
} }
/* PC runs this at interval of approx 2 seconds /* PC runs this at interval of approx 2 seconds
Thanks to BusHound from Perisoft.net for the Windows USB Analysis output Thanks to BusHound from Perisoft.net for the Windows USB Analysis output
Found by timstamp.co.uk Found by timstamp.co.uk

View file

@ -87,16 +87,22 @@ public:
* @return 0 on success. * @return 0 on success.
*/ */
virtual uint8_t Poll(); virtual uint8_t Poll();
/** /**
* Get the device address. * Get the device address.
* @return The device address. * @return The device address.
*/ */
virtual uint8_t GetAddress() { return bAddress; }; virtual uint8_t GetAddress() {
return bAddress;
};
/** /**
* Used to check if the controller has been initialized. * Used to check if the controller has been initialized.
* @return True if it's ready. * @return True if it's ready.
*/ */
virtual bool isReady() { return bPollEnable; }; virtual bool isReady() {
return bPollEnable;
};
/**@}*/ /**@}*/
/** @name Xbox Controller functions */ /** @name Xbox Controller functions */
@ -124,16 +130,23 @@ public:
* @return Returns a signed 16-bit integer. * @return Returns a signed 16-bit integer.
*/ */
int16_t getAnalogHat(uint8_t controller, AnalogHat a); int16_t getAnalogHat(uint8_t controller, AnalogHat a);
/** /**
* Turn rumble off and all the LEDs on the specific controller. * Turn rumble off and all the LEDs on the specific controller.
* @param controller The controller to write to. * @param controller The controller to write to.
*/ */
void setAllOff(uint8_t controller) { setRumbleOn(controller,0,0); setLedOff(controller); }; void setAllOff(uint8_t controller) {
setRumbleOn(controller, 0, 0);
setLedOff(controller);
};
/** /**
* Turn rumble off the specific controller. * Turn rumble off the specific controller.
* @param controller The controller to write to. * @param controller The controller to write to.
*/ */
void setRumbleOff(uint8_t controller) { setRumbleOn(controller,0,0); }; void setRumbleOff(uint8_t controller) {
setRumbleOn(controller, 0, 0);
};
/** /**
* Turn rumble on. * Turn rumble on.
* @param controller The controller to write to. * @param controller The controller to write to.
@ -149,11 +162,14 @@ public:
* setLedBlink(uint8_t controller, LED l), and setLedMode(uint8_t controller, LEDMode lm). * setLedBlink(uint8_t controller, LED l), and setLedMode(uint8_t controller, LEDMode lm).
*/ */
void setLedRaw(uint8_t controller, uint8_t value); void setLedRaw(uint8_t controller, uint8_t value);
/** /**
* Turn all LEDs off the specific controller. * Turn all LEDs off the specific controller.
* @param controller The controller to write to. * @param controller The controller to write to.
*/ */
void setLedOff(uint8_t controller) { setLedRaw(controller,0); }; void setLedOff(uint8_t controller) {
setLedRaw(controller, 0);
};
/** /**
* Turn on a LED by using the ::LED enum. * Turn on a LED by using the ::LED enum.
* @param controller The controller to write to. * @param controller The controller to write to.

View file

@ -99,8 +99,7 @@ uint8_t XBOXUSB::Init(uint8_t parent, uint8_t port, bool lowspeed) {
Notify(PSTR("\r\nYou have plugged in a wireless Xbox 360 controller - it doesn't support USB communication"), 0x80); Notify(PSTR("\r\nYou have plugged in a wireless Xbox 360 controller - it doesn't support USB communication"), 0x80);
#endif #endif
goto FailUnknownDevice; goto FailUnknownDevice;
} } else if (PID == XBOX_WIRELESS_RECEIVER_PID || PID == XBOX_WIRELESS_RECEIVER_THIRD_PARTY_PID) {
else if(PID == XBOX_WIRELESS_RECEIVER_PID || PID == XBOX_WIRELESS_RECEIVER_THIRD_PARTY_PID) {
#ifdef DEBUG #ifdef DEBUG
Notify(PSTR("\r\nThis library only supports Xbox 360 controllers via USB"), 0x80); Notify(PSTR("\r\nThis library only supports Xbox 360 controllers via USB"), 0x80);
#endif #endif
@ -224,6 +223,7 @@ uint8_t XBOXUSB::Release() {
bPollEnable = false; bPollEnable = false;
return 0; return 0;
} }
uint8_t XBOXUSB::Poll() { uint8_t XBOXUSB::Poll() {
if (!bPollEnable) if (!bPollEnable)
return 0; return 0;
@ -282,6 +282,7 @@ uint8_t XBOXUSB::getButtonPress(Button b) {
return (uint8_t)ButtonState; return (uint8_t)ButtonState;
return (ButtonState & ((uint32_t)pgm_read_word(&XBOXBUTTONS[(uint8_t)b]) << 16)); return (ButtonState & ((uint32_t)pgm_read_word(&XBOXBUTTONS[(uint8_t)b]) << 16));
} }
bool XBOXUSB::getButtonClick(Button b) { bool XBOXUSB::getButtonClick(Button b) {
if (b == L2) { if (b == L2) {
if (L2Clicked) { if (L2Clicked) {
@ -289,8 +290,7 @@ bool XBOXUSB::getButtonClick(Button b) {
return true; return true;
} }
return false; return false;
} } else if (b == R2) {
else if(b == R2) {
if (R2Clicked) { if (R2Clicked) {
R2Clicked = false; R2Clicked = false;
return true; return true;
@ -302,6 +302,7 @@ bool XBOXUSB::getButtonClick(Button b) {
ButtonClickState &= ~button; // clear "click" event ButtonClickState &= ~button; // clear "click" event
return click; return click;
} }
int16_t XBOXUSB::getAnalogHat(AnalogHat a) { int16_t XBOXUSB::getAnalogHat(AnalogHat a) {
return hatValue[a]; return hatValue[a];
} }
@ -311,6 +312,7 @@ void XBOXUSB::XboxCommand(uint8_t* data, uint16_t nbytes) {
//bmRequest = Host to device (0x00) | Class (0x20) | Interface (0x01) = 0x21, bRequest = Set Report (0x09), Report ID (0x00), Report Type (Output 0x02), interface (0x00), datalength, datalength, data) //bmRequest = Host to device (0x00) | Class (0x20) | Interface (0x01) = 0x21, bRequest = Set Report (0x09), Report ID (0x00), Report Type (Output 0x02), interface (0x00), datalength, datalength, data)
pUsb->ctrlReq(bAddress, epInfo[XBOX_CONTROL_PIPE].epAddr, bmREQ_HID_OUT, HID_REQUEST_SET_REPORT, 0x00, 0x02, 0x00, nbytes, nbytes, data, NULL); pUsb->ctrlReq(bAddress, epInfo[XBOX_CONTROL_PIPE].epAddr, bmREQ_HID_OUT, HID_REQUEST_SET_REPORT, 0x00, 0x02, 0x00, nbytes, nbytes, data, NULL);
} }
void XBOXUSB::setLedRaw(uint8_t value) { void XBOXUSB::setLedRaw(uint8_t value) {
writeBuf[0] = 0x01; writeBuf[0] = 0x01;
writeBuf[1] = 0x03; writeBuf[1] = 0x03;
@ -318,16 +320,20 @@ void XBOXUSB::setLedRaw(uint8_t value) {
XboxCommand(writeBuf, 3); XboxCommand(writeBuf, 3);
} }
void XBOXUSB::setLedOn(LED led) { void XBOXUSB::setLedOn(LED led) {
if (led != ALL) // All LEDs can't be on a the same time if (led != ALL) // All LEDs can't be on a the same time
setLedRaw((pgm_read_byte(&XBOXLEDS[(uint8_t)led])) + 4); setLedRaw((pgm_read_byte(&XBOXLEDS[(uint8_t)led])) + 4);
} }
void XBOXUSB::setLedBlink(LED led) { void XBOXUSB::setLedBlink(LED led) {
setLedRaw(pgm_read_byte(&XBOXLEDS[(uint8_t)led])); setLedRaw(pgm_read_byte(&XBOXLEDS[(uint8_t)led]));
} }
void XBOXUSB::setLedMode(LEDMode ledMode) { // This function is used to do some speciel LED stuff the controller supports void XBOXUSB::setLedMode(LEDMode ledMode) { // This function is used to do some speciel LED stuff the controller supports
setLedRaw((uint8_t)ledMode); setLedRaw((uint8_t)ledMode);
} }
void XBOXUSB::setRumbleOn(uint8_t lValue, uint8_t rValue) { void XBOXUSB::setRumbleOn(uint8_t lValue, uint8_t rValue) {
writeBuf[0] = 0x00; writeBuf[0] = 0x00;
writeBuf[1] = 0x08; writeBuf[1] = 0x08;

View file

@ -83,16 +83,22 @@ public:
* @return 0 on success. * @return 0 on success.
*/ */
virtual uint8_t Poll(); virtual uint8_t Poll();
/** /**
* Get the device address. * Get the device address.
* @return The device address. * @return The device address.
*/ */
virtual uint8_t GetAddress() { return bAddress; }; virtual uint8_t GetAddress() {
return bAddress;
};
/** /**
* Used to check if the controller has been initialized. * Used to check if the controller has been initialized.
* @return True if it's ready. * @return True if it's ready.
*/ */
virtual bool isReady() { return bPollEnable; }; virtual bool isReady() {
return bPollEnable;
};
/**@}*/ /**@}*/
/** @name Xbox Controller functions */ /** @name Xbox Controller functions */
@ -120,9 +126,15 @@ public:
int16_t getAnalogHat(AnalogHat a); int16_t getAnalogHat(AnalogHat a);
/** Turn rumble off and all the LEDs on the controller. */ /** Turn rumble off and all the LEDs on the controller. */
void setAllOff() { setRumbleOn(0,0); setLedRaw(0); }; void setAllOff() {
setRumbleOn(0, 0);
setLedRaw(0);
};
/** Turn rumble off the controller. */ /** Turn rumble off the controller. */
void setRumbleOff() { setRumbleOn(0,0); }; void setRumbleOff() {
setRumbleOn(0, 0);
};
/** /**
* Turn rumble on. * Turn rumble on.
* @param lValue Left motor (big weight) inside the controller. * @param lValue Left motor (big weight) inside the controller.
@ -136,8 +148,11 @@ public:
* setLedBlink(LED l), and setLedMode(LEDMode lm). * setLedBlink(LED l), and setLedMode(LEDMode lm).
*/ */
void setLedRaw(uint8_t value); void setLedRaw(uint8_t value);
/** Turn all LEDs off the controller. */ /** Turn all LEDs off the controller. */
void setLedOff() { setLedRaw(0); }; void setLedOff() {
setLedRaw(0);
};
/** /**
* Turn on a LED by using the ::LED enum. * Turn on a LED by using the ::LED enum.
* @param l ::LED1, ::LED2, ::LED3 and ::LED4 is supported by the Xbox controller. * @param l ::LED1, ::LED2, ::LED3 and ::LED4 is supported by the Xbox controller.

View file

@ -41,8 +41,7 @@ pUsb(p), //pointer to USB class instance - mandatory
bAddress(0), //device address - mandatory bAddress(0), //device address - mandatory
bConfNum(0), //configuration number bConfNum(0), //configuration number
bNumEP(1), //if config descriptor needs to be parsed bNumEP(1), //if config descriptor needs to be parsed
ready(false) ready(false) {
{
// initialize endpoint data structures // initialize endpoint data structures
for (uint8_t i = 0; i < ADK_MAX_ENDPOINTS; i++) { for (uint8_t i = 0; i < ADK_MAX_ENDPOINTS; i++) {
epInfo[i].epAddr = 0; epInfo[i].epAddr = 0;

View file

@ -39,6 +39,7 @@ enum LED {
/** Used to blink all LEDs on the Xbox controller */ /** Used to blink all LEDs on the Xbox controller */
ALL = 4, ALL = 4,
}; };
/** This enum is used to read all the different buttons on the different controllers */ /** This enum is used to read all the different buttons on the different controllers */
enum Button { enum Button {
/**@{*/ /**@{*/
@ -101,6 +102,7 @@ enum Button {
SYNC = 17, SYNC = 17,
/**@}*/ /**@}*/
}; };
/** Joysticks on the PS3 and Xbox controllers. */ /** Joysticks on the PS3 and Xbox controllers. */
enum AnalogHat { enum AnalogHat {
/** Left joystick x-axis */ /** Left joystick x-axis */