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

35
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 */
@ -204,18 +210,19 @@ public:
/** Disconnects both the L2CAP Channel and the HCI Connection for all Bluetooth services. */ /** Disconnects both the L2CAP Channel and the HCI Connection for all Bluetooth services. */
void disconnect() { void disconnect() {
for (uint8_t i=0; i<BTD_NUMSERVICES; i++) for(uint8_t i = 0; i < BTD_NUMSERVICES; i++)
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.
* @return The serice ID on succes or -1 on fail. * @return The serice ID on succes or -1 on fail.
*/ */
int8_t registerServiceClass(BluetoothService *pService) { int8_t registerServiceClass(BluetoothService *pService) {
for (uint8_t i=0; i<BTD_NUMSERVICES; i++) { for(uint8_t i = 0; i < BTD_NUMSERVICES; i++) {
if (!btService[i]) { if(!btService[i]) {
btService[i] = pService; btService[i] = pService;
return i; // Return ID return i; // Return ID
} }
@ -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. */
@ -435,9 +448,9 @@ private:
uint16_t hci_event_flag; // hci flags of received bluetooth events uint16_t hci_event_flag; // hci flags of received bluetooth events
uint8_t inquiry_counter; uint8_t inquiry_counter;
uint8_t hcibuf[BULK_MAXPKTSIZE];//General purpose buffer for hci data uint8_t hcibuf[BULK_MAXPKTSIZE]; //General purpose buffer for hci data
uint8_t l2capinbuf[BULK_MAXPKTSIZE];//General purpose buffer for l2cap in data uint8_t l2capinbuf[BULK_MAXPKTSIZE]; //General purpose buffer for l2cap in data
uint8_t l2capoutbuf[BULK_MAXPKTSIZE];//General purpose buffer for l2cap out data uint8_t l2capoutbuf[BULK_MAXPKTSIZE]; //General purpose buffer for l2cap out data
/* State machines */ /* State machines */
void HCI_event_task(); // Poll the HCI event pipe void HCI_event_task(); // Poll the HCI event pipe

291
PS3BT.cpp
View file

@ -32,7 +32,7 @@ const uint8_t OUTPUT_REPORT_BUFFER[] PROGMEM = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
}; };
PS3BT::PS3BT(BTD *p, uint8_t btadr5, uint8_t btadr4, uint8_t btadr3, uint8_t btadr2, uint8_t btadr1, uint8_t btadr0): PS3BT::PS3BT(BTD *p, uint8_t btadr5, uint8_t btadr4, uint8_t btadr3, uint8_t btadr2, uint8_t btadr1, uint8_t btadr0) :
pBtd(p) // pointer to USB class instance - mandatory pBtd(p) // pointer to USB class instance - mandatory
{ {
if (pBtd) if (pBtd)
@ -45,49 +45,54 @@ pBtd(p) // pointer to USB class instance - mandatory
pBtd->my_bdaddr[1] = btadr1; pBtd->my_bdaddr[1] = btadr1;
pBtd->my_bdaddr[0] = btadr0; pBtd->my_bdaddr[0] = btadr0;
HIDBuffer[0] = 0x52;// HID BT Set_report (0x50) | Report Type (Output 0x02) HIDBuffer[0] = 0x52; // HID BT Set_report (0x50) | Report Type (Output 0x02)
HIDBuffer[1] = 0x01;// Report ID HIDBuffer[1] = 0x01; // Report ID
//Needed for PS3 Move Controller commands to work via bluetooth //Needed for PS3 Move Controller commands to work via bluetooth
HIDMoveBuffer[0] = 0xA2;// HID BT DATA_request (0xA0) | Report Type (Output 0x02) HIDMoveBuffer[0] = 0xA2; // HID BT DATA_request (0xA0) | Report Type (Output 0x02)
HIDMoveBuffer[1] = 0x02;// Report ID HIDMoveBuffer[1] = 0x02; // Report ID
/* Set device cid for the control and intterrupt channelse - LSB */ /* Set device cid for the control and intterrupt channelse - LSB */
control_dcid[0] = 0x40;//0x0040 control_dcid[0] = 0x40; //0x0040
control_dcid[1] = 0x00; control_dcid[1] = 0x00;
interrupt_dcid[0] = 0x41;//0x0041 interrupt_dcid[0] = 0x41; //0x0041
interrupt_dcid[1] = 0x00; interrupt_dcid[1] = 0x00;
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;
if(PS3Connected) { if (PS3Connected) {
if (a == aX || a == aY || a == aZ || a == gZ) if (a == aX || a == aY || a == aZ || a == gZ)
return ((l2capinbuf[(uint16_t)a] << 8) | l2capinbuf[(uint16_t)a + 1]); return ((l2capinbuf[(uint16_t)a] << 8) | l2capinbuf[(uint16_t)a + 1]);
else else
return 0; return 0;
} else if(PS3MoveConnected) { } else if (PS3MoveConnected) {
if (a == mXmove || a == mYmove) // These are all 12-bits long if (a == mXmove || a == mYmove) // These are all 12-bits long
return (((l2capinbuf[(uint16_t)a] & 0x0F) << 8) | (l2capinbuf[(uint16_t)a + 1])); return (((l2capinbuf[(uint16_t)a] & 0x0F) << 8) | (l2capinbuf[(uint16_t)a + 1]));
else if (a == mZmove || a == tempMove) // The tempearature is also 12 bits long else if (a == mZmove || a == tempMove) // The tempearature is also 12 bits long
@ -97,77 +102,81 @@ 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;
double accZval; double accZval;
if(PS3Connected) { if (PS3Connected) {
// Data for the Kionix KXPC4 used in the DualShock 3 // Data for the Kionix KXPC4 used in the DualShock 3
const double zeroG = 511.5; // 1.65/3.3*1023 (1,65V) const double zeroG = 511.5; // 1.65/3.3*1023 (1,65V)
accXval = -((double)getSensor(aX)-zeroG); accXval = -((double)getSensor(aX) - zeroG);
accYval = -((double)getSensor(aY)-zeroG); accYval = -((double)getSensor(aY) - zeroG);
accZval = -((double)getSensor(aZ)-zeroG); accZval = -((double)getSensor(aZ) - zeroG);
} else if(PS3MoveConnected) { } else if (PS3MoveConnected) {
// It's a Kionix KXSC4 inside the Motion controller // It's a Kionix KXSC4 inside the Motion controller
const uint16_t zeroG = 0x8000; const uint16_t zeroG = 0x8000;
accXval = -(int16_t)(getSensor(aXmove)-zeroG); accXval = -(int16_t)(getSensor(aXmove) - zeroG);
accYval = (int16_t)(getSensor(aYmove)-zeroG); accYval = (int16_t)(getSensor(aYmove) - zeroG);
accZval = (int16_t)(getSensor(aZmove)-zeroG); accZval = (int16_t)(getSensor(aZmove) - zeroG);
} }
// Convert to 360 degrees resolution // Convert to 360 degrees resolution
// atan2 outputs the value of -π to π (radians) // atan2 outputs the value of -π to π (radians)
// We are then converting it to 0 to 2π and then to degrees // We are then converting it to 0 to 2π and then to degrees
if (a == Pitch) { if (a == Pitch) {
double angle = (atan2(accYval,accZval)+PI)*RAD_TO_DEG; double angle = (atan2(accYval, accZval) + PI) * RAD_TO_DEG;
return angle; return angle;
} else { } else {
double angle = (atan2(accXval,accZval)+PI)*RAD_TO_DEG; double angle = (atan2(accXval, accZval) + PI) * RAD_TO_DEG;
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;
int16_t value = getSensor(a); int16_t value = getSensor(a);
if (a == mXmove || a == mYmove || a == mZmove) { if (a == mXmove || a == mYmove || a == mZmove) {
if (value > 2047) if (value > 2047)
value -= 0x1000; value -= 0x1000;
return (double)value/3.2; // unit: muT = 10^(-6) Tesla return (double)value / 3.2; // unit: muT = 10^(-6) Tesla
} else if (a == aXmove || a == aYmove || a == aZmove) { } else if (a == aXmove || a == aYmove || a == aZmove) {
if (value < 0) if (value < 0)
value += 0x8000; value += 0x8000;
else else
value -= 0x8000; value -= 0x8000;
return (double)value/442.0; // unit: m/(s^2) return (double)value / 442.0; // unit: m/(s^2)
} else if (a == gXmove || a == gYmove || a == gZmove) { } else if (a == gXmove || a == gYmove || a == gZmove) {
if (value < 0) if (value < 0)
value += 0x8000; value += 0x8000;
else else
value -= 0x8000; value -= 0x8000;
if (a == gXmove) if (a == gXmove)
return (double)value/11.6; // unit: deg/s return (double)value / 11.6; // unit: deg/s
else if (a == gYmove) else if (a == gYmove)
return (double)value/11.2; // unit: deg/s return (double)value / 11.2; // unit: deg/s
else // gZmove else // gZmove
return (double)value/9.6; // unit: deg/s return (double)value / 9.6; // unit: deg/s
} 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);
String output = String(input/100); String output = String(input / 100);
output += "."; output += ".";
if(input%100 < 10) if (input % 100 < 10)
output += "0"; output += "0";
output += String(input%100); output += String(input % 100);
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,55 +184,56 @@ 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];
strcpy(statusOutput,"ConnectionStatus: "); strcpy(statusOutput, "ConnectionStatus: ");
if (getStatus(Plugged)) strcat(statusOutput,"Plugged"); if (getStatus(Plugged)) strcat(statusOutput, "Plugged");
else if (getStatus(Unplugged)) strcat(statusOutput,"Unplugged"); else if (getStatus(Unplugged)) strcat(statusOutput, "Unplugged");
else strcat(statusOutput,"Error"); else strcat(statusOutput, "Error");
strcat(statusOutput," - PowerRating: "); strcat(statusOutput, " - PowerRating: ");
if (getStatus(Charging)) strcat(statusOutput,"Charging"); if (getStatus(Charging)) strcat(statusOutput, "Charging");
else if (getStatus(NotCharging)) strcat(statusOutput,"Not Charging"); else if (getStatus(NotCharging)) strcat(statusOutput, "Not Charging");
else if (getStatus(Shutdown)) strcat(statusOutput,"Shutdown"); else if (getStatus(Shutdown)) strcat(statusOutput, "Shutdown");
else if (getStatus(Dying)) strcat(statusOutput,"Dying"); else if (getStatus(Dying)) strcat(statusOutput, "Dying");
else if (getStatus(Low)) strcat(statusOutput,"Low"); else if (getStatus(Low)) strcat(statusOutput, "Low");
else if (getStatus(High)) strcat(statusOutput,"High"); else if (getStatus(High)) strcat(statusOutput, "High");
else if (getStatus(Full)) strcat(statusOutput,"Full"); else if (getStatus(Full)) strcat(statusOutput, "Full");
else strcat(statusOutput,"Error"); else strcat(statusOutput, "Error");
strcat(statusOutput," - WirelessStatus: "); strcat(statusOutput, " - WirelessStatus: ");
if (getStatus(CableRumble)) strcat(statusOutput,"Cable - Rumble is on"); if (getStatus(CableRumble)) strcat(statusOutput, "Cable - Rumble is on");
else if (getStatus(Cable)) strcat(statusOutput,"Cable - Rumble is off"); else if (getStatus(Cable)) strcat(statusOutput, "Cable - Rumble is off");
else if (getStatus(BluetoothRumble)) strcat(statusOutput,"Bluetooth - Rumble is on"); else if (getStatus(BluetoothRumble)) strcat(statusOutput, "Bluetooth - Rumble is on");
else if (getStatus(Bluetooth)) strcat(statusOutput,"Bluetooth - Rumble is off"); else if (getStatus(Bluetooth)) strcat(statusOutput, "Bluetooth - Rumble is off");
else strcat(statusOutput,"Error"); else strcat(statusOutput, "Error");
return statusOutput; return statusOutput;
} } else if (PS3MoveConnected) {
else if(PS3MoveConnected) {
char statusOutput[50]; char statusOutput[50];
strcpy(statusOutput,"PowerRating: "); strcpy(statusOutput, "PowerRating: ");
if (getStatus(MoveCharging)) strcat(statusOutput,"Charging"); if (getStatus(MoveCharging)) strcat(statusOutput, "Charging");
else if (getStatus(MoveNotCharging)) strcat(statusOutput,"Not Charging"); else if (getStatus(MoveNotCharging)) strcat(statusOutput, "Not Charging");
else if (getStatus(MoveShutdown)) strcat(statusOutput,"Shutdown"); else if (getStatus(MoveShutdown)) strcat(statusOutput, "Shutdown");
else if (getStatus(MoveDying)) strcat(statusOutput,"Dying"); else if (getStatus(MoveDying)) strcat(statusOutput, "Dying");
else if (getStatus(MoveLow)) strcat(statusOutput,"Low"); else if (getStatus(MoveLow)) strcat(statusOutput, "Low");
else if (getStatus(MoveHigh)) strcat(statusOutput,"High"); else if (getStatus(MoveHigh)) strcat(statusOutput, "High");
else if (getStatus(MoveFull)) strcat(statusOutput,"Full"); else if (getStatus(MoveFull)) strcat(statusOutput, "Full");
else strcat(statusOutput,"Error"); else strcat(statusOutput, "Error");
return statusOutput; return statusOutput;
} }
} }
void PS3BT::Reset() { void PS3BT::Reset() {
PS3Connected = false; PS3Connected = false;
PS3MoveConnected = false; PS3MoveConnected = false;
@ -239,23 +249,23 @@ void PS3BT::Reset() {
void PS3BT::disconnect() { // Use this void to disconnect any of the controllers void PS3BT::disconnect() { // Use this void to disconnect any of the controllers
//First the HID interrupt channel has to be disconencted, then the HID control channel and finally the HCI connection //First the HID interrupt channel has to be disconencted, then the HID control channel and finally the HCI connection
pBtd->l2cap_disconnection_request(hci_handle,0x0A, interrupt_scid, interrupt_dcid); pBtd->l2cap_disconnection_request(hci_handle, 0x0A, interrupt_scid, interrupt_dcid);
Reset(); Reset();
l2cap_state = L2CAP_INTERRUPT_DISCONNECT; l2cap_state = L2CAP_INTERRUPT_DISCONNECT;
} }
void PS3BT::ACLData(uint8_t* ACLData) { void PS3BT::ACLData(uint8_t* ACLData) {
if(!pBtd->l2capConnectionClaimed && !PS3Connected && !PS3MoveConnected && !PS3NavigationConnected && !activeConnection && !pBtd->connectToWii && !pBtd->incomingWii && !pBtd->pairWithWii) { if (!pBtd->l2capConnectionClaimed && !PS3Connected && !PS3MoveConnected && !PS3NavigationConnected && !activeConnection && !pBtd->connectToWii && !pBtd->incomingWii && !pBtd->pairWithWii) {
if (ACLData[8] == L2CAP_CMD_CONNECTION_REQUEST) { if (ACLData[8] == L2CAP_CMD_CONNECTION_REQUEST) {
if((ACLData[12] | (ACLData[13] << 8)) == HID_CTRL_PSM) { if ((ACLData[12] | (ACLData[13] << 8)) == HID_CTRL_PSM) {
pBtd->l2capConnectionClaimed = true; // Claim that the incoming connection belongs to this service pBtd->l2capConnectionClaimed = true; // Claim that the incoming connection belongs to this service
activeConnection = true; activeConnection = true;
hci_handle = pBtd->hci_handle; // Store the HCI Handle for the connection hci_handle = pBtd->hci_handle; // Store the HCI Handle for the connection
l2cap_state = L2CAP_WAIT; l2cap_state = L2CAP_WAIT;
for(uint8_t i = 0; i < 30; i++) for (uint8_t i = 0; i < 30; i++)
remote_name[i] = pBtd->remote_name[i]; // Store the remote name for the connection remote_name[i] = pBtd->remote_name[i]; // Store the remote name for the connection
#ifdef DEBUG #ifdef DEBUG
if(pBtd->hci_version < 3) { // Check the HCI Version of the Bluetooth dongle if (pBtd->hci_version < 3) { // Check the HCI Version of the Bluetooth dongle
Notify(PSTR("\r\nYour dongle may not support reading the analog buttons, sensors and status\r\nYour HCI Version is: "), 0x80); Notify(PSTR("\r\nYour dongle may not support reading the analog buttons, sensors and status\r\nYour HCI Version is: "), 0x80);
Serial.print(pBtd->hci_version); Serial.print(pBtd->hci_version);
Notify(PSTR("\r\nBut should be at least 3\r\nThis means that it doesn't support Bluetooth Version 2.0+EDR"), 0x80); Notify(PSTR("\r\nBut should be at least 3\r\nThis means that it doesn't support Bluetooth Version 2.0+EDR"), 0x80);
@ -265,100 +275,90 @@ void PS3BT::ACLData(uint8_t* ACLData) {
} }
} }
if (((ACLData[0] | (ACLData[1] << 8)) == (hci_handle | 0x2000))) { //acl_handle_ok if (((ACLData[0] | (ACLData[1] << 8)) == (hci_handle | 0x2000))) { //acl_handle_ok
for(uint8_t i = 0; i < BULK_MAXPKTSIZE; i++) for (uint8_t i = 0; i < BULK_MAXPKTSIZE; i++)
l2capinbuf[i] = ACLData[i]; l2capinbuf[i] = ACLData[i];
if ((l2capinbuf[6] | (l2capinbuf[7] << 8)) == 0x0001) { //l2cap_control - Channel ID for ACL-U if ((l2capinbuf[6] | (l2capinbuf[7] << 8)) == 0x0001) { //l2cap_control - Channel ID for ACL-U
if (l2capinbuf[8] == L2CAP_CMD_COMMAND_REJECT) { if (l2capinbuf[8] == L2CAP_CMD_COMMAND_REJECT) {
#ifdef DEBUG #ifdef DEBUG
Notify(PSTR("\r\nL2CAP Command Rejected - Reason: "), 0x80); Notify(PSTR("\r\nL2CAP Command Rejected - Reason: "), 0x80);
PrintHex<uint8_t>(l2capinbuf[13], 0x80); PrintHex<uint8_t > (l2capinbuf[13], 0x80);
Serial.print(" "); Serial.print(" ");
PrintHex<uint8_t>(l2capinbuf[12], 0x80); PrintHex<uint8_t > (l2capinbuf[12], 0x80);
Serial.print(" Data: "); Serial.print(" Data: ");
PrintHex<uint8_t>(l2capinbuf[17], 0x80); PrintHex<uint8_t > (l2capinbuf[17], 0x80);
Serial.print(" "); Serial.print(" ");
PrintHex<uint8_t>(l2capinbuf[16], 0x80); PrintHex<uint8_t > (l2capinbuf[16], 0x80);
Serial.print(" "); Serial.print(" ");
PrintHex<uint8_t>(l2capinbuf[15], 0x80); PrintHex<uint8_t > (l2capinbuf[15], 0x80);
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);
Notify(PSTR(" "), 0x80); Notify(PSTR(" "), 0x80);
PrintHex<uint8_t>(l2capinbuf[12], 0x80); PrintHex<uint8_t > (l2capinbuf[12], 0x80);
Notify(PSTR(" SCID: "), 0x80); Notify(PSTR(" SCID: "), 0x80);
PrintHex<uint8_t>(l2capinbuf[15], 0x80); PrintHex<uint8_t > (l2capinbuf[15], 0x80);
Notify(PSTR(" "), 0x80); Notify(PSTR(" "), 0x80);
PrintHex<uint8_t>(l2capinbuf[14], 0x80); PrintHex<uint8_t > (l2capinbuf[14], 0x80);
Notify(PSTR(" Identifier: "), 0x80); Notify(PSTR(" Identifier: "), 0x80);
PrintHex<uint8_t>(l2capinbuf[9], 0x80); PrintHex<uint8_t > (l2capinbuf[9], 0x80);
#endif #endif
if ((l2capinbuf[12] | (l2capinbuf[13] << 8)) == HID_CTRL_PSM) { if ((l2capinbuf[12] | (l2capinbuf[13] << 8)) == HID_CTRL_PSM) {
identifier = l2capinbuf[9]; identifier = l2capinbuf[9];
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);
#endif #endif
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
identifier = l2capinbuf[9]; identifier = l2capinbuf[9];
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;
@ -367,30 +367,30 @@ void PS3BT::ACLData(uint8_t* ACLData) {
#ifdef EXTRADEBUG #ifdef EXTRADEBUG
else { else {
Notify(PSTR("\r\nL2CAP Unknown Signaling Command: "), 0x80); Notify(PSTR("\r\nL2CAP Unknown Signaling Command: "), 0x80);
PrintHex<uint8_t>(l2capinbuf[8], 0x80); PrintHex<uint8_t > (l2capinbuf[8], 0x80);
} }
#endif #endif
} else if (l2capinbuf[6] == interrupt_dcid[0] && l2capinbuf[7] == interrupt_dcid[1]) { // l2cap_interrupt } else if (l2capinbuf[6] == interrupt_dcid[0] && l2capinbuf[7] == interrupt_dcid[1]) { // l2cap_interrupt
//Serial.print("\r\nL2CAP Interrupt"); //Serial.print("\r\nL2CAP Interrupt");
if(PS3Connected || PS3MoveConnected || PS3NavigationConnected) { if (PS3Connected || PS3MoveConnected || PS3NavigationConnected) {
/* Read Report */ /* Read Report */
if(l2capinbuf[8] == 0xA1) { // HID_THDR_DATA_INPUT if (l2capinbuf[8] == 0xA1) { // HID_THDR_DATA_INPUT
if(PS3Connected || PS3NavigationConnected) if (PS3Connected || PS3NavigationConnected)
ButtonState = (uint32_t)(l2capinbuf[11] | ((uint16_t)l2capinbuf[12] << 8) | ((uint32_t)l2capinbuf[13] << 16)); ButtonState = (uint32_t)(l2capinbuf[11] | ((uint16_t)l2capinbuf[12] << 8) | ((uint32_t)l2capinbuf[13] << 16));
else if(PS3MoveConnected) else if (PS3MoveConnected)
ButtonState = (uint32_t)(l2capinbuf[10] | ((uint16_t)l2capinbuf[11] << 8) | ((uint32_t)l2capinbuf[12] << 16)); ButtonState = (uint32_t)(l2capinbuf[10] | ((uint16_t)l2capinbuf[11] << 8) | ((uint32_t)l2capinbuf[12] << 16));
//Notify(PSTR("\r\nButtonState", 0x80); //Notify(PSTR("\r\nButtonState", 0x80);
//PrintHex<uint32_t>(ButtonState, 0x80); //PrintHex<uint32_t>(ButtonState, 0x80);
if(ButtonState != OldButtonState) { if (ButtonState != OldButtonState) {
ButtonClickState = ButtonState & ~OldButtonState; // Update click state variable ButtonClickState = ButtonState & ~OldButtonState; // Update click state variable
OldButtonState = ButtonState; OldButtonState = ButtonState;
} }
#ifdef PRINTREPORT // Uncomment "#define PRINTREPORT" to print the report send by the PS3 Controllers #ifdef PRINTREPORT // Uncomment "#define PRINTREPORT" to print the report send by the PS3 Controllers
for(uint8_t i = 10; i < 58;i++) { for (uint8_t i = 10; i < 58; i++) {
PrintHex<uint8_t>(l2capinbuf[i], 0x80); PrintHex<uint8_t > (l2capinbuf[i], 0x80);
Serial.print(" "); Serial.print(" ");
} }
Serial.println(); Serial.println();
@ -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:
@ -408,12 +409,12 @@ void PS3BT::L2CAP_task() {
#ifdef DEBUG #ifdef DEBUG
Notify(PSTR("\r\nHID Control Incoming Connection Request"), 0x80); Notify(PSTR("\r\nHID Control Incoming Connection Request"), 0x80);
#endif #endif
pBtd->l2cap_connection_response(hci_handle,identifier, control_dcid, control_scid, PENDING); pBtd->l2cap_connection_response(hci_handle, identifier, control_dcid, control_scid, PENDING);
delay(1); delay(1);
pBtd->l2cap_connection_response(hci_handle,identifier, control_dcid, control_scid, SUCCESSFUL); pBtd->l2cap_connection_response(hci_handle, identifier, control_dcid, control_scid, SUCCESSFUL);
identifier++; identifier++;
delay(1); delay(1);
pBtd->l2cap_config_request(hci_handle,identifier, control_scid); pBtd->l2cap_config_request(hci_handle, identifier, control_scid);
l2cap_state = L2CAP_CONTROL_REQUEST; l2cap_state = L2CAP_CONTROL_REQUEST;
} }
break; break;
@ -422,7 +423,7 @@ void PS3BT::L2CAP_task() {
#ifdef DEBUG #ifdef DEBUG
Notify(PSTR("\r\nHID Control Configuration Request"), 0x80); Notify(PSTR("\r\nHID Control Configuration Request"), 0x80);
#endif #endif
pBtd->l2cap_config_response(hci_handle,identifier, control_scid); pBtd->l2cap_config_response(hci_handle, identifier, control_scid);
l2cap_state = L2CAP_CONTROL_SUCCESS; l2cap_state = L2CAP_CONTROL_SUCCESS;
} }
break; break;
@ -440,12 +441,12 @@ void PS3BT::L2CAP_task() {
#ifdef DEBUG #ifdef DEBUG
Notify(PSTR("\r\nHID Interrupt Incoming Connection Request"), 0x80); Notify(PSTR("\r\nHID Interrupt Incoming Connection Request"), 0x80);
#endif #endif
pBtd->l2cap_connection_response(hci_handle,identifier, interrupt_dcid, interrupt_scid, PENDING); pBtd->l2cap_connection_response(hci_handle, identifier, interrupt_dcid, interrupt_scid, PENDING);
delay(1); delay(1);
pBtd->l2cap_connection_response(hci_handle,identifier, interrupt_dcid, interrupt_scid, SUCCESSFUL); pBtd->l2cap_connection_response(hci_handle, identifier, interrupt_dcid, interrupt_scid, SUCCESSFUL);
identifier++; identifier++;
delay(1); delay(1);
pBtd->l2cap_config_request(hci_handle,identifier, interrupt_scid); pBtd->l2cap_config_request(hci_handle, identifier, interrupt_scid);
l2cap_state = L2CAP_INTERRUPT_REQUEST; l2cap_state = L2CAP_INTERRUPT_REQUEST;
} }
@ -455,7 +456,7 @@ void PS3BT::L2CAP_task() {
#ifdef DEBUG #ifdef DEBUG
Notify(PSTR("\r\nHID Interrupt Configuration Request"), 0x80); Notify(PSTR("\r\nHID Interrupt Configuration Request"), 0x80);
#endif #endif
pBtd->l2cap_config_response(hci_handle,identifier, interrupt_scid); pBtd->l2cap_config_response(hci_handle, identifier, interrupt_scid);
l2cap_state = L2CAP_INTERRUPT_SUCCESS; l2cap_state = L2CAP_INTERRUPT_SUCCESS;
} }
break; break;
@ -464,7 +465,7 @@ void PS3BT::L2CAP_task() {
#ifdef DEBUG #ifdef DEBUG
Notify(PSTR("\r\nHID Interrupt Successfully Configured"), 0x80); Notify(PSTR("\r\nHID Interrupt Successfully Configured"), 0x80);
#endif #endif
if(remote_name[0] == 'M') { // First letter in Motion Controller ('M') if (remote_name[0] == 'M') { // First letter in Motion Controller ('M')
for (uint8_t i = 0; i < BULK_MAXPKTSIZE; i++) // Reset l2cap in buffer as it sometimes read it as a button has been pressed for (uint8_t i = 0; i < BULK_MAXPKTSIZE; i++) // Reset l2cap in buffer as it sometimes read it as a button has been pressed
l2capinbuf[i] = 0; l2capinbuf[i] = 0;
ButtonState = 0; ButtonState = 0;
@ -503,10 +504,11 @@ 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:
if(millis() - timer > 1000) { // loop 1 second before sending the command if (millis() - timer > 1000) { // loop 1 second before sending the command
for (uint8_t i = 0; i < BULK_MAXPKTSIZE; i++) // Reset l2cap in buffer as it sometimes read it as a button has been pressed for (uint8_t i = 0; i < BULK_MAXPKTSIZE; i++) // Reset l2cap in buffer as it sometimes read it as a button has been pressed
l2capinbuf[i] = 0; l2capinbuf[i] = 0;
ButtonState = 0; ButtonState = 0;
@ -521,7 +523,7 @@ void PS3BT::Run() {
break; break;
case L2CAP_HID_PS3_LED: case L2CAP_HID_PS3_LED:
if(millis() - timer > 1000) { // loop 1 second before sending the command if (millis() - timer > 1000) { // loop 1 second before sending the command
if (remote_name[0] == 'P') { // First letter in PLAYSTATION(R)3 Controller ('P') if (remote_name[0] == 'P') { // First letter in PLAYSTATION(R)3 Controller ('P')
setLedOn(LED1); setLedOn(LED1);
#ifdef DEBUG #ifdef DEBUG
@ -534,7 +536,7 @@ void PS3BT::Run() {
Notify(PSTR("\r\nNavigation Controller Enabled\r\n"), 0x80); Notify(PSTR("\r\nNavigation Controller Enabled\r\n"), 0x80);
#endif #endif
PS3NavigationConnected = true; PS3NavigationConnected = true;
} else if(remote_name[0] == 'M') { // First letter in Motion Controller ('M') } else if (remote_name[0] == 'M') { // First letter in Motion Controller ('M')
moveSetBulb(Red); moveSetBulb(Red);
timerBulbRumble = millis(); timerBulbRumble = millis();
#ifdef DEBUG #ifdef DEBUG
@ -549,7 +551,7 @@ void PS3BT::Run() {
case L2CAP_DONE: case L2CAP_DONE:
if (PS3MoveConnected) { //The Bulb and rumble values, has to be send at aproximatly every 5th second for it to stay on if (PS3MoveConnected) { //The Bulb and rumble values, has to be send at aproximatly every 5th second for it to stay on
if (millis() - timerBulbRumble > 4000) { //Send at least every 4th second if (millis() - timerBulbRumble > 4000) { //Send at least every 4th second
HIDMove_Command(HIDMoveBuffer, HID_BUFFERSIZE);//The Bulb and rumble values, has to be written again and again, for it to stay turned on HIDMove_Command(HIDMoveBuffer, HID_BUFFERSIZE); //The Bulb and rumble values, has to be written again and again, for it to stay turned on
timerBulbRumble = millis(); timerBulbRumble = millis();
} }
} }
@ -562,26 +564,30 @@ 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
HIDBuffer[5] = 0x00; HIDBuffer[5] = 0x00;
HIDBuffer[6] = 0x00;//high mode off HIDBuffer[6] = 0x00; //high mode off
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
@ -593,33 +599,36 @@ void PS3BT::setRumbleOn(Rumble mode) {
HIDBuffer[3] = 0xfe; HIDBuffer[3] = 0xfe;
HIDBuffer[5] = 0xfe; HIDBuffer[5] = 0xfe;
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)
cmd_buf[1] = 0xF4;// Report ID cmd_buf[1] = 0xF4; // Report ID
cmd_buf[2] = 0x42;// Special PS3 Controller enable commands cmd_buf[2] = 0x42; // Special PS3 Controller enable commands
cmd_buf[3] = 0x03; cmd_buf[3] = 0x03;
cmd_buf[4] = 0x00; cmd_buf[4] = 0x00;
cmd_buf[5] = 0x00; cmd_buf[5] = 0x00;
@ -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,12 +653,14 @@ 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)
Notify(PSTR("\r\nThe rumble value has to at least 64, or approximately 25%"), 0x80); Notify(PSTR("\r\nThe rumble value has to at least 64, or approximately 25%"), 0x80);
#endif #endif
//set the rumble value into the write buffer //set the rumble value into the write buffer

View file

@ -72,7 +72,7 @@ public:
* Pass your dongles Bluetooth address into the constructor, * Pass your dongles Bluetooth address into the constructor,
* This will set BTD#my_bdaddr, so you don't have to plug in the dongle before pairing with your controller. * This will set BTD#my_bdaddr, so you don't have to plug in the dongle before pairing with your controller.
*/ */
PS3BT(BTD *pBtd, uint8_t btadr5=0, uint8_t btadr4=0, uint8_t btadr3=0, uint8_t btadr2=0, uint8_t btadr1=0, uint8_t btadr0=0); PS3BT(BTD *pBtd, uint8_t btadr5 = 0, uint8_t btadr4 = 0, uint8_t btadr3 = 0, uint8_t btadr2 = 0, uint8_t btadr1 = 0, uint8_t btadr0 = 0);
/** @name BluetoothService implementation */ /** @name BluetoothService implementation */
/** /**
@ -225,7 +225,7 @@ private:
uint32_t ButtonClickState; uint32_t ButtonClickState;
uint32_t timerHID; // Timer used see if there has to be a delay before a new HID command uint32_t timerHID; // Timer used see if there has to be a delay before a new HID command
uint32_t timerBulbRumble;// used to continuously set PS3 Move controller Bulb and rumble values uint32_t timerBulbRumble; // used to continuously set PS3 Move controller Bulb and rumble values
uint8_t l2capinbuf[BULK_MAXPKTSIZE]; // General purpose buffer for L2CAP in data uint8_t l2capinbuf[BULK_MAXPKTSIZE]; // General purpose buffer for L2CAP in data
uint8_t HIDBuffer[HID_BUFFERSIZE]; // Used to store HID commands uint8_t HIDBuffer[HID_BUFFERSIZE]; // Used to store HID commands

View file

@ -76,7 +76,7 @@ const uint8_t ANALOGBUTTONS[] PROGMEM = {
24, // RIGHT_ANALOG 24, // RIGHT_ANALOG
25, // DOWN_ANALOG 25, // DOWN_ANALOG
26, // LEFT_ANALOG 26, // LEFT_ANALOG
0,0,0,0, // Skip SELECT, L3, R3 and START 0, 0, 0, 0, // Skip SELECT, L3, R3 and START
27, // L2_ANALOG 27, // L2_ANALOG
28, // R2_ANALOG 28, // R2_ANALOG
@ -86,7 +86,7 @@ const uint8_t ANALOGBUTTONS[] PROGMEM = {
32, // CIRCLE_ANALOG 32, // CIRCLE_ANALOG
33, // CROSS_ANALOG 33, // CROSS_ANALOG
34, // SQUARE_ANALOG 34, // SQUARE_ANALOG
0,0, // Skip PS and MOVE 0, 0, // Skip PS and MOVE
// Playstation Move Controller // Playstation Move Controller
15 // T_ANALOG - Both at byte 14 (last reading) and byte 15 (current reading) 15 // T_ANALOG - Both at byte 14 (last reading) and byte 15 (current reading)
@ -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
@ -180,11 +182,12 @@ enum Status {
MoveHigh = (21 << 8) | 0x04, MoveHigh = (21 << 8) | 0x04,
MoveFull = (21 << 8) | 0x05, MoveFull = (21 << 8) | 0x05,
CableRumble = (40 << 8) | 0x10,//Opperating by USB and rumble is turned on CableRumble = (40 << 8) | 0x10, //Opperating by USB and rumble is turned on
Cable = (40 << 8) | 0x12,//Opperating by USB and rumble is turned off Cable = (40 << 8) | 0x12, //Opperating by USB and rumble is turned off
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

@ -38,12 +38,12 @@ const uint8_t MOVE_REPORT_BUFFER[] PROGMEM = {
0x00 // Rumble 0x00 // Rumble
}; };
PS3USB::PS3USB(USB *p, uint8_t btadr5, uint8_t btadr4, uint8_t btadr3, uint8_t btadr2, uint8_t btadr1, uint8_t btadr0): PS3USB::PS3USB(USB *p, uint8_t btadr5, uint8_t btadr4, uint8_t btadr3, uint8_t btadr2, uint8_t btadr1, uint8_t btadr0) :
pUsb(p), // pointer to USB class instance - mandatory pUsb(p), // pointer to USB class instance - mandatory
bAddress(0), // device address - mandatory bAddress(0), // device address - mandatory
bPollEnable(false) // don't start polling before dongle is connected bPollEnable(false) // don't start polling before dongle is connected
{ {
for(uint8_t i=0; i<PS3_MAX_ENDPOINTS; i++) { for (uint8_t i = 0; i < PS3_MAX_ENDPOINTS; i++) {
epInfo[i].epAddr = 0; epInfo[i].epAddr = 0;
epInfo[i].maxPktSize = (i) ? 0 : 8; epInfo[i].maxPktSize = (i) ? 0 : 8;
epInfo[i].epAttribs = 0; epInfo[i].epAttribs = 0;
@ -62,7 +62,7 @@ bPollEnable(false) // don't start polling before dongle is connected
} }
uint8_t PS3USB::Init(uint8_t parent, uint8_t port, bool lowspeed) { uint8_t PS3USB::Init(uint8_t parent, uint8_t port, bool lowspeed) {
uint8_t buf[sizeof(USB_DEVICE_DESCRIPTOR)]; uint8_t buf[sizeof (USB_DEVICE_DESCRIPTOR)];
uint8_t rcode; uint8_t rcode;
UsbDevice *p = NULL; UsbDevice *p = NULL;
EpInfo *oldep_ptr = NULL; EpInfo *oldep_ptr = NULL;
@ -108,17 +108,17 @@ uint8_t PS3USB::Init(uint8_t parent, uint8_t port, bool lowspeed) {
p->lowspeed = lowspeed; p->lowspeed = lowspeed;
// Get device descriptor // Get device descriptor
rcode = pUsb->getDevDescr(0, 0, sizeof(USB_DEVICE_DESCRIPTOR), (uint8_t*)buf);// Get device descriptor - addr, ep, nbytes, data rcode = pUsb->getDevDescr(0, 0, sizeof (USB_DEVICE_DESCRIPTOR), (uint8_t*)buf); // Get device descriptor - addr, ep, nbytes, data
// Restore p->epinfo // Restore p->epinfo
p->epinfo = oldep_ptr; p->epinfo = oldep_ptr;
if(rcode) if (rcode)
goto FailGetDevDescr; goto FailGetDevDescr;
VID = ((USB_DEVICE_DESCRIPTOR*)buf)->idVendor; VID = ((USB_DEVICE_DESCRIPTOR*)buf)->idVendor;
PID = ((USB_DEVICE_DESCRIPTOR*)buf)->idProduct; PID = ((USB_DEVICE_DESCRIPTOR*)buf)->idProduct;
if(VID != PS3_VID || (PID != PS3_PID && PID != PS3NAVIGATION_PID && PID != PS3MOVE_PID)) if (VID != PS3_VID || (PID != PS3_PID && PID != PS3NAVIGATION_PID && PID != PS3MOVE_PID))
goto FailUnknownDevice; goto FailUnknownDevice;
// Allocate new address according to device class // Allocate new address according to device class
@ -131,7 +131,7 @@ uint8_t PS3USB::Init(uint8_t parent, uint8_t port, bool lowspeed) {
epInfo[0].maxPktSize = (uint8_t)((USB_DEVICE_DESCRIPTOR*)buf)->bMaxPacketSize0; epInfo[0].maxPktSize = (uint8_t)((USB_DEVICE_DESCRIPTOR*)buf)->bMaxPacketSize0;
// Assign new address to the device // Assign new address to the device
rcode = pUsb->setAddr( 0, 0, bAddress ); rcode = pUsb->setAddr(0, 0, bAddress);
if (rcode) { if (rcode) {
p->lowspeed = false; p->lowspeed = false;
addrPool.FreeAddress(bAddress); addrPool.FreeAddress(bAddress);
@ -139,12 +139,12 @@ uint8_t PS3USB::Init(uint8_t parent, uint8_t port, bool lowspeed) {
#ifdef DEBUG #ifdef DEBUG
Notify(PSTR("\r\nsetAddr: "), 0x80); Notify(PSTR("\r\nsetAddr: "), 0x80);
#endif #endif
PrintHex<uint8_t>(rcode, 0x80); PrintHex<uint8_t > (rcode, 0x80);
return rcode; return rcode;
} }
#ifdef EXTRADEBUG #ifdef EXTRADEBUG
Notify(PSTR("\r\nAddr: "), 0x80); Notify(PSTR("\r\nAddr: "), 0x80);
PrintHex<uint8_t>(bAddress, 0x80); PrintHex<uint8_t > (bAddress, 0x80);
#endif #endif
p->lowspeed = false; p->lowspeed = false;
@ -180,17 +180,17 @@ uint8_t PS3USB::Init(uint8_t parent, uint8_t port, bool lowspeed) {
epInfo[ PS3_INPUT_PIPE ].bmRcvToggle = bmRCVTOG0; epInfo[ PS3_INPUT_PIPE ].bmRcvToggle = bmRCVTOG0;
rcode = pUsb->setEpInfoEntry(bAddress, 3, epInfo); rcode = pUsb->setEpInfoEntry(bAddress, 3, epInfo);
if( rcode ) if (rcode)
goto FailSetDevTblEntry; goto FailSetDevTblEntry;
delay(200);//Give time for address change delay(200); //Give time for address change
rcode = pUsb->setConf(bAddress, epInfo[ PS3_CONTROL_PIPE ].epAddr, 1); rcode = pUsb->setConf(bAddress, epInfo[ PS3_CONTROL_PIPE ].epAddr, 1);
if( rcode ) if (rcode)
goto FailSetConf; goto FailSetConf;
if(PID == PS3_PID || PID == PS3NAVIGATION_PID) { if (PID == PS3_PID || PID == PS3NAVIGATION_PID) {
if(PID == PS3_PID) { if (PID == PS3_PID) {
#ifdef DEBUG #ifdef DEBUG
Notify(PSTR("\r\nDualshock 3 Controller Connected"), 0x80); Notify(PSTR("\r\nDualshock 3 Controller Connected"), 0x80);
#endif #endif
@ -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
@ -250,16 +249,16 @@ FailSetConf:
FailUnknownDevice: FailUnknownDevice:
#ifdef DEBUG #ifdef DEBUG
Notify(PSTR("\r\nUnknown Device Connected - VID: "), 0x80); Notify(PSTR("\r\nUnknown Device Connected - VID: "), 0x80);
PrintHex<uint16_t>(VID, 0x80); PrintHex<uint16_t > (VID, 0x80);
Notify(PSTR(" PID: "), 0x80); Notify(PSTR(" PID: "), 0x80);
PrintHex<uint16_t>(PID, 0x80); PrintHex<uint16_t > (PID, 0x80);
#endif #endif
rcode = USB_DEV_CONFIG_ERROR_DEVICE_NOT_SUPPORTED; rcode = USB_DEV_CONFIG_ERROR_DEVICE_NOT_SUPPORTED;
goto Fail; goto Fail;
Fail: Fail:
#ifdef DEBUG #ifdef DEBUG
Notify(PSTR("\r\nPS3 Init Failed, error code: "), 0x80); Notify(PSTR("\r\nPS3 Init Failed, error code: "), 0x80);
Serial.print(rcode,HEX); Serial.print(rcode, HEX);
#endif #endif
Release(); Release();
return rcode; return rcode;
@ -275,21 +274,21 @@ 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;
if(PS3Connected || PS3NavigationConnected) { if (PS3Connected || PS3NavigationConnected) {
uint16_t BUFFER_SIZE = EP_MAXPKTSIZE; uint16_t BUFFER_SIZE = EP_MAXPKTSIZE;
pUsb->inTransfer(bAddress, epInfo[ PS3_INPUT_PIPE ].epAddr, &BUFFER_SIZE, readBuf); // input on endpoint 1 pUsb->inTransfer(bAddress, epInfo[ PS3_INPUT_PIPE ].epAddr, &BUFFER_SIZE, readBuf); // input on endpoint 1
if(millis() - timer > 100) { // Loop 100ms before processing data if (millis() - timer > 100) { // Loop 100ms before processing data
readReport(); readReport();
#ifdef PRINTREPORT #ifdef PRINTREPORT
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
@ -308,7 +307,7 @@ void PS3USB::readReport() {
//Notify(PSTR("\r\nButtonState", 0x80); //Notify(PSTR("\r\nButtonState", 0x80);
//PrintHex<uint32_t>(ButtonState, 0x80); //PrintHex<uint32_t>(ButtonState, 0x80);
if(ButtonState != OldButtonState) { if (ButtonState != OldButtonState) {
ButtonClickState = ButtonState & ~OldButtonState; // Update click state variable ButtonClickState = ButtonState & ~OldButtonState; // Update click state variable
OldButtonState = ButtonState; OldButtonState = ButtonState;
} }
@ -318,8 +317,8 @@ void PS3USB::printReport() { //Uncomment "#define PRINTREPORT" to print the repo
#ifdef PRINTREPORT #ifdef PRINTREPORT
if (readBuf == NULL) if (readBuf == NULL)
return; return;
for(uint8_t i = 0; i < PS3_REPORT_BUFFER_SIZE;i++) { for (uint8_t i = 0; i < PS3_REPORT_BUFFER_SIZE; i++) {
PrintHex<uint8_t>(readBuf[i], 0x80); PrintHex<uint8_t > (readBuf[i], 0x80);
Serial.print(" "); Serial.print(" ");
} }
Serial.println(); Serial.println();
@ -329,88 +328,95 @@ 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;
double accYval; double accYval;
double accZval; double accZval;
// Data for the Kionix KXPC4 used in the DualShock 3 // Data for the Kionix KXPC4 used in the DualShock 3
const double zeroG = 511.5; // 1.65/3.3*1023 (1,65V) const double zeroG = 511.5; // 1.65/3.3*1023 (1,65V)
accXval = -((double)getSensor(aX)-zeroG); accXval = -((double)getSensor(aX) - zeroG);
accYval = -((double)getSensor(aY)-zeroG); accYval = -((double)getSensor(aY) - zeroG);
accZval = -((double)getSensor(aZ)-zeroG); accZval = -((double)getSensor(aZ) - zeroG);
// Convert to 360 degrees resolution // Convert to 360 degrees resolution
// atan2 outputs the value of -π to π (radians) // atan2 outputs the value of -π to π (radians)
// We are then converting it to 0 to 2π and then to degrees // We are then converting it to 0 to 2π and then to degrees
if (a == Pitch) { if (a == Pitch) {
double angle = (atan2(accYval,accZval)+PI)*RAD_TO_DEG; double angle = (atan2(accYval, accZval) + PI) * RAD_TO_DEG;
return angle; return angle;
} else { } else {
double angle = (atan2(accXval,accZval)+PI)*RAD_TO_DEG; double angle = (atan2(accXval, accZval) + PI) * RAD_TO_DEG;
return angle; return angle;
} }
} 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;
if (readBuf[((uint16_t)c >> 8)-9] == ((uint8_t)c & 0xff)) if (readBuf[((uint16_t)c >> 8) - 9] == ((uint8_t)c & 0xff))
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];
strcpy(statusOutput,"ConnectionStatus: "); strcpy(statusOutput, "ConnectionStatus: ");
if (getStatus(Plugged)) strcat(statusOutput,"Plugged"); if (getStatus(Plugged)) strcat(statusOutput, "Plugged");
else if (getStatus(Unplugged)) strcat(statusOutput,"Unplugged"); else if (getStatus(Unplugged)) strcat(statusOutput, "Unplugged");
else strcat(statusOutput,"Error"); else strcat(statusOutput, "Error");
strcat(statusOutput," - PowerRating: "); strcat(statusOutput, " - PowerRating: ");
if (getStatus(Charging)) strcat(statusOutput,"Charging"); if (getStatus(Charging)) strcat(statusOutput, "Charging");
else if (getStatus(NotCharging)) strcat(statusOutput,"Not Charging"); else if (getStatus(NotCharging)) strcat(statusOutput, "Not Charging");
else if (getStatus(Shutdown)) strcat(statusOutput,"Shutdown"); else if (getStatus(Shutdown)) strcat(statusOutput, "Shutdown");
else if (getStatus(Dying)) strcat(statusOutput,"Dying"); else if (getStatus(Dying)) strcat(statusOutput, "Dying");
else if (getStatus(Low)) strcat(statusOutput,"Low"); else if (getStatus(Low)) strcat(statusOutput, "Low");
else if (getStatus(High)) strcat(statusOutput,"High"); else if (getStatus(High)) strcat(statusOutput, "High");
else if (getStatus(Full)) strcat(statusOutput,"Full"); else if (getStatus(Full)) strcat(statusOutput, "Full");
else strcat(statusOutput,"Error"); else strcat(statusOutput, "Error");
strcat(statusOutput," - WirelessStatus: "); strcat(statusOutput, " - WirelessStatus: ");
if (getStatus(CableRumble)) strcat(statusOutput,"Cable - Rumble is on"); if (getStatus(CableRumble)) strcat(statusOutput, "Cable - Rumble is on");
else if (getStatus(Cable)) strcat(statusOutput,"Cable - Rumble is off"); else if (getStatus(Cable)) strcat(statusOutput, "Cable - Rumble is off");
else if (getStatus(BluetoothRumble)) strcat(statusOutput,"Bluetooth - Rumble is on"); else if (getStatus(BluetoothRumble)) strcat(statusOutput, "Bluetooth - Rumble is on");
else if (getStatus(Bluetooth)) strcat(statusOutput,"Bluetooth - Rumble is off"); else if (getStatus(Bluetooth)) strcat(statusOutput, "Bluetooth - Rumble is off");
else strcat(statusOutput,"Error"); else strcat(statusOutput, "Error");
return statusOutput; return statusOutput;
} }
@ -419,22 +425,25 @@ String PS3USB::getStatusString() {
/* Playstation Sixaxis Dualshock and Navigation Controller commands */ /* Playstation Sixaxis Dualshock and Navigation Controller commands */
void PS3USB::PS3_Command(uint8_t* data, uint16_t nbytes) { 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
writeBuf[3] = 0x00; writeBuf[3] = 0x00;
writeBuf[4] = 0x00;//high mode off writeBuf[4] = 0x00; //high mode off
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
@ -446,57 +455,61 @@ void PS3USB::setRumbleOn(Rumble mode) {
writeBuf[1] = 0xfe; writeBuf[1] = 0xfe;
writeBuf[3] = 0xfe; writeBuf[3] = 0xfe;
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];
buf[0] = 0x01; buf[0] = 0x01;
buf[1] = 0x00; buf[1] = 0x00;
for (uint8_t i = 0; i < 6; i++) for (uint8_t i = 0; i < 6; i++)
buf[i+2] = BDADDR[5 - i];//Copy into buffer, has to be written reversed buf[i + 2] = BDADDR[5 - i]; //Copy into buffer, has to be written reversed
//bmRequest = Host to device (0x00) | Class (0x20) | Interface (0x01) = 0x21, bRequest = Set Report (0x09), Report ID (0xF5), Report Type (Feature 0x03), interface (0x00), datalength, datalength, data) //bmRequest = Host to device (0x00) | Class (0x20) | Interface (0x01) = 0x21, bRequest = Set Report (0x09), Report ID (0xF5), Report Type (Feature 0x03), interface (0x00), datalength, datalength, data)
pUsb->ctrlReq(bAddress,epInfo[PS3_CONTROL_PIPE].epAddr, bmREQ_HID_OUT, HID_REQUEST_SET_REPORT, 0xF5, 0x03, 0x00, 8, 8, buf, NULL); pUsb->ctrlReq(bAddress, epInfo[PS3_CONTROL_PIPE].epAddr, bmREQ_HID_OUT, HID_REQUEST_SET_REPORT, 0xF5, 0x03, 0x00, 8, 8, buf, NULL);
#ifdef DEBUG #ifdef DEBUG
Notify(PSTR("\r\nBluetooth Address was set to: "), 0x80); Notify(PSTR("\r\nBluetooth Address was set to: "), 0x80);
for(int8_t i = 5; i > 0; i--) { for (int8_t i = 5; i > 0; i--) {
PrintHex<uint8_t>(my_bdaddr[i], 0x80); PrintHex<uint8_t > (my_bdaddr[i], 0x80);
Serial.print(":"); Serial.print(":");
} }
PrintHex<uint8_t>(my_bdaddr[0], 0x80); PrintHex<uint8_t > (my_bdaddr[0], 0x80);
#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
cmd_buf[1] = 0x0c; cmd_buf[1] = 0x0c;
cmd_buf[2] = 0x00; cmd_buf[2] = 0x00;
cmd_buf[3] = 0x00; cmd_buf[3] = 0x00;
//bmRequest = Host to device (0x00) | Class (0x20) | Interface (0x01) = 0x21, bRequest = Set Report (0x09), Report ID (0xF4), Report Type (Feature 0x03), interface (0x00), datalength, datalength, data) //bmRequest = Host to device (0x00) | Class (0x20) | Interface (0x01) = 0x21, bRequest = Set Report (0x09), Report ID (0xF4), Report Type (Feature 0x03), interface (0x00), datalength, datalength, data)
pUsb->ctrlReq(bAddress,epInfo[PS3_CONTROL_PIPE].epAddr, bmREQ_HID_OUT, HID_REQUEST_SET_REPORT, 0xF4, 0x03, 0x00, 4, 4, cmd_buf, NULL); pUsb->ctrlReq(bAddress, epInfo[PS3_CONTROL_PIPE].epAddr, bmREQ_HID_OUT, HID_REQUEST_SET_REPORT, 0xF4, 0x03, 0x00, 4, 4, cmd_buf, NULL);
} }
/* Playstation Move Controller commands */ /* Playstation Move Controller commands */
@ -512,12 +525,14 @@ 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)
Notify(PSTR("\r\nThe rumble value has to at least 64, or approximately 25%"), 0x80); Notify(PSTR("\r\nThe rumble value has to at least 64, or approximately 25%"), 0x80);
#endif #endif
//set the rumble value into the write buffer //set the rumble value into the write buffer
@ -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];
@ -538,14 +554,14 @@ void PS3USB::setMoveBdaddr(uint8_t* BDADDR) {
buf[i + 1] = BDADDR[i]; buf[i + 1] = BDADDR[i];
//bmRequest = Host to device (0x00) | Class (0x20) | Interface (0x01) = 0x21, bRequest = Set Report (0x09), Report ID (0x05), Report Type (Feature 0x03), interface (0x00), datalength, datalength, data) //bmRequest = Host to device (0x00) | Class (0x20) | Interface (0x01) = 0x21, bRequest = Set Report (0x09), Report ID (0x05), Report Type (Feature 0x03), interface (0x00), datalength, datalength, data)
pUsb->ctrlReq(bAddress,epInfo[PS3_CONTROL_PIPE].epAddr, bmREQ_HID_OUT, HID_REQUEST_SET_REPORT, 0x05, 0x03, 0x00,11,11, buf, NULL); pUsb->ctrlReq(bAddress, epInfo[PS3_CONTROL_PIPE].epAddr, bmREQ_HID_OUT, HID_REQUEST_SET_REPORT, 0x05, 0x03, 0x00, 11, 11, buf, NULL);
#ifdef DEBUG #ifdef DEBUG
Notify(PSTR("\r\nBluetooth Address was set to: "), 0x80); Notify(PSTR("\r\nBluetooth Address was set to: "), 0x80);
for(int8_t i = 5; i > 0; i--) { for (int8_t i = 5; i > 0; i--) {
PrintHex<uint8_t>(my_bdaddr[i], 0x80); PrintHex<uint8_t > (my_bdaddr[i], 0x80);
Serial.print(":"); Serial.print(":");
} }
PrintHex<uint8_t>(my_bdaddr[0], 0x80); PrintHex<uint8_t > (my_bdaddr[0], 0x80);
#endif #endif
return; return;
} }

View file

@ -70,7 +70,7 @@ public:
* Pass your dongles Bluetooth address into the constructor, * Pass your dongles Bluetooth address into the constructor,
* so you are able to pair the controller with a Bluetooth dongle. * so you are able to pair the controller with a Bluetooth dongle.
*/ */
PS3USB(USB *pUsb, uint8_t btadr5=0, uint8_t btadr4=0, uint8_t btadr3=0, uint8_t btadr2=0, uint8_t btadr1=0, uint8_t btadr0=0); PS3USB(USB *pUsb, uint8_t btadr5 = 0, uint8_t btadr4 = 0, uint8_t btadr3 = 0, uint8_t btadr2 = 0, uint8_t btadr1 = 0, uint8_t btadr0 = 0);
/** @name USBDeviceConfig implementation */ /** @name USBDeviceConfig implementation */
/** /**
@ -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;
};
/**@}*/ /**@}*/
/** /**

425
SPP.cpp
View file

@ -23,7 +23,7 @@
/* /*
* CRC (reversed crc) lookup table as calculated by the table generator in ETSI TS 101 369 V6.3.0. * CRC (reversed crc) lookup table as calculated by the table generator in ETSI TS 101 369 V6.3.0.
*/ */
const uint8_t rfcomm_crc_table[256] PROGMEM = { /* reversed, 8-bit, poly=0x07 */ const uint8_t rfcomm_crc_table[256] PROGMEM = {/* reversed, 8-bit, poly=0x07 */
0x00, 0x91, 0xE3, 0x72, 0x07, 0x96, 0xE4, 0x75, 0x0E, 0x9F, 0xED, 0x7C, 0x09, 0x98, 0xEA, 0x7B, 0x00, 0x91, 0xE3, 0x72, 0x07, 0x96, 0xE4, 0x75, 0x0E, 0x9F, 0xED, 0x7C, 0x09, 0x98, 0xEA, 0x7B,
0x1C, 0x8D, 0xFF, 0x6E, 0x1B, 0x8A, 0xF8, 0x69, 0x12, 0x83, 0xF1, 0x60, 0x15, 0x84, 0xF6, 0x67, 0x1C, 0x8D, 0xFF, 0x6E, 0x1B, 0x8A, 0xF8, 0x69, 0x12, 0x83, 0xF1, 0x60, 0x15, 0x84, 0xF6, 0x67,
0x38, 0xA9, 0xDB, 0x4A, 0x3F, 0xAE, 0xDC, 0x4D, 0x36, 0xA7, 0xD5, 0x44, 0x31, 0xA0, 0xD2, 0x43, 0x38, 0xA9, 0xDB, 0x4A, 0x3F, 0xAE, 0xDC, 0x4D, 0x36, 0xA7, 0xD5, 0x44, 0x31, 0xA0, 0xD2, 0x43,
@ -42,7 +42,7 @@ const uint8_t rfcomm_crc_table[256] PROGMEM = { /* reversed, 8-bit, poly=0x07 */
0xB4, 0x25, 0x57, 0xC6, 0xB3, 0x22, 0x50, 0xC1, 0xBA, 0x2B, 0x59, 0xC8, 0xBD, 0x2C, 0x5E, 0xCF 0xB4, 0x25, 0x57, 0xC6, 0xB3, 0x22, 0x50, 0xC1, 0xBA, 0x2B, 0x59, 0xC8, 0xBD, 0x2C, 0x5E, 0xCF
}; };
SPP::SPP(BTD *p, const char* name, const char* pin): SPP::SPP(BTD *p, const char* name, const char* pin) :
pBtd(p) // Pointer to BTD class instance - mandatory pBtd(p) // Pointer to BTD class instance - mandatory
{ {
if (pBtd) if (pBtd)
@ -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,25 +68,27 @@ 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
if(RFCOMMConnected) if (RFCOMMConnected)
pBtd->l2cap_disconnection_request(hci_handle,0x0A, rfcomm_scid, rfcomm_dcid); pBtd->l2cap_disconnection_request(hci_handle, 0x0A, rfcomm_scid, rfcomm_dcid);
if(RFCOMMConnected && SDPConnected) if (RFCOMMConnected && SDPConnected)
delay(1); // Add delay between commands delay(1); // Add delay between commands
if(SDPConnected) if (SDPConnected)
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) {
if((l2capinbuf[12] | (l2capinbuf[13] << 8)) == SDP_PSM && !pBtd->sdpConnectionClaimed) { if ((l2capinbuf[12] | (l2capinbuf[13] << 8)) == SDP_PSM && !pBtd->sdpConnectionClaimed) {
pBtd->sdpConnectionClaimed = true; pBtd->sdpConnectionClaimed = true;
hci_handle = pBtd->hci_handle; // Store the HCI Handle for the connection hci_handle = pBtd->hci_handle; // Store the HCI Handle for the connection
l2cap_sdp_state = L2CAP_SDP_WAIT; // Reset state l2cap_sdp_state = L2CAP_SDP_WAIT; // Reset state
} else if((l2capinbuf[12] | (l2capinbuf[13] << 8)) == RFCOMM_PSM && !pBtd->rfcommConnectionClaimed) { } else if ((l2capinbuf[12] | (l2capinbuf[13] << 8)) == RFCOMM_PSM && !pBtd->rfcommConnectionClaimed) {
pBtd->rfcommConnectionClaimed = true; pBtd->rfcommConnectionClaimed = true;
hci_handle = pBtd->hci_handle; // Store the HCI Handle for the connection hci_handle = pBtd->hci_handle; // Store the HCI Handle for the connection
l2cap_rfcomm_state = L2CAP_RFCOMM_WAIT; // Reset state l2cap_rfcomm_state = L2CAP_RFCOMM_WAIT; // Reset state
@ -97,30 +100,30 @@ void SPP::ACLData(uint8_t* l2capinbuf) {
if (l2capinbuf[8] == L2CAP_CMD_COMMAND_REJECT) { if (l2capinbuf[8] == L2CAP_CMD_COMMAND_REJECT) {
#ifdef DEBUG #ifdef DEBUG
Notify(PSTR("\r\nL2CAP Command Rejected - Reason: "), 0x80); Notify(PSTR("\r\nL2CAP Command Rejected - Reason: "), 0x80);
PrintHex<uint8_t>(l2capinbuf[13], 0x80); PrintHex<uint8_t > (l2capinbuf[13], 0x80);
Notify(PSTR(" "), 0x80); Notify(PSTR(" "), 0x80);
PrintHex<uint8_t>(l2capinbuf[12], 0x80); PrintHex<uint8_t > (l2capinbuf[12], 0x80);
Notify(PSTR(" Data: "), 0x80); Notify(PSTR(" Data: "), 0x80);
PrintHex<uint8_t>(l2capinbuf[17], 0x80); PrintHex<uint8_t > (l2capinbuf[17], 0x80);
Notify(PSTR(" "), 0x80); Notify(PSTR(" "), 0x80);
PrintHex<uint8_t>(l2capinbuf[16], 0x80); PrintHex<uint8_t > (l2capinbuf[16], 0x80);
Notify(PSTR(" "), 0x80); Notify(PSTR(" "), 0x80);
PrintHex<uint8_t>(l2capinbuf[15], 0x80); PrintHex<uint8_t > (l2capinbuf[15], 0x80);
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_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);
Notify(PSTR(" "), 0x80); Notify(PSTR(" "), 0x80);
PrintHex<uint8_t>(l2capinbuf[12], 0x80); PrintHex<uint8_t > (l2capinbuf[12], 0x80);
Notify(PSTR(" SCID: "), 0x80); Notify(PSTR(" SCID: "), 0x80);
PrintHex<uint8_t>(l2capinbuf[15], 0x80); PrintHex<uint8_t > (l2capinbuf[15], 0x80);
Notify(PSTR(" "), 0x80); Notify(PSTR(" "), 0x80);
PrintHex<uint8_t>(l2capinbuf[14], 0x80); PrintHex<uint8_t > (l2capinbuf[14], 0x80);
Notify(PSTR(" Identifier: "), 0x80); Notify(PSTR(" Identifier: "), 0x80);
PrintHex<uint8_t>(l2capinbuf[9], 0x80); PrintHex<uint8_t > (l2capinbuf[9], 0x80);
#endif #endif
if ((l2capinbuf[12] | (l2capinbuf[13] << 8)) == SDP_PSM) { // It doesn't matter if it receives another reqeust, since it waits for the channel to disconnect in the L2CAP_SDP_DONE state, and the l2cap_event_flag will be cleared if so if ((l2capinbuf[12] | (l2capinbuf[13] << 8)) == SDP_PSM) { // It doesn't matter if it receives another reqeust, since it waits for the channel to disconnect in the L2CAP_SDP_DONE state, and the l2cap_event_flag will be cleared if so
identifier = l2capinbuf[9]; identifier = l2capinbuf[9];
@ -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;
@ -180,16 +181,16 @@ void SPP::ACLData(uint8_t* l2capinbuf) {
Notify(PSTR("\r\nInformation request"), 0x80); Notify(PSTR("\r\nInformation request"), 0x80);
#endif #endif
identifier = l2capinbuf[9]; identifier = l2capinbuf[9];
pBtd->l2cap_information_response(hci_handle,identifier,l2capinbuf[12],l2capinbuf[13]); pBtd->l2cap_information_response(hci_handle, identifier, l2capinbuf[12], l2capinbuf[13]);
} }
#ifdef EXTRADEBUG #ifdef EXTRADEBUG
else { else {
Notify(PSTR("\r\nL2CAP Unknown Signaling Command: "), 0x80); Notify(PSTR("\r\nL2CAP Unknown Signaling Command: "), 0x80);
PrintHex<uint8_t>(l2capinbuf[8], 0x80); PrintHex<uint8_t > (l2capinbuf[8], 0x80);
} }
#endif #endif
} else if (l2capinbuf[6] == sdp_dcid[0] && l2capinbuf[7] == sdp_dcid[1]) { // SDP } else if (l2capinbuf[6] == sdp_dcid[0] && l2capinbuf[7] == sdp_dcid[1]) { // SDP
if(l2capinbuf[8] == SDP_SERVICE_SEARCH_ATTRIBUTE_REQUEST_PDU) { if (l2capinbuf[8] == SDP_SERVICE_SEARCH_ATTRIBUTE_REQUEST_PDU) {
/* /*
Serial.print("\r\nUUID: 0x"); Serial.print("\r\nUUID: 0x");
Serial.print(l2capinbuf[16],HEX); Serial.print(l2capinbuf[16],HEX);
@ -197,23 +198,23 @@ void SPP::ACLData(uint8_t* l2capinbuf) {
Serial.print(l2capinbuf[17],HEX); Serial.print(l2capinbuf[17],HEX);
*/ */
if ((l2capinbuf[16] << 8 | l2capinbuf[17]) == SERIALPORT_UUID) { if ((l2capinbuf[16] << 8 | l2capinbuf[17]) == SERIALPORT_UUID) {
if(firstMessage) { if (firstMessage) {
serialPortResponse1(l2capinbuf[9],l2capinbuf[10]); serialPortResponse1(l2capinbuf[9], l2capinbuf[10]);
firstMessage = false; firstMessage = false;
} else { } else {
serialPortResponse2(l2capinbuf[9],l2capinbuf[10]); // Serialport continuation state serialPortResponse2(l2capinbuf[9], l2capinbuf[10]); // Serialport continuation state
firstMessage = true; firstMessage = true;
} }
} else if ((l2capinbuf[16] << 8 | l2capinbuf[17]) == L2CAP_UUID) { } else if ((l2capinbuf[16] << 8 | l2capinbuf[17]) == L2CAP_UUID) {
if(firstMessage) { if (firstMessage) {
l2capResponse1(l2capinbuf[9],l2capinbuf[10]); l2capResponse1(l2capinbuf[9], l2capinbuf[10]);
firstMessage = false; firstMessage = false;
} else { } else {
l2capResponse2(l2capinbuf[9],l2capinbuf[10]); // L2CAP continuation state l2capResponse2(l2capinbuf[9], l2capinbuf[10]); // L2CAP continuation state
firstMessage = true; firstMessage = true;
} }
} else } else
serviceNotSupported(l2capinbuf[9],l2capinbuf[10]); // The service is not supported serviceNotSupported(l2capinbuf[9], l2capinbuf[10]); // The service is not supported
} }
} else if (l2capinbuf[6] == rfcomm_dcid[0] && l2capinbuf[7] == rfcomm_dcid[1]) { // RFCOMM } else if (l2capinbuf[6] == rfcomm_dcid[0] && l2capinbuf[7] == rfcomm_dcid[1]) { // RFCOMM
rfcommChannel = l2capinbuf[8] & 0xF8; rfcommChannel = l2capinbuf[8] & 0xF8;
@ -222,37 +223,37 @@ void SPP::ACLData(uint8_t* l2capinbuf) {
rfcommChannelType = l2capinbuf[9] & 0xEF; rfcommChannelType = l2capinbuf[9] & 0xEF;
rfcommPfBit = l2capinbuf[9] & 0x10; rfcommPfBit = l2capinbuf[9] & 0x10;
if(rfcommChannel>>3 != 0x00) if (rfcommChannel >> 3 != 0x00)
rfcommChannelConnection = rfcommChannel; rfcommChannelConnection = rfcommChannel;
#ifdef EXTRADEBUG #ifdef EXTRADEBUG
Notify(PSTR("\r\nRFCOMM Channel: "), 0x80); Notify(PSTR("\r\nRFCOMM Channel: "), 0x80);
Serial.print(rfcommChannel>>3,HEX); Serial.print(rfcommChannel >> 3, HEX);
Notify(PSTR(" Direction: "), 0x80); Notify(PSTR(" Direction: "), 0x80);
Serial.print(rfcommDirection>>2,HEX); Serial.print(rfcommDirection >> 2, HEX);
Notify(PSTR(" CommandResponse: "), 0x80); Notify(PSTR(" CommandResponse: "), 0x80);
Serial.print(rfcommCommandResponse>>1,HEX); Serial.print(rfcommCommandResponse >> 1, HEX);
Notify(PSTR(" ChannelType: "), 0x80); Notify(PSTR(" ChannelType: "), 0x80);
Serial.print(rfcommChannelType,HEX); Serial.print(rfcommChannelType, HEX);
Notify(PSTR(" PF_BIT: "), 0x80); Notify(PSTR(" PF_BIT: "), 0x80);
Serial.print(rfcommPfBit,HEX); Serial.print(rfcommPfBit, HEX);
#endif #endif
if (rfcommChannelType == RFCOMM_DISC) { if (rfcommChannelType == RFCOMM_DISC) {
#ifdef DEBUG #ifdef DEBUG
Notify(PSTR("\r\nReceived Disconnect RFCOMM Command on channel: "), 0x80); Notify(PSTR("\r\nReceived Disconnect RFCOMM Command on channel: "), 0x80);
Serial.print(rfcommChannel>>3,HEX); Serial.print(rfcommChannel >> 3, HEX);
#endif #endif
connected = false; connected = false;
sendRfcomm(rfcommChannel,rfcommDirection,rfcommCommandResponse,RFCOMM_UA,rfcommPfBit,rfcommbuf,0x00); // UA Command sendRfcomm(rfcommChannel, rfcommDirection, rfcommCommandResponse, RFCOMM_UA, rfcommPfBit, rfcommbuf, 0x00); // UA Command
} }
if(connected) { if (connected) {
/* Read the incoming message */ /* Read the incoming message */
if(rfcommChannelType == RFCOMM_UIH && rfcommChannel == rfcommChannelConnection) { if (rfcommChannelType == RFCOMM_UIH && rfcommChannel == rfcommChannelConnection) {
uint8_t length = l2capinbuf[10] >> 1; // Get length uint8_t length = l2capinbuf[10] >> 1; // Get length
uint8_t offset = l2capinbuf[4]-length-4; // See if there is credit uint8_t offset = l2capinbuf[4] - length - 4; // See if there is credit
if(rfcommAvailable + length <= sizeof(rfcommDataBuffer)) { // Don't add data to buffer if it would be full if (rfcommAvailable + length <= sizeof (rfcommDataBuffer)) { // Don't add data to buffer if it would be full
for(uint8_t i = 0; i < length; i++) for (uint8_t i = 0; i < length; i++)
rfcommDataBuffer[rfcommAvailable+i] = l2capinbuf[11+i+offset]; rfcommDataBuffer[rfcommAvailable + i] = l2capinbuf[11 + i + offset];
rfcommAvailable += length; rfcommAvailable += length;
} }
#ifdef EXTRADEBUG #ifdef EXTRADEBUG
@ -260,12 +261,12 @@ void SPP::ACLData(uint8_t* l2capinbuf) {
Serial.print(rfcommAvailable); Serial.print(rfcommAvailable);
if (offset) { if (offset) {
Notify(PSTR(" - Credit: 0x"), 0x80); Notify(PSTR(" - Credit: 0x"), 0x80);
Serial.print(l2capinbuf[11],HEX); Serial.print(l2capinbuf[11], HEX);
} }
#endif #endif
#ifdef PRINTREPORT // Uncomment "#define PRINTREPORT" to print the report send to the Arduino via Bluetooth #ifdef PRINTREPORT // Uncomment "#define PRINTREPORT" to print the report send to the Arduino via Bluetooth
for(uint8_t i = 0; i < length; i++) for (uint8_t i = 0; i < length; i++)
Serial.write(l2capinbuf[i+11+offset]); Serial.write(l2capinbuf[i + 11 + offset]);
#endif #endif
} else if (rfcommChannelType == RFCOMM_UIH && l2capinbuf[11] == BT_RFCOMM_RPN_CMD) { // UIH Remote Port Negotiation Command } else if (rfcommChannelType == RFCOMM_UIH && l2capinbuf[11] == BT_RFCOMM_RPN_CMD) { // UIH Remote Port Negotiation Command
#ifdef DEBUG #ifdef DEBUG
@ -281,8 +282,8 @@ void SPP::ACLData(uint8_t* l2capinbuf) {
rfcommbuf[7] = l2capinbuf[18]; // Max Fram Size MSB rfcommbuf[7] = l2capinbuf[18]; // Max Fram Size MSB
rfcommbuf[8] = l2capinbuf[19]; // MaxRatransm. rfcommbuf[8] = l2capinbuf[19]; // MaxRatransm.
rfcommbuf[9] = l2capinbuf[20]; // Number of Frames rfcommbuf[9] = l2capinbuf[20]; // Number of Frames
sendRfcomm(rfcommChannel,rfcommDirection,0,RFCOMM_UIH,rfcommPfBit,rfcommbuf,0x0A); // UIH Remote Port Negotiation Response sendRfcomm(rfcommChannel, rfcommDirection, 0, RFCOMM_UIH, rfcommPfBit, rfcommbuf, 0x0A); // UIH Remote Port Negotiation Response
} else if(rfcommChannelType == RFCOMM_UIH && l2capinbuf[11] == BT_RFCOMM_MSC_CMD) { // UIH Modem Status Command } else if (rfcommChannelType == RFCOMM_UIH && l2capinbuf[11] == BT_RFCOMM_MSC_CMD) { // UIH Modem Status Command
#ifdef DEBUG #ifdef DEBUG
Notify(PSTR("\r\nSend UIH Modem Status Response"), 0x80); Notify(PSTR("\r\nSend UIH Modem Status Response"), 0x80);
#endif #endif
@ -290,15 +291,15 @@ void SPP::ACLData(uint8_t* l2capinbuf) {
rfcommbuf[1] = 2 << 1 | 1; // Length and shiftet like so: length << 1 | 1 rfcommbuf[1] = 2 << 1 | 1; // Length and shiftet like so: length << 1 | 1
rfcommbuf[2] = l2capinbuf[13]; // Channel: (1 << 0) | (1 << 1) | (0 << 2) | (channel << 3) rfcommbuf[2] = l2capinbuf[13]; // Channel: (1 << 0) | (1 << 1) | (0 << 2) | (channel << 3)
rfcommbuf[3] = l2capinbuf[14]; rfcommbuf[3] = l2capinbuf[14];
sendRfcomm(rfcommChannel,rfcommDirection,0,RFCOMM_UIH,rfcommPfBit,rfcommbuf,0x04); sendRfcomm(rfcommChannel, rfcommDirection, 0, RFCOMM_UIH, rfcommPfBit, rfcommbuf, 0x04);
} }
} else { } else {
if(rfcommChannelType == RFCOMM_SABM) { // SABM Command - this is sent twice: once for channel 0 and then for the channel to establish if (rfcommChannelType == RFCOMM_SABM) { // SABM Command - this is sent twice: once for channel 0 and then for the channel to establish
#ifdef DEBUG #ifdef DEBUG
Notify(PSTR("\r\nReceived SABM Command"), 0x80); Notify(PSTR("\r\nReceived SABM Command"), 0x80);
#endif #endif
sendRfcomm(rfcommChannel,rfcommDirection,rfcommCommandResponse,RFCOMM_UA,rfcommPfBit,rfcommbuf,0x00); // UA Command sendRfcomm(rfcommChannel, rfcommDirection, rfcommCommandResponse, RFCOMM_UA, rfcommPfBit, rfcommbuf, 0x00); // UA Command
} else if(rfcommChannelType == RFCOMM_UIH && l2capinbuf[11] == BT_RFCOMM_PN_CMD) { // UIH Parameter Negotiation Command } else if (rfcommChannelType == RFCOMM_UIH && l2capinbuf[11] == BT_RFCOMM_PN_CMD) { // UIH Parameter Negotiation Command
#ifdef DEBUG #ifdef DEBUG
Notify(PSTR("\r\nReceived UIH Parameter Negotiation Command"), 0x80); Notify(PSTR("\r\nReceived UIH Parameter Negotiation Command"), 0x80);
#endif #endif
@ -308,12 +309,12 @@ void SPP::ACLData(uint8_t* l2capinbuf) {
rfcommbuf[3] = 0xE0; // Pre difined for Bluetooth, see 5.5.3 of TS 07.10 Adaption for RFCOMM rfcommbuf[3] = 0xE0; // Pre difined for Bluetooth, see 5.5.3 of TS 07.10 Adaption for RFCOMM
rfcommbuf[4] = 0x00; // Priority rfcommbuf[4] = 0x00; // Priority
rfcommbuf[5] = 0x00; // Timer rfcommbuf[5] = 0x00; // Timer
rfcommbuf[6] = BULK_MAXPKTSIZE-14; // Max Fram Size LSB - set to the size of received data (50) rfcommbuf[6] = BULK_MAXPKTSIZE - 14; // Max Fram Size LSB - set to the size of received data (50)
rfcommbuf[7] = 0x00; // Max Fram Size MSB rfcommbuf[7] = 0x00; // Max Fram Size MSB
rfcommbuf[8] = 0x00; // MaxRatransm. rfcommbuf[8] = 0x00; // MaxRatransm.
rfcommbuf[9] = 0x00; // Number of Frames rfcommbuf[9] = 0x00; // Number of Frames
sendRfcomm(rfcommChannel,rfcommDirection,0,RFCOMM_UIH,rfcommPfBit,rfcommbuf,0x0A); sendRfcomm(rfcommChannel, rfcommDirection, 0, RFCOMM_UIH, rfcommPfBit, rfcommbuf, 0x0A);
} else if(rfcommChannelType == RFCOMM_UIH && l2capinbuf[11] == BT_RFCOMM_MSC_CMD) { // UIH Modem Status Command } else if (rfcommChannelType == RFCOMM_UIH && l2capinbuf[11] == BT_RFCOMM_MSC_CMD) { // UIH Modem Status Command
#ifdef DEBUG #ifdef DEBUG
Notify(PSTR("\r\nSend UIH Modem Status Response"), 0x80); Notify(PSTR("\r\nSend UIH Modem Status Response"), 0x80);
#endif #endif
@ -321,7 +322,7 @@ void SPP::ACLData(uint8_t* l2capinbuf) {
rfcommbuf[1] = 2 << 1 | 1; // Length and shiftet like so: length << 1 | 1 rfcommbuf[1] = 2 << 1 | 1; // Length and shiftet like so: length << 1 | 1
rfcommbuf[2] = l2capinbuf[13]; // Channel: (1 << 0) | (1 << 1) | (0 << 2) | (channel << 3) rfcommbuf[2] = l2capinbuf[13]; // Channel: (1 << 0) | (1 << 1) | (0 << 2) | (channel << 3)
rfcommbuf[3] = l2capinbuf[14]; rfcommbuf[3] = l2capinbuf[14];
sendRfcomm(rfcommChannel,rfcommDirection,0,RFCOMM_UIH,rfcommPfBit,rfcommbuf,0x04); sendRfcomm(rfcommChannel, rfcommDirection, 0, RFCOMM_UIH, rfcommPfBit, rfcommbuf, 0x04);
delay(1); delay(1);
#ifdef DEBUG #ifdef DEBUG
@ -332,22 +333,22 @@ void SPP::ACLData(uint8_t* l2capinbuf) {
rfcommbuf[2] = l2capinbuf[13]; // Channel: (1 << 0) | (1 << 1) | (0 << 2) | (channel << 3) rfcommbuf[2] = l2capinbuf[13]; // Channel: (1 << 0) | (1 << 1) | (0 << 2) | (channel << 3)
rfcommbuf[3] = 0x8D; // Can receive frames (YES), Ready to Communicate (YES), Ready to Receive (YES), Incomig Call (NO), Data is Value (YES) rfcommbuf[3] = 0x8D; // Can receive frames (YES), Ready to Communicate (YES), Ready to Receive (YES), Incomig Call (NO), Data is Value (YES)
sendRfcomm(rfcommChannel,rfcommDirection,0,RFCOMM_UIH,rfcommPfBit,rfcommbuf,0x04); sendRfcomm(rfcommChannel, rfcommDirection, 0, RFCOMM_UIH, rfcommPfBit, rfcommbuf, 0x04);
} else if(rfcommChannelType == RFCOMM_UIH && l2capinbuf[11] == BT_RFCOMM_MSC_RSP) { // UIH Modem Status Response } else if (rfcommChannelType == RFCOMM_UIH && l2capinbuf[11] == BT_RFCOMM_MSC_RSP) { // UIH Modem Status Response
if(!creditSent) { if (!creditSent) {
#ifdef DEBUG #ifdef DEBUG
Notify(PSTR("\r\nSend UIH Command with credit"), 0x80); Notify(PSTR("\r\nSend UIH Command with credit"), 0x80);
#endif #endif
sendRfcommCredit(rfcommChannelConnection,rfcommDirection,0,RFCOMM_UIH,0x10,sizeof(rfcommDataBuffer)); // Send credit sendRfcommCredit(rfcommChannelConnection, rfcommDirection, 0, RFCOMM_UIH, 0x10, sizeof (rfcommDataBuffer)); // Send credit
creditSent = true; creditSent = true;
timer = millis(); timer = millis();
waitForLastCommand = true; waitForLastCommand = true;
} }
} else if(rfcommChannelType == RFCOMM_UIH && l2capinbuf[10] == 0x01) { // UIH Command with credit } else if (rfcommChannelType == RFCOMM_UIH && l2capinbuf[10] == 0x01) { // UIH Command with credit
#ifdef DEBUG #ifdef DEBUG
Notify(PSTR("\r\nReceived UIH Command with credit"), 0x80); Notify(PSTR("\r\nReceived UIH Command with credit"), 0x80);
#endif #endif
} else if(rfcommChannelType == RFCOMM_UIH && l2capinbuf[11] == BT_RFCOMM_RPN_CMD) { // UIH Remote Port Negotiation Command } else if (rfcommChannelType == RFCOMM_UIH && l2capinbuf[11] == BT_RFCOMM_RPN_CMD) { // UIH Remote Port Negotiation Command
#ifdef DEBUG #ifdef DEBUG
Notify(PSTR("\r\nReceived UIH Remote Port Negotiation Command"), 0x80); Notify(PSTR("\r\nReceived UIH Remote Port Negotiation Command"), 0x80);
#endif #endif
@ -361,7 +362,7 @@ void SPP::ACLData(uint8_t* l2capinbuf) {
rfcommbuf[7] = l2capinbuf[18]; // Max Fram Size MSB rfcommbuf[7] = l2capinbuf[18]; // Max Fram Size MSB
rfcommbuf[8] = l2capinbuf[19]; // MaxRatransm. rfcommbuf[8] = l2capinbuf[19]; // MaxRatransm.
rfcommbuf[9] = l2capinbuf[20]; // Number of Frames rfcommbuf[9] = l2capinbuf[20]; // Number of Frames
sendRfcomm(rfcommChannel,rfcommDirection,0,RFCOMM_UIH,rfcommPfBit,rfcommbuf,0x0A); // UIH Remote Port Negotiation Response sendRfcomm(rfcommChannel, rfcommDirection, 0, RFCOMM_UIH, rfcommPfBit, rfcommbuf, 0x0A); // UIH Remote Port Negotiation Response
#ifdef DEBUG #ifdef DEBUG
Notify(PSTR("\r\nRFCOMM Connection is now established\r\n"), 0x80); Notify(PSTR("\r\nRFCOMM Connection is now established\r\n"), 0x80);
#endif #endif
@ -370,11 +371,11 @@ void SPP::ACLData(uint8_t* l2capinbuf) {
connected = true; // The RFCOMM channel is now established connected = true; // The RFCOMM channel is now established
} }
#ifdef DEBUG #ifdef DEBUG
else if(rfcommChannelType != RFCOMM_DISC) { else if (rfcommChannelType != RFCOMM_DISC) {
Notify(PSTR("\r\nUnsupported RFCOMM Data - ChannelType: "), 0x80); Notify(PSTR("\r\nUnsupported RFCOMM Data - ChannelType: "), 0x80);
PrintHex<uint8_t>(rfcommChannelType, 0x80); PrintHex<uint8_t > (rfcommChannelType, 0x80);
Notify(PSTR(" Command: "), 0x80); Notify(PSTR(" Command: "), 0x80);
PrintHex<uint8_t>(l2capinbuf[11], 0x80); PrintHex<uint8_t > (l2capinbuf[11], 0x80);
} }
#endif #endif
} }
@ -382,17 +383,18 @@ void SPP::ACLData(uint8_t* l2capinbuf) {
#ifdef EXTRADEBUG #ifdef EXTRADEBUG
else { else {
Notify(PSTR("\r\nUnsupported L2CAP Data - Channel ID: "), 0x80); Notify(PSTR("\r\nUnsupported L2CAP Data - Channel ID: "), 0x80);
PrintHex<uint8_t>(l2capinbuf[7], 0x80); PrintHex<uint8_t > (l2capinbuf[7], 0x80);
Notify(PSTR(" "), 0x80); Notify(PSTR(" "), 0x80);
PrintHex<uint8_t>(l2capinbuf[6], 0x80); PrintHex<uint8_t > (l2capinbuf[6], 0x80);
} }
#endif #endif
SDP_task(); SDP_task();
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
Notify(PSTR("\r\nRFCOMM Connection is now established - Automatic\r\n"), 0x80); Notify(PSTR("\r\nRFCOMM Connection is now established - Automatic\r\n"), 0x80);
#endif #endif
@ -401,21 +403,21 @@ 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
#ifdef DEBUG #ifdef DEBUG
Notify(PSTR("\r\nSDP Incoming Connection Request"), 0x80); Notify(PSTR("\r\nSDP Incoming Connection Request"), 0x80);
#endif #endif
pBtd->l2cap_connection_response(hci_handle,identifier, sdp_dcid, sdp_scid, PENDING); pBtd->l2cap_connection_response(hci_handle, identifier, sdp_dcid, sdp_scid, PENDING);
delay(1); delay(1);
pBtd->l2cap_connection_response(hci_handle,identifier, sdp_dcid, sdp_scid, SUCCESSFUL); pBtd->l2cap_connection_response(hci_handle, identifier, sdp_dcid, sdp_scid, SUCCESSFUL);
identifier++; identifier++;
delay(1); delay(1);
pBtd->l2cap_config_request(hci_handle,identifier, sdp_scid); pBtd->l2cap_config_request(hci_handle, identifier, sdp_scid);
l2cap_sdp_state = L2CAP_SDP_REQUEST; l2cap_sdp_state = L2CAP_SDP_REQUEST;
} }
break; break;
@ -425,7 +427,7 @@ void SPP::SDP_task() {
#ifdef DEBUG #ifdef DEBUG
Notify(PSTR("\r\nSDP Configuration Request"), 0x80); Notify(PSTR("\r\nSDP Configuration Request"), 0x80);
#endif #endif
pBtd->l2cap_config_response(hci_handle,identifier, sdp_scid); pBtd->l2cap_config_response(hci_handle, identifier, sdp_scid);
l2cap_sdp_state = L2CAP_SDP_SUCCESS; l2cap_sdp_state = L2CAP_SDP_SUCCESS;
} }
break; break;
@ -441,15 +443,15 @@ void SPP::SDP_task() {
} }
break; break;
case L2CAP_SDP_DONE: case L2CAP_SDP_DONE:
if(l2cap_disconnect_request_sdp_flag) { if (l2cap_disconnect_request_sdp_flag) {
l2cap_event_flag &= ~L2CAP_FLAG_DISCONNECT_SDP_REQUEST; // Clear flag l2cap_event_flag &= ~L2CAP_FLAG_DISCONNECT_SDP_REQUEST; // Clear flag
SDPConnected = false; SDPConnected = false;
#ifdef DEBUG #ifdef DEBUG
Notify(PSTR("\r\nDisconnected SDP Channel"), 0x80); Notify(PSTR("\r\nDisconnected SDP Channel"), 0x80);
#endif #endif
pBtd->l2cap_disconnection_response(hci_handle,identifier,sdp_dcid,sdp_scid); pBtd->l2cap_disconnection_response(hci_handle, identifier, sdp_dcid, sdp_scid);
l2cap_sdp_state = L2CAP_SDP_WAIT; l2cap_sdp_state = L2CAP_SDP_WAIT;
} else if(l2cap_connection_request_sdp_flag) } else if (l2cap_connection_request_sdp_flag)
l2cap_rfcomm_state = L2CAP_SDP_WAIT; l2cap_rfcomm_state = L2CAP_SDP_WAIT;
break; break;
case L2CAP_DISCONNECT_RESPONSE: // This is for both disconnection response from the RFCOMM and SDP channel if they were connected case L2CAP_DISCONNECT_RESPONSE: // This is for both disconnection response from the RFCOMM and SDP channel if they were connected
@ -468,22 +470,21 @@ 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
#ifdef DEBUG #ifdef DEBUG
Notify(PSTR("\r\nRFCOMM Incoming Connection Request"), 0x80); Notify(PSTR("\r\nRFCOMM Incoming Connection Request"), 0x80);
#endif #endif
pBtd->l2cap_connection_response(hci_handle,identifier, rfcomm_dcid, rfcomm_scid, PENDING); pBtd->l2cap_connection_response(hci_handle, identifier, rfcomm_dcid, rfcomm_scid, PENDING);
delay(1); delay(1);
pBtd->l2cap_connection_response(hci_handle,identifier, rfcomm_dcid, rfcomm_scid, SUCCESSFUL); pBtd->l2cap_connection_response(hci_handle, identifier, rfcomm_dcid, rfcomm_scid, SUCCESSFUL);
identifier++; identifier++;
delay(1); delay(1);
pBtd->l2cap_config_request(hci_handle,identifier, rfcomm_scid); pBtd->l2cap_config_request(hci_handle, identifier, rfcomm_scid);
l2cap_rfcomm_state = L2CAP_RFCOMM_REQUEST; l2cap_rfcomm_state = L2CAP_RFCOMM_REQUEST;
} }
break; break;
@ -493,7 +494,7 @@ void SPP::RFCOMM_task()
#ifdef DEBUG #ifdef DEBUG
Notify(PSTR("\r\nRFCOMM Configuration Request"), 0x80); Notify(PSTR("\r\nRFCOMM Configuration Request"), 0x80);
#endif #endif
pBtd->l2cap_config_response(hci_handle,identifier, rfcomm_scid); pBtd->l2cap_config_response(hci_handle, identifier, rfcomm_scid);
l2cap_rfcomm_state = L2CAP_RFCOMM_SUCCESS; l2cap_rfcomm_state = L2CAP_RFCOMM_SUCCESS;
} }
break; break;
@ -510,26 +511,28 @@ void SPP::RFCOMM_task()
} }
break; break;
case L2CAP_RFCOMM_DONE: case L2CAP_RFCOMM_DONE:
if(l2cap_disconnect_request_rfcomm_flag) { if (l2cap_disconnect_request_rfcomm_flag) {
l2cap_event_flag &= ~L2CAP_FLAG_DISCONNECT_RFCOMM_REQUEST; // Clear flag l2cap_event_flag &= ~L2CAP_FLAG_DISCONNECT_RFCOMM_REQUEST; // Clear flag
RFCOMMConnected = false; RFCOMMConnected = false;
connected = false; connected = false;
#ifdef DEBUG #ifdef DEBUG
Notify(PSTR("\r\nDisconnected RFCOMM Channel"), 0x80); Notify(PSTR("\r\nDisconnected RFCOMM Channel"), 0x80);
#endif #endif
pBtd->l2cap_disconnection_response(hci_handle,identifier,rfcomm_dcid,rfcomm_scid); pBtd->l2cap_disconnection_response(hci_handle, identifier, rfcomm_dcid, rfcomm_scid);
l2cap_rfcomm_state = L2CAP_RFCOMM_WAIT; l2cap_rfcomm_state = L2CAP_RFCOMM_WAIT;
} else if(l2cap_connection_request_rfcomm_flag) } else if (l2cap_connection_request_rfcomm_flag)
l2cap_rfcomm_state = L2CAP_RFCOMM_WAIT; l2cap_rfcomm_state = L2CAP_RFCOMM_WAIT;
break; break;
} }
} }
/************************************************************/ /************************************************************/
/* 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;
@ -544,8 +547,9 @@ void SPP::serviceNotSupported(uint8_t transactionIDHigh, uint8_t transactionIDLo
l2capoutbuf[8] = 0x00; l2capoutbuf[8] = 0x00;
l2capoutbuf[9] = 0x00; l2capoutbuf[9] = 0x00;
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;
@ -601,8 +605,9 @@ void SPP::serialPortResponse1(uint8_t transactionIDHigh, uint8_t transactionIDLo
l2capoutbuf[46] = 0x00; // 25 (0x19) more bytes to come l2capoutbuf[46] = 0x00; // 25 (0x19) more bytes to come
l2capoutbuf[47] = 0x19; l2capoutbuf[47] = 0x19;
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;
@ -642,19 +647,22 @@ void SPP::serialPortResponse2(uint8_t transactionIDHigh, uint8_t transactionIDLo
l2capoutbuf[31] = 'P'; l2capoutbuf[31] = 'P';
l2capoutbuf[32] = 0x00; // No more data l2capoutbuf[32] = 0x00; // No more data
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]);
} }
void SPP::sendRfcomm(uint8_t channel, uint8_t direction, uint8_t CR, uint8_t channelType, uint8_t pfBit, uint8_t* data, uint8_t length) { void SPP::sendRfcomm(uint8_t channel, uint8_t direction, uint8_t CR, uint8_t channelType, uint8_t pfBit, uint8_t* data, uint8_t length) {
@ -662,17 +670,17 @@ void SPP::sendRfcomm(uint8_t channel, uint8_t direction, uint8_t CR, uint8_t cha
l2capoutbuf[1] = channelType | pfBit; // RFCOMM Control l2capoutbuf[1] = channelType | pfBit; // RFCOMM Control
l2capoutbuf[2] = length << 1 | 0x01; // Length and format (allways 0x01 bytes format) l2capoutbuf[2] = length << 1 | 0x01; // Length and format (allways 0x01 bytes format)
uint8_t i = 0; uint8_t i = 0;
for(; i < length; i++) for (; i < length; i++)
l2capoutbuf[i+3] = data[i]; l2capoutbuf[i + 3] = data[i];
l2capoutbuf[i+3] = calcFcs(l2capoutbuf); l2capoutbuf[i + 3] = calcFcs(l2capoutbuf);
#ifdef EXTRADEBUG #ifdef EXTRADEBUG
Notify(PSTR(" - RFCOMM Data: "), 0x80); Notify(PSTR(" - RFCOMM Data: "), 0x80);
for(i = 0; i < length+4; i++) { for (i = 0; i < length + 4; i++) {
Serial.print(l2capoutbuf[i],HEX); Serial.print(l2capoutbuf[i], HEX);
Notify(PSTR(" "), 0x80); Notify(PSTR(" "), 0x80);
} }
#endif #endif
RFCOMM_Command(l2capoutbuf,length+4); RFCOMM_Command(l2capoutbuf, length + 4);
} }
void SPP::sendRfcommCredit(uint8_t channel, uint8_t direction, uint8_t CR, uint8_t channelType, uint8_t pfBit, uint8_t credit) { void SPP::sendRfcommCredit(uint8_t channel, uint8_t direction, uint8_t CR, uint8_t channelType, uint8_t pfBit, uint8_t credit) {
@ -683,22 +691,22 @@ void SPP::sendRfcommCredit(uint8_t channel, uint8_t direction, uint8_t CR, uint8
l2capoutbuf[4] = calcFcs(l2capoutbuf); l2capoutbuf[4] = calcFcs(l2capoutbuf);
#ifdef EXTRADEBUG #ifdef EXTRADEBUG
Notify(PSTR(" - RFCOMM Credit Data: "), 0x80); Notify(PSTR(" - RFCOMM Credit Data: "), 0x80);
for(uint8_t i = 0; i < 5; i++) { for (uint8_t i = 0; i < 5; i++) {
Serial.print(l2capoutbuf[i],HEX); Serial.print(l2capoutbuf[i], HEX);
Notify(PSTR(" "), 0x80); Notify(PSTR(" "), 0x80);
} }
#endif #endif
RFCOMM_Command(l2capoutbuf,5); RFCOMM_Command(l2capoutbuf, 5);
} }
/* CRC on 2 bytes */ /* CRC on 2 bytes */
uint8_t SPP::__crc(uint8_t* data) { uint8_t SPP::__crc(uint8_t* data) {
return(pgm_read_byte(&rfcomm_crc_table[pgm_read_byte(&rfcomm_crc_table[0xff ^ data[0]]) ^ data[1]])); return (pgm_read_byte(&rfcomm_crc_table[pgm_read_byte(&rfcomm_crc_table[0xff ^ data[0]]) ^ data[1]]));
} }
/* Calculate FCS - we never actually check if the host sends correct FCS to the Arduino */ /* Calculate FCS - we never actually check if the host sends correct FCS to the Arduino */
uint8_t SPP::calcFcs(uint8_t *data) { uint8_t SPP::calcFcs(uint8_t *data) {
if((data[1] & 0xEF) == RFCOMM_UIH) if ((data[1] & 0xEF) == RFCOMM_UIH)
return (0xff - __crc(data)); // FCS on 2 bytes return (0xff - __crc(data)); // FCS on 2 bytes
else else
return (0xff - pgm_read_byte(&rfcomm_crc_table[__crc(data) ^ data[2]])); // FCS on 3 bytes return (0xff - pgm_read_byte(&rfcomm_crc_table[__crc(data) ^ data[2]])); // FCS on 3 bytes
@ -706,143 +714,159 @@ uint8_t SPP::calcFcs(uint8_t *data) {
/* Serial commands */ /* Serial commands */
void SPP::print(const String &str) { void SPP::print(const String &str) {
if(!connected) if (!connected)
return; return;
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;
for(; i < length; i++) for (; i < length; i++)
l2capoutbuf[i+3] = str[i]; l2capoutbuf[i + 3] = str[i];
l2capoutbuf[i+3] = calcFcs(l2capoutbuf); l2capoutbuf[i + 3] = calcFcs(l2capoutbuf);
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;
for(; i < length; i++) for (; i < length; i++)
l2capoutbuf[i+3] = str[i]; l2capoutbuf[i + 3] = str[i];
l2capoutbuf[i+3] = calcFcs(l2capoutbuf); l2capoutbuf[i + 3] = calcFcs(l2capoutbuf);
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;
for(; i < length; i++) for (; i < length; i++)
l2capoutbuf[i+3] = array[i]; l2capoutbuf[i + 3] = array[i];
l2capoutbuf[i+3] = calcFcs(l2capoutbuf); l2capoutbuf[i + 3] = calcFcs(l2capoutbuf);
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);
buf[length] = '\r'; buf[length] = '\r';
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;
while (1) { // Calculate the size of the string while (1) { // Calculate the size of the string
uint8_t c = pgm_read_byte(p+size); uint8_t c = pgm_read_byte(p + size);
if (c == 0) if (c == 0)
break; break;
size++; size++;
} }
uint8_t buf[size+2]; // Add two extra in case it needs to print a newline and carriage return uint8_t buf[size + 2]; // Add two extra in case it needs to print a newline and carriage return
for(uint8_t i = 0; i < size; i++) for (uint8_t i = 0; i < size; i++)
buf[i] = pgm_read_byte(p++); buf[i] = pgm_read_byte(p++);
if(newline) { if (newline) {
buf[size] = '\r'; buf[size] = '\r';
buf[size+1] = '\n'; buf[size + 1] = '\n';
print(buf,size+2); print(buf, size + 2);
} 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);
} }
/* These must be used to print numbers */ /* These must be used to print numbers */
void SPP::printNumber(uint32_t n) { void SPP::printNumber(uint32_t n) {
char output[11]; char output[11];
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];
intToString((uint32_t)(input*-1),buf); intToString((uint32_t)(input*-1), buf);
strcpy(output,"-"); strcpy(output, "-");
strcat(output,buf); strcat(output, buf);
} 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;
while(temp) { while (temp) {
temp /= 10; temp /= 10;
digits++; digits++;
} }
if(digits == 0) if (digits == 0)
strcpy(output,"0"); strcpy(output, "0");
else { else {
for(uint8_t i = 1; i <= digits; i++) { for (uint8_t i = 1; i <= digits; i++) {
output[digits-i] = input%10 + '0'; // Get number and convert to ASCII Character output[digits - i] = input % 10 + '0'; // Get number and convert to ASCII Character
input /= 10; input /= 10;
} }
output[digits] = '\0'; // Add null character output[digits] = '\0'; // Add null character
@ -850,60 +874,61 @@ void SPP::intToString(uint32_t input, char* output) {
} }
void SPP::printNumber(double n, uint8_t digits) { void SPP::printNumber(double n, uint8_t digits) {
char output[13+digits]; char output[13 + 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
double rounding = 0.5; double rounding = 0.5;
for (uint8_t i=0; i<digits; i++) for (uint8_t i = 0; i < digits; i++)
rounding /= 10.0; rounding /= 10.0;
input += rounding; input += rounding;
uint32_t intpart = (uint32_t)input; uint32_t intpart = (uint32_t)input;
intToString(intpart,buffer); // Convert to string intToString(intpart, buffer); // Convert to string
strcat(output,buffer); strcat(output, buffer);
strcat(output,"."); strcat(output, ".");
double fractpart = (input-(double)intpart); double fractpart = (input - (double)intpart);
fractpart *= pow(10,digits); fractpart *= pow(10, digits);
for(uint8_t i=1;i<digits;i++) { // Put zeros in front of number for (uint8_t i = 1; i < digits; i++) { // Put zeros in front of number
if(fractpart < pow(10,digits-i)) { if (fractpart < pow(10, digits - i)) {
strcat(output,"0"); strcat(output, "0");
} }
} }
intToString((uint32_t)fractpart,buffer); // Convert to string intToString((uint32_t)fractpart, buffer); // Convert to string
strcat(output,buffer); strcat(output, buffer);
} }
uint8_t SPP::read() { uint8_t SPP::read() {
if(rfcommAvailable == 0) // Don't read if there is nothing in the buffer if (rfcommAvailable == 0) // Don't read if there is nothing in the buffer
return 0; return 0;
uint8_t output = rfcommDataBuffer[0]; uint8_t output = rfcommDataBuffer[0];
for(uint8_t i = 1; i < rfcommAvailable; i++) for (uint8_t i = 1; i < rfcommAvailable; i++)
rfcommDataBuffer[i-1] = rfcommDataBuffer[i]; // Shift the buffer one left rfcommDataBuffer[i - 1] = rfcommDataBuffer[i]; // Shift the buffer one left
rfcommAvailable--; rfcommAvailable--;
bytesRead++; bytesRead++;
if(bytesRead > (sizeof(rfcommDataBuffer)-5)) { // We will send the command just before it runs out of credit if (bytesRead > (sizeof (rfcommDataBuffer) - 5)) { // We will send the command just before it runs out of credit
bytesRead = 0; bytesRead = 0;
sendRfcommCredit(rfcommChannelConnection,rfcommDirection,0,RFCOMM_UIH,0x10,sizeof(rfcommDataBuffer)); // Send more credit sendRfcommCredit(rfcommChannelConnection, rfcommDirection, 0, RFCOMM_UIH, 0x10, sizeof (rfcommDataBuffer)); // Send more credit
#ifdef EXTRADEBUG #ifdef EXTRADEBUG
Notify(PSTR("\r\nSent "), 0x80); Notify(PSTR("\r\nSent "), 0x80);
Serial.print(sizeof(rfcommDataBuffer)); Serial.print(sizeof (rfcommDataBuffer));
Notify(PSTR(" more credit"), 0x80); Notify(PSTR(" more credit"), 0x80);
#endif #endif
} }

62
SPP.h
View file

@ -87,7 +87,7 @@
#define BT_RFCOMM_RLS_CMD 0x53 #define BT_RFCOMM_RLS_CMD 0x53
#define BT_RFCOMM_RLS_RSP 0x51 #define BT_RFCOMM_RLS_RSP 0x51
#define BT_RFCOMM_NSC_RSP 0x11 #define BT_RFCOMM_NSC_RSP 0x11
*/ */
/** This BluetoothService class implements the Serial Port Protocol (SPP). */ /** This BluetoothService class implements the Serial Port Protocol (SPP). */
class SPP : public BluetoothService { class SPP : public BluetoothService {
@ -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:

View file

@ -176,7 +176,7 @@ uint8_t USB::ctrlReq(uint8_t addr, uint8_t ep, uint8_t bmReqType, uint8_t bReque
// Invoke callback function if inTransfer completed successfuly and callback function pointer is specified // Invoke callback function if inTransfer completed successfuly and callback function pointer is specified
if (!rcode && p) if (!rcode && p)
((USBReadParser*) p)->Parse(read, dataptr, total - left); ((USBReadParser*)p)->Parse(read, dataptr, total - left);
left -= read; left -= read;
@ -243,7 +243,7 @@ uint8_t USB::InTransfer(EpInfo *pep, uint16_t nak_limit, uint16_t *nbytesptr, ui
//printf("Got %i bytes ", pktsize); //printf("Got %i bytes ", pktsize);
assert(pktsize <= nbytes); assert(pktsize <= nbytes);
int16_t mem_left = (int16_t) nbytes - *((int16_t*) nbytesptr); int16_t mem_left = (int16_t)nbytes - *((int16_t*)nbytesptr);
if (mem_left < 0) if (mem_left < 0)
mem_left = 0; mem_left = 0;
@ -591,7 +591,7 @@ uint8_t USB::getConfDescr(uint8_t addr, uint8_t ep, uint8_t conf, USBReadParser
if (ret) if (ret)
return ret; return ret;
uint16_t total = ((USB_CONFIGURATION_DESCRIPTOR*) buf)->wTotalLength; uint16_t total = ((USB_CONFIGURATION_DESCRIPTOR*)buf)->wTotalLength;
//USBTRACE2("\r\ntotal conf.size:", total); //USBTRACE2("\r\ntotal conf.size:", total);

20
Usb.h
View file

@ -147,7 +147,7 @@ typedef struct {
uint8_t recipient : 5; // Recipient of the request uint8_t recipient : 5; // Recipient of the request
uint8_t type : 2; // Type of request uint8_t type : 2; // Type of request
uint8_t direction : 1; // Direction of data X-fer uint8_t direction : 1; // Direction of data X-fer
}__attribute__((packed)); } __attribute__((packed));
} ReqType_u; } ReqType_u;
uint8_t bRequest; // 1 Request uint8_t bRequest; // 1 Request
@ -157,7 +157,7 @@ typedef struct {
struct { struct {
uint8_t wValueLo; uint8_t wValueLo;
uint8_t wValueHi; uint8_t wValueHi;
}__attribute__((packed)); } __attribute__((packed));
} wVal_u; } wVal_u;
uint16_t wIndex; // 4 Depends on bRequest uint16_t wIndex; // 4 Depends on bRequest
uint16_t wLength; // 6 Depends on bRequest uint16_t wLength; // 6 Depends on bRequest
@ -190,12 +190,12 @@ public:
}; };
AddressPool& GetAddressPool() { AddressPool& GetAddressPool() {
return (AddressPool&) addrPool; return(AddressPool&) addrPool;
}; };
uint8_t RegisterDeviceClass(USBDeviceConfig *pdev) { uint8_t RegisterDeviceClass(USBDeviceConfig *pdev) {
for (uint8_t i = 0; i < USB_NUMDEVICES; i++) { for(uint8_t i = 0; i < USB_NUMDEVICES; i++) {
if (!devConfig[i]) { if(!devConfig[i]) {
devConfig[i] = pdev; devConfig[i] = pdev;
return 0; return 0;
} }
@ -250,27 +250,27 @@ private:
//get device descriptor //get device descriptor
inline uint8_t USB::getDevDescr(uint8_t addr, uint8_t ep, uint16_t nbytes, uint8_t* dataptr) { inline uint8_t USB::getDevDescr(uint8_t addr, uint8_t ep, uint16_t nbytes, uint8_t* dataptr) {
return ( ctrlReq(addr, ep, bmREQ_GET_DESCR, USB_REQUEST_GET_DESCRIPTOR, 0x00, USB_DESCRIPTOR_DEVICE, 0x0000, nbytes, dataptr)); return( ctrlReq(addr, ep, bmREQ_GET_DESCR, USB_REQUEST_GET_DESCRIPTOR, 0x00, USB_DESCRIPTOR_DEVICE, 0x0000, nbytes, dataptr));
} }
//get configuration descriptor //get configuration descriptor
inline uint8_t USB::getConfDescr(uint8_t addr, uint8_t ep, uint16_t nbytes, uint8_t conf, uint8_t* dataptr) { inline uint8_t USB::getConfDescr(uint8_t addr, uint8_t ep, uint16_t nbytes, uint8_t conf, uint8_t* dataptr) {
return ( ctrlReq(addr, ep, bmREQ_GET_DESCR, USB_REQUEST_GET_DESCRIPTOR, conf, USB_DESCRIPTOR_CONFIGURATION, 0x0000, nbytes, dataptr)); return( ctrlReq(addr, ep, bmREQ_GET_DESCR, USB_REQUEST_GET_DESCRIPTOR, conf, USB_DESCRIPTOR_CONFIGURATION, 0x0000, nbytes, dataptr));
} }
//get string descriptor //get string descriptor
inline uint8_t USB::getStrDescr(uint8_t addr, uint8_t ep, uint16_t nuint8_ts, uint8_t index, uint16_t langid, uint8_t* dataptr) { inline uint8_t USB::getStrDescr(uint8_t addr, uint8_t ep, uint16_t nuint8_ts, uint8_t index, uint16_t langid, uint8_t* dataptr) {
return ( ctrlReq(addr, ep, bmREQ_GET_DESCR, USB_REQUEST_GET_DESCRIPTOR, index, USB_DESCRIPTOR_STRING, langid, nuint8_ts, dataptr)); return( ctrlReq(addr, ep, bmREQ_GET_DESCR, USB_REQUEST_GET_DESCRIPTOR, index, USB_DESCRIPTOR_STRING, langid, nuint8_ts, dataptr));
} }
//set address //set address
inline uint8_t USB::setAddr(uint8_t oldaddr, uint8_t ep, uint8_t newaddr) { inline uint8_t USB::setAddr(uint8_t oldaddr, uint8_t ep, uint8_t newaddr) {
return ( ctrlReq(oldaddr, ep, bmREQ_SET, USB_REQUEST_SET_ADDRESS, newaddr, 0x00, 0x0000, 0x0000, NULL)); return( ctrlReq(oldaddr, ep, bmREQ_SET, USB_REQUEST_SET_ADDRESS, newaddr, 0x00, 0x0000, 0x0000, NULL));
} }
//set configuration //set configuration
inline uint8_t USB::setConf(uint8_t addr, uint8_t ep, uint8_t conf_value) { inline uint8_t USB::setConf(uint8_t addr, uint8_t ep, uint8_t conf_value) {
return ( ctrlReq(addr, ep, bmREQ_SET, USB_REQUEST_SET_CONFIGURATION, conf_value, 0x00, 0x0000, 0x0000, NULL)); return( ctrlReq(addr, ep, bmREQ_SET, USB_REQUEST_SET_CONFIGURATION, conf_value, 0x00, 0x0000, 0x0000, NULL));
} }
#endif // defined(USB_METHODS_INLINE) #endif // defined(USB_METHODS_INLINE)

443
Wii.cpp

File diff suppressed because it is too large Load diff

89
Wii.h
View file

@ -101,7 +101,7 @@ public:
* @param pair Set this to true in order to pair with the Wiimote. If the argument is omitted then it won't pair with it. * @param pair Set this to true in order to pair with the Wiimote. If the argument is omitted then it won't pair with it.
* One can use ::PAIR to set it to true. * One can use ::PAIR to set it to true.
*/ */
WII(BTD *p, bool pair=false); WII(BTD *p, bool pair = false);
/** @name BluetoothService implementation */ /** @name BluetoothService implementation */
/** /**
@ -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
@ -368,14 +415,14 @@ private:
/* variables used by high level L2CAP task */ /* variables used by high level L2CAP task */
uint8_t l2cap_state; uint8_t l2cap_state;
uint16_t l2cap_event_flag;// l2cap flags of received bluetooth events uint16_t l2cap_event_flag; // l2cap flags of received bluetooth events
uint32_t ButtonState; uint32_t ButtonState;
uint32_t OldButtonState; uint32_t OldButtonState;
uint32_t ButtonClickState; uint32_t ButtonClickState;
uint16_t hatValues[4]; uint16_t hatValues[4];
uint8_t HIDBuffer[3];// Used to store HID commands uint8_t HIDBuffer[3]; // Used to store HID commands
uint16_t stateCounter; uint16_t stateCounter;
bool unknownExtensionConnected; bool unknownExtensionConnected;

View file

@ -22,11 +22,11 @@
//#define EXTRADEBUG // Uncomment to get even more debugging data //#define EXTRADEBUG // Uncomment to get even more debugging data
//#define PRINTREPORT // Uncomment to print the report send by the Xbox 360 Controller //#define PRINTREPORT // Uncomment to print the report send by the Xbox 360 Controller
XBOXRECV::XBOXRECV(USB *p): XBOXRECV::XBOXRECV(USB *p) :
pUsb(p), // pointer to USB class instance - mandatory pUsb(p), // pointer to USB class instance - mandatory
bAddress(0), // device address - mandatory bAddress(0), // device address - mandatory
bPollEnable(false) { // don't start polling before dongle is connected bPollEnable(false) { // don't start polling before dongle is connected
for(uint8_t i=0; i<XBOX_MAX_ENDPOINTS; i++) { for (uint8_t i = 0; i < XBOX_MAX_ENDPOINTS; i++) {
epInfo[i].epAddr = 0; epInfo[i].epAddr = 0;
epInfo[i].maxPktSize = (i) ? 0 : 8; epInfo[i].maxPktSize = (i) ? 0 : 8;
epInfo[i].epAttribs = 0; epInfo[i].epAttribs = 0;
@ -38,7 +38,7 @@ bPollEnable(false) { // don't start polling before dongle is connected
} }
uint8_t XBOXRECV::Init(uint8_t parent, uint8_t port, bool lowspeed) { uint8_t XBOXRECV::Init(uint8_t parent, uint8_t port, bool lowspeed) {
uint8_t buf[sizeof(USB_DEVICE_DESCRIPTOR)]; uint8_t buf[sizeof (USB_DEVICE_DESCRIPTOR)];
uint8_t rcode; uint8_t rcode;
UsbDevice *p = NULL; UsbDevice *p = NULL;
EpInfo *oldep_ptr = NULL; EpInfo *oldep_ptr = NULL;
@ -84,19 +84,19 @@ uint8_t XBOXRECV::Init(uint8_t parent, uint8_t port, bool lowspeed) {
p->lowspeed = lowspeed; p->lowspeed = lowspeed;
// Get device descriptor // Get device descriptor
rcode = pUsb->getDevDescr(0, 0, sizeof(USB_DEVICE_DESCRIPTOR), (uint8_t*)buf);// Get device descriptor - addr, ep, nbytes, data rcode = pUsb->getDevDescr(0, 0, sizeof (USB_DEVICE_DESCRIPTOR), (uint8_t*)buf); // Get device descriptor - addr, ep, nbytes, data
// Restore p->epinfo // Restore p->epinfo
p->epinfo = oldep_ptr; p->epinfo = oldep_ptr;
if(rcode) if (rcode)
goto FailGetDevDescr; goto FailGetDevDescr;
VID = ((USB_DEVICE_DESCRIPTOR*)buf)->idVendor; VID = ((USB_DEVICE_DESCRIPTOR*)buf)->idVendor;
PID = ((USB_DEVICE_DESCRIPTOR*)buf)->idProduct; PID = ((USB_DEVICE_DESCRIPTOR*)buf)->idProduct;
if(VID != XBOX_VID && VID != MADCATZ_VID) // We just check if it's a xbox receiver using the Vendor ID if (VID != XBOX_VID && VID != MADCATZ_VID) // We just check if it's a xbox receiver using the Vendor ID
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\nYou'll need a wireless receiver for this libary to work"), 0x80); Notify(PSTR("\r\nYou'll need a wireless receiver for this libary to work"), 0x80);
#endif #endif
@ -113,7 +113,7 @@ uint8_t XBOXRECV::Init(uint8_t parent, uint8_t port, bool lowspeed) {
epInfo[0].maxPktSize = (uint8_t)((USB_DEVICE_DESCRIPTOR*)buf)->bMaxPacketSize0; epInfo[0].maxPktSize = (uint8_t)((USB_DEVICE_DESCRIPTOR*)buf)->bMaxPacketSize0;
// Assign new address to the device // Assign new address to the device
rcode = pUsb->setAddr( 0, 0, bAddress ); rcode = pUsb->setAddr(0, 0, bAddress);
if (rcode) { if (rcode) {
p->lowspeed = false; p->lowspeed = false;
addrPool.FreeAddress(bAddress); addrPool.FreeAddress(bAddress);
@ -121,12 +121,12 @@ uint8_t XBOXRECV::Init(uint8_t parent, uint8_t port, bool lowspeed) {
#ifdef DEBUG #ifdef DEBUG
Notify(PSTR("\r\nsetAddr: "), 0x80); Notify(PSTR("\r\nsetAddr: "), 0x80);
#endif #endif
PrintHex<uint8_t>(rcode, 0x80); PrintHex<uint8_t > (rcode, 0x80);
return rcode; return rcode;
} }
#ifdef EXTRADEBUG #ifdef EXTRADEBUG
Notify(PSTR("\r\nAddr: "), 0x80); Notify(PSTR("\r\nAddr: "), 0x80);
PrintHex<uint8_t>(bAddress, 0x80); PrintHex<uint8_t > (bAddress, 0x80);
#endif #endif
p->lowspeed = false; p->lowspeed = false;
@ -200,13 +200,13 @@ uint8_t XBOXRECV::Init(uint8_t parent, uint8_t port, bool lowspeed) {
epInfo[ XBOX_OUTPUT_PIPE_4 ].bmRcvToggle = bmRCVTOG0; epInfo[ XBOX_OUTPUT_PIPE_4 ].bmRcvToggle = bmRCVTOG0;
rcode = pUsb->setEpInfoEntry(bAddress, 9, epInfo); rcode = pUsb->setEpInfoEntry(bAddress, 9, epInfo);
if( rcode ) if (rcode)
goto FailSetDevTblEntry; goto FailSetDevTblEntry;
delay(200);//Give time for address change delay(200); //Give time for address change
rcode = pUsb->setConf(bAddress, epInfo[ XBOX_CONTROL_PIPE ].epAddr, 1); rcode = pUsb->setConf(bAddress, epInfo[ XBOX_CONTROL_PIPE ].epAddr, 1);
if( rcode ) if (rcode)
goto FailSetConf; goto FailSetConf;
#ifdef DEBUG #ifdef DEBUG
@ -235,16 +235,16 @@ FailSetConf:
FailUnknownDevice: FailUnknownDevice:
#ifdef DEBUG #ifdef DEBUG
Notify(PSTR("\r\nUnknown Device Connected - VID: "), 0x80); Notify(PSTR("\r\nUnknown Device Connected - VID: "), 0x80);
PrintHex<uint16_t>(VID, 0x80); PrintHex<uint16_t > (VID, 0x80);
Notify(PSTR(" PID: "), 0x80); Notify(PSTR(" PID: "), 0x80);
PrintHex<uint16_t>(PID, 0x80); PrintHex<uint16_t > (PID, 0x80);
#endif #endif
rcode = USB_DEV_CONFIG_ERROR_DEVICE_NOT_SUPPORTED; rcode = USB_DEV_CONFIG_ERROR_DEVICE_NOT_SUPPORTED;
goto Fail; goto Fail;
Fail: Fail:
#ifdef DEBUG #ifdef DEBUG
Notify(PSTR("\r\nXbox 360 Init Failed, error code: "), 0x80); Notify(PSTR("\r\nXbox 360 Init Failed, error code: "), 0x80);
Serial.print(rcode,HEX); Serial.print(rcode, HEX);
#endif #endif
Release(); Release();
return rcode; return rcode;
@ -253,32 +253,37 @@ Fail:
/* Performs a cleanup after failed Init() attempt */ /* Performs a cleanup after failed Init() attempt */
uint8_t XBOXRECV::Release() { uint8_t XBOXRECV::Release() {
XboxReceiverConnected = false; XboxReceiverConnected = false;
for(uint8_t i=0;i<4;i++) for (uint8_t i = 0; i < 4; i++)
Xbox360Connected[i] = 0x00; Xbox360Connected[i] = 0x00;
pUsb->GetAddressPool().FreeAddress(bAddress); pUsb->GetAddressPool().FreeAddress(bAddress);
bAddress = 0; bAddress = 0;
bPollEnable = false; bPollEnable = false;
return 0; return 0;
} }
uint8_t XBOXRECV::Poll() { uint8_t XBOXRECV::Poll() {
if (!bPollEnable) if (!bPollEnable)
return 0; return 0;
if(!timer || ((millis() - timer) > 3000)) { // Run checkStatus every 3 seconds if (!timer || ((millis() - timer) > 3000)) { // Run checkStatus every 3 seconds
timer = millis(); timer = millis();
checkStatus(); checkStatus();
} }
uint8_t inputPipe; uint8_t inputPipe;
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);
if(bufferSize > 0) { // The number of received bytes if (bufferSize > 0) { // The number of received bytes
#ifdef EXTRADEBUG #ifdef EXTRADEBUG
Notify(PSTR("Bytes Received: "), 0x80); Notify(PSTR("Bytes Received: "), 0x80);
Serial.print(bufferSize); Serial.print(bufferSize);
@ -286,7 +291,7 @@ uint8_t XBOXRECV::Poll() {
#endif #endif
readReport(i); readReport(i);
#ifdef PRINTREPORT #ifdef PRINTREPORT
printReport(i,bufferSize); // Uncomment "#define PRINTREPORT" to print the report send by the Xbox 360 Controller printReport(i, bufferSize); // Uncomment "#define PRINTREPORT" to print the report send by the Xbox 360 Controller
#endif #endif
} }
} }
@ -297,31 +302,38 @@ void XBOXRECV::readReport(uint8_t controller) {
if (readBuf == NULL) if (readBuf == NULL)
return; return;
// This report is send when a controller is connected and disconnected // This report is send when a controller is connected and disconnected
if(readBuf[0] == 0x08 && readBuf[1] != Xbox360Connected[controller]) { if (readBuf[0] == 0x08 && readBuf[1] != Xbox360Connected[controller]) {
Xbox360Connected[controller] = readBuf[1]; Xbox360Connected[controller] = readBuf[1];
#ifdef DEBUG #ifdef DEBUG
Notify(PSTR("Controller "), 0x80); Notify(PSTR("Controller "), 0x80);
Serial.print(controller); Serial.print(controller);
#endif #endif
if(Xbox360Connected[controller]) { if (Xbox360Connected[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);
} }
#ifdef DEBUG #ifdef DEBUG
else else
@ -330,15 +342,15 @@ void XBOXRECV::readReport(uint8_t controller) {
return; return;
} }
// Controller status report // Controller status report
if(readBuf[1] == 0x00 && readBuf[3] & 0x13 && readBuf[4] >= 0x22) { if (readBuf[1] == 0x00 && readBuf[3] & 0x13 && readBuf[4] >= 0x22) {
controllerStatus[controller] = ((uint16_t)readBuf[3] << 8) | readBuf[4]; controllerStatus[controller] = ((uint16_t)readBuf[3] << 8) | readBuf[4];
return; return;
} }
if(readBuf[1] != 0x01) // Check if it's the correct report - the receiver also sends different status reports if (readBuf[1] != 0x01) // Check if it's the correct report - the receiver also sends different status reports
return; return;
// A controller must be connected if it's sending data // A controller must be connected if it's sending data
if(!Xbox360Connected[controller]) if (!Xbox360Connected[controller])
Xbox360Connected[controller] |= 0x80; Xbox360Connected[controller] |= 0x80;
ButtonState[controller] = (uint32_t)(readBuf[9] | ((uint16_t)readBuf[8] << 8) | ((uint32_t)readBuf[7] << 16) | ((uint32_t)readBuf[6] << 24)); ButtonState[controller] = (uint32_t)(readBuf[9] | ((uint16_t)readBuf[8] << 8) | ((uint32_t)readBuf[7] << 16) | ((uint32_t)readBuf[6] << 24));
@ -351,12 +363,12 @@ void XBOXRECV::readReport(uint8_t controller) {
//Notify(PSTR("\r\nButtonState: "), 0x80); //Notify(PSTR("\r\nButtonState: "), 0x80);
//PrintHex<uint32_t>(ButtonState[controller], 0x80); //PrintHex<uint32_t>(ButtonState[controller], 0x80);
if(ButtonState[controller] != OldButtonState[controller]) { if (ButtonState[controller] != OldButtonState[controller]) {
buttonStateChanged[controller] = true; buttonStateChanged[controller] = true;
ButtonClickState[controller] = (ButtonState[controller] >> 16) & ((~OldButtonState[controller]) >> 16); // Update click state variable, but don't include the two trigger buttons L2 and R2 ButtonClickState[controller] = (ButtonState[controller] >> 16) & ((~OldButtonState[controller]) >> 16); // Update click state variable, but don't include the two trigger buttons L2 and R2
if(((uint8_t)OldButtonState[controller]) == 0 && ((uint8_t)ButtonState[controller]) != 0) // The L2 and R2 buttons are special as they are analog buttons if (((uint8_t)OldButtonState[controller]) == 0 && ((uint8_t)ButtonState[controller]) != 0) // The L2 and R2 buttons are special as they are analog buttons
R2Clicked[controller] = true; R2Clicked[controller] = true;
if((uint8_t)(OldButtonState[controller] >> 8) == 0 && (uint8_t)(ButtonState[controller] >> 8) != 0) if ((uint8_t)(OldButtonState[controller] >> 8) == 0 && (uint8_t)(ButtonState[controller] >> 8) != 0)
L2Clicked[controller] = true; L2Clicked[controller] = true;
OldButtonState[controller] = ButtonState[controller]; OldButtonState[controller] = ButtonState[controller];
} }
@ -369,30 +381,31 @@ void XBOXRECV::printReport(uint8_t controller, uint8_t nBytes) { //Uncomment "#d
Notify(PSTR("Controller "), 0x80); Notify(PSTR("Controller "), 0x80);
Serial.print(controller); Serial.print(controller);
Notify(PSTR(": "), 0x80); Notify(PSTR(": "), 0x80);
for(uint8_t i = 0; i < nBytes;i++) { for (uint8_t i = 0; i < nBytes; i++) {
PrintHex<uint8_t>(readBuf[i], 0x80); PrintHex<uint8_t > (readBuf[i], 0x80);
Serial.print(" "); Serial.print(" ");
} }
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);
else if(b == R2) else if (b == R2)
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]) {
L2Clicked[controller] = false; L2Clicked[controller] = false;
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
@ -429,10 +445,10 @@ ControllerStatus Breakdown
ControllerStatus[controller] & 0x2000 // 0 ControllerStatus[controller] & 0x2000 // 0
ControllerStatus[controller] & 0x4000 // 0 ControllerStatus[controller] & 0x4000 // 0
ControllerStatus[controller] & 0x8000 // 0 ControllerStatus[controller] & 0x8000 // 0
*/ */
uint8_t XBOXRECV::getBatteryLevel(uint8_t controller) { uint8_t XBOXRECV::getBatteryLevel(uint8_t controller) {
uint8_t batteryLevel = ((controllerStatus[controller] & 0x00C0) >> 6) * 33; uint8_t batteryLevel = ((controllerStatus[controller] & 0x00C0) >> 6) * 33;
if(batteryLevel == 99) if (batteryLevel == 99)
batteryLevel = 100; batteryLevel = 100;
return batteryLevel; return batteryLevel;
} }
@ -441,17 +457,22 @@ 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
if(rcode) if (rcode)
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,29 +481,33 @@ 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
*/ */
void XBOXRECV::checkStatus() { void XBOXRECV::checkStatus() {
if(!bPollEnable) if (!bPollEnable)
return; return;
// Get controller info // Get controller info
writeBuf[0] = 0x08; writeBuf[0] = 0x08;
writeBuf[1] = 0x00; writeBuf[1] = 0x00;
writeBuf[2] = 0x0f; writeBuf[2] = 0x0f;
writeBuf[3] = 0xc0; writeBuf[3] = 0xc0;
for(uint8_t i=0; i<4; i++) { for (uint8_t i = 0; i < 4; i++) {
XboxCommand(i, writeBuf, 4); XboxCommand(i, writeBuf, 4);
} }
// Get battery status // Get battery status
@ -490,8 +515,8 @@ void XBOXRECV::checkStatus() {
writeBuf[1] = 0x00; writeBuf[1] = 0x00;
writeBuf[2] = 0x00; writeBuf[2] = 0x00;
writeBuf[3] = 0x40; writeBuf[3] = 0x40;
for(uint8_t i=0; i<4; i++) { for (uint8_t i = 0; i < 4; i++) {
if(Xbox360Connected[i]) if (Xbox360Connected[i])
XboxCommand(i, writeBuf, 4); XboxCommand(i, writeBuf, 4);
} }
} }

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

@ -20,11 +20,11 @@
//#define EXTRADEBUG // Uncomment to get even more debugging data //#define EXTRADEBUG // Uncomment to get even more debugging data
//#define PRINTREPORT // Uncomment to print the report send by the Xbox 360 Controller //#define PRINTREPORT // Uncomment to print the report send by the Xbox 360 Controller
XBOXUSB::XBOXUSB(USB *p): XBOXUSB::XBOXUSB(USB *p) :
pUsb(p), // pointer to USB class instance - mandatory pUsb(p), // pointer to USB class instance - mandatory
bAddress(0), // device address - mandatory bAddress(0), // device address - mandatory
bPollEnable(false) { // don't start polling before dongle is connected bPollEnable(false) { // don't start polling before dongle is connected
for(uint8_t i=0; i<XBOX_MAX_ENDPOINTS; i++) { for (uint8_t i = 0; i < XBOX_MAX_ENDPOINTS; i++) {
epInfo[i].epAddr = 0; epInfo[i].epAddr = 0;
epInfo[i].maxPktSize = (i) ? 0 : 8; epInfo[i].maxPktSize = (i) ? 0 : 8;
epInfo[i].epAttribs = 0; epInfo[i].epAttribs = 0;
@ -36,7 +36,7 @@ bPollEnable(false) { // don't start polling before dongle is connected
} }
uint8_t XBOXUSB::Init(uint8_t parent, uint8_t port, bool lowspeed) { uint8_t XBOXUSB::Init(uint8_t parent, uint8_t port, bool lowspeed) {
uint8_t buf[sizeof(USB_DEVICE_DESCRIPTOR)]; uint8_t buf[sizeof (USB_DEVICE_DESCRIPTOR)];
uint8_t rcode; uint8_t rcode;
UsbDevice *p = NULL; UsbDevice *p = NULL;
EpInfo *oldep_ptr = NULL; EpInfo *oldep_ptr = NULL;
@ -82,25 +82,24 @@ uint8_t XBOXUSB::Init(uint8_t parent, uint8_t port, bool lowspeed) {
p->lowspeed = lowspeed; p->lowspeed = lowspeed;
// Get device descriptor // Get device descriptor
rcode = pUsb->getDevDescr(0, 0, sizeof(USB_DEVICE_DESCRIPTOR), (uint8_t*)buf);// Get device descriptor - addr, ep, nbytes, data rcode = pUsb->getDevDescr(0, 0, sizeof (USB_DEVICE_DESCRIPTOR), (uint8_t*)buf); // Get device descriptor - addr, ep, nbytes, data
// Restore p->epinfo // Restore p->epinfo
p->epinfo = oldep_ptr; p->epinfo = oldep_ptr;
if(rcode) if (rcode)
goto FailGetDevDescr; goto FailGetDevDescr;
VID = ((USB_DEVICE_DESCRIPTOR*)buf)->idVendor; VID = ((USB_DEVICE_DESCRIPTOR*)buf)->idVendor;
PID = ((USB_DEVICE_DESCRIPTOR*)buf)->idProduct; PID = ((USB_DEVICE_DESCRIPTOR*)buf)->idProduct;
if(VID != XBOX_VID && VID != MADCATZ_VID && VID != JOYTECH_VID) // We just check if it's a xbox controller using the Vendor ID if (VID != XBOX_VID && VID != MADCATZ_VID && VID != JOYTECH_VID) // We just check if it's a xbox controller using the Vendor ID
goto FailUnknownDevice; goto FailUnknownDevice;
if(PID == XBOX_WIRELESS_PID) { if (PID == XBOX_WIRELESS_PID) {
#ifdef DEBUG #ifdef DEBUG
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
@ -117,7 +116,7 @@ uint8_t XBOXUSB::Init(uint8_t parent, uint8_t port, bool lowspeed) {
epInfo[0].maxPktSize = (uint8_t)((USB_DEVICE_DESCRIPTOR*)buf)->bMaxPacketSize0; epInfo[0].maxPktSize = (uint8_t)((USB_DEVICE_DESCRIPTOR*)buf)->bMaxPacketSize0;
// Assign new address to the device // Assign new address to the device
rcode = pUsb->setAddr( 0, 0, bAddress ); rcode = pUsb->setAddr(0, 0, bAddress);
if (rcode) { if (rcode) {
p->lowspeed = false; p->lowspeed = false;
addrPool.FreeAddress(bAddress); addrPool.FreeAddress(bAddress);
@ -125,12 +124,12 @@ uint8_t XBOXUSB::Init(uint8_t parent, uint8_t port, bool lowspeed) {
#ifdef DEBUG #ifdef DEBUG
Notify(PSTR("\r\nsetAddr: "), 0x80); Notify(PSTR("\r\nsetAddr: "), 0x80);
#endif #endif
PrintHex<uint8_t>(rcode, 0x80); PrintHex<uint8_t > (rcode, 0x80);
return rcode; return rcode;
} }
#ifdef EXTRADEBUG #ifdef EXTRADEBUG
Notify(PSTR("\r\nAddr: "), 0x80); Notify(PSTR("\r\nAddr: "), 0x80);
PrintHex<uint8_t>(bAddress, 0x80); PrintHex<uint8_t > (bAddress, 0x80);
#endif #endif
p->lowspeed = false; p->lowspeed = false;
@ -165,13 +164,13 @@ uint8_t XBOXUSB::Init(uint8_t parent, uint8_t port, bool lowspeed) {
epInfo[ XBOX_OUTPUT_PIPE ].bmRcvToggle = bmRCVTOG0; epInfo[ XBOX_OUTPUT_PIPE ].bmRcvToggle = bmRCVTOG0;
rcode = pUsb->setEpInfoEntry(bAddress, 3, epInfo); rcode = pUsb->setEpInfoEntry(bAddress, 3, epInfo);
if( rcode ) if (rcode)
goto FailSetDevTblEntry; goto FailSetDevTblEntry;
delay(200);//Give time for address change delay(200); //Give time for address change
rcode = pUsb->setConf(bAddress, epInfo[ XBOX_CONTROL_PIPE ].epAddr, 1); rcode = pUsb->setConf(bAddress, epInfo[ XBOX_CONTROL_PIPE ].epAddr, 1);
if( rcode ) if (rcode)
goto FailSetConf; goto FailSetConf;
#ifdef DEBUG #ifdef DEBUG
@ -201,16 +200,16 @@ FailSetConf:
FailUnknownDevice: FailUnknownDevice:
#ifdef DEBUG #ifdef DEBUG
Notify(PSTR("\r\nUnknown Device Connected - VID: "), 0x80); Notify(PSTR("\r\nUnknown Device Connected - VID: "), 0x80);
PrintHex<uint16_t>(VID, 0x80); PrintHex<uint16_t > (VID, 0x80);
Notify(PSTR(" PID: "), 0x80); Notify(PSTR(" PID: "), 0x80);
PrintHex<uint16_t>(PID, 0x80); PrintHex<uint16_t > (PID, 0x80);
#endif #endif
rcode = USB_DEV_CONFIG_ERROR_DEVICE_NOT_SUPPORTED; rcode = USB_DEV_CONFIG_ERROR_DEVICE_NOT_SUPPORTED;
goto Fail; goto Fail;
Fail: Fail:
#ifdef DEBUG #ifdef DEBUG
Notify(PSTR("\r\nXbox 360 Init Failed, error code: "), 0x80); Notify(PSTR("\r\nXbox 360 Init Failed, error code: "), 0x80);
Serial.print(rcode,HEX); Serial.print(rcode, HEX);
#endif #endif
Release(); Release();
return rcode; return rcode;
@ -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;
@ -239,7 +239,7 @@ uint8_t XBOXUSB::Poll() {
void XBOXUSB::readReport() { void XBOXUSB::readReport() {
if (readBuf == NULL) if (readBuf == NULL)
return; return;
if(readBuf[0] != 0x00 || readBuf[1] != 0x14) { // Check if it's the correct report - the controller also sends different status reports if (readBuf[0] != 0x00 || readBuf[1] != 0x14) { // Check if it's the correct report - the controller also sends different status reports
return; return;
} }
@ -253,11 +253,11 @@ void XBOXUSB::readReport() {
//Notify(PSTR("\r\nButtonState"), 0x80); //Notify(PSTR("\r\nButtonState"), 0x80);
//PrintHex<uint32_t>(ButtonState, 0x80); //PrintHex<uint32_t>(ButtonState, 0x80);
if(ButtonState != OldButtonState) { if (ButtonState != OldButtonState) {
ButtonClickState = (ButtonState >> 16) & ((~OldButtonState) >> 16); // Update click state variable, but don't include the two trigger buttons L2 and R2 ButtonClickState = (ButtonState >> 16) & ((~OldButtonState) >> 16); // Update click state variable, but don't include the two trigger buttons L2 and R2
if(((uint8_t)OldButtonState) == 0 && ((uint8_t)ButtonState) != 0) // The L2 and R2 buttons are special as they are analog buttons if (((uint8_t)OldButtonState) == 0 && ((uint8_t)ButtonState) != 0) // The L2 and R2 buttons are special as they are analog buttons
R2Clicked = true; R2Clicked = true;
if((uint8_t)(OldButtonState >> 8) == 0 && (uint8_t)(ButtonState >> 8) != 0) if ((uint8_t)(OldButtonState >> 8) == 0 && (uint8_t)(ButtonState >> 8) != 0)
L2Clicked = true; L2Clicked = true;
OldButtonState = ButtonState; OldButtonState = ButtonState;
} }
@ -267,8 +267,8 @@ void XBOXUSB::printReport() { //Uncomment "#define PRINTREPORT" to print the rep
#ifdef PRINTREPORT #ifdef PRINTREPORT
if (readBuf == NULL) if (readBuf == NULL)
return; return;
for(uint8_t i = 0; i < XBOX_REPORT_BUFFER_SIZE;i++) { for (uint8_t i = 0; i < XBOX_REPORT_BUFFER_SIZE; i++) {
PrintHex<uint8_t>(readBuf[i], 0x80); PrintHex<uint8_t > (readBuf[i], 0x80);
Serial.print(" "); Serial.print(" ");
} }
Serial.println(); Serial.println();
@ -276,22 +276,22 @@ void XBOXUSB::printReport() { //Uncomment "#define PRINTREPORT" to print the rep
} }
uint8_t XBOXUSB::getButtonPress(Button b) { uint8_t XBOXUSB::getButtonPress(Button b) {
if(b == L2) // These are analog buttons if (b == L2) // These are analog buttons
return (uint8_t)(ButtonState >> 8); return (uint8_t)(ButtonState >> 8);
else if(b == R2) else if (b == R2)
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) {
L2Clicked = false; L2Clicked = false;
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];
} }
@ -309,8 +310,9 @@ int16_t XBOXUSB::getAnalogHat(AnalogHat a) {
/* Xbox Controller commands */ /* Xbox Controller commands */
void XBOXUSB::XboxCommand(uint8_t* data, uint16_t nbytes) { 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

@ -40,9 +40,9 @@ struct EpInfo {
uint8_t bmSndToggle : 1; // Send toggle, when zero bmSNDTOG0, bmSNDTOG1 otherwise uint8_t bmSndToggle : 1; // Send toggle, when zero bmSNDTOG0, bmSNDTOG1 otherwise
uint8_t bmRcvToggle : 1; // Send toggle, when zero bmRCVTOG0, bmRCVTOG1 otherwise uint8_t bmRcvToggle : 1; // Send toggle, when zero bmRCVTOG0, bmRCVTOG1 otherwise
uint8_t bmNakPower : 6; // Binary order for NAK_LIMIT value uint8_t bmNakPower : 6; // Binary order for NAK_LIMIT value
}__attribute__((packed)); } __attribute__((packed));
}; };
}__attribute__((packed)); } __attribute__((packed));
// 7 6 5 4 3 2 1 0 // 7 6 5 4 3 2 1 0
// --------------------------------- // ---------------------------------
@ -63,10 +63,10 @@ struct UsbDeviceAddress {
uint8_t bmParent : 3; // parent hub address uint8_t bmParent : 3; // parent hub address
uint8_t bmHub : 1; // hub flag uint8_t bmHub : 1; // hub flag
uint8_t bmReserved : 1; // reserved, must be zerro uint8_t bmReserved : 1; // reserved, must be zerro
}__attribute__((packed)); } __attribute__((packed));
uint8_t devAddress; uint8_t devAddress;
}; };
}__attribute__((packed)); } __attribute__((packed));
#define bmUSB_DEV_ADDR_ADDRESS 0x07 #define bmUSB_DEV_ADDR_ADDRESS 0x07
#define bmUSB_DEV_ADDR_PARENT 0x38 #define bmUSB_DEV_ADDR_PARENT 0x38
@ -78,7 +78,7 @@ struct UsbDevice {
uint8_t epcount; // number of endpoints uint8_t epcount; // number of endpoints
bool lowspeed; // indicates if a device is the low speed one bool lowspeed; // indicates if a device is the low speed one
// uint8_t devclass; // device class // uint8_t devclass; // device class
}__attribute__((packed)); } __attribute__((packed));
class AddressPool { class AddressPool {
public: public:
@ -112,8 +112,8 @@ class AddressPoolImpl : public AddressPool {
// Returns thePool index for a given address // Returns thePool index for a given address
uint8_t FindAddressIndex(uint8_t address = 0) { uint8_t FindAddressIndex(uint8_t address = 0) {
for (uint8_t i = 1; i < MAX_DEVICES_ALLOWED; i++) { for(uint8_t i = 1; i < MAX_DEVICES_ALLOWED; i++) {
if (thePool[i].address == address) if(thePool[i].address == address)
return i; return i;
} }
return 0; return 0;
@ -121,8 +121,8 @@ class AddressPoolImpl : public AddressPool {
// Returns thePool child index for a given parent // Returns thePool child index for a given parent
uint8_t FindChildIndex(UsbDeviceAddress addr, uint8_t start = 1) { uint8_t FindChildIndex(UsbDeviceAddress addr, uint8_t start = 1) {
for (uint8_t i = (start < 1 || start >= MAX_DEVICES_ALLOWED) ? 1 : start; i < MAX_DEVICES_ALLOWED; i++) { for(uint8_t i = (start < 1 || start >= MAX_DEVICES_ALLOWED) ? 1 : start; i < MAX_DEVICES_ALLOWED; i++) {
if (((UsbDeviceAddress*) & thePool[i].address)->bmParent == addr.bmAddress) if(((UsbDeviceAddress*) & thePool[i].address)->bmParent == addr.bmAddress)
return i; return i;
} }
return 0; return 0;
@ -131,16 +131,16 @@ class AddressPoolImpl : public AddressPool {
void FreeAddressByIndex(uint8_t index) { void FreeAddressByIndex(uint8_t index) {
// Zerro field is reserved and should not be affected // Zerro field is reserved and should not be affected
if (index == 0) if(index == 0)
return; return;
// If a hub was switched off all port addresses should be freed // If a hub was switched off all port addresses should be freed
if (((UsbDeviceAddress*) & thePool[index].address)->bmHub == 1) { if(((UsbDeviceAddress*) & thePool[index].address)->bmHub == 1) {
for (uint8_t i = 1; (i = FindChildIndex(*((UsbDeviceAddress*) & thePool[index].address), i));) for(uint8_t i = 1; (i = FindChildIndex(*((UsbDeviceAddress*) & thePool[index].address), i));)
FreeAddressByIndex(i); FreeAddressByIndex(i);
// If the hub had the last allocated address, hubCounter should be decremented // If the hub had the last allocated address, hubCounter should be decremented
if (hubCounter == ((UsbDeviceAddress*) & thePool[index].address)->bmAddress) if(hubCounter == ((UsbDeviceAddress*) & thePool[index].address)->bmAddress)
hubCounter--; hubCounter--;
} }
InitEntry(index); InitEntry(index);
@ -148,7 +148,7 @@ class AddressPoolImpl : public AddressPool {
// Initializes the whole address pool at once // Initializes the whole address pool at once
void InitAllAddresses() { void InitAllAddresses() {
for (uint8_t i = 1; i < MAX_DEVICES_ALLOWED; i++) for(uint8_t i = 1; i < MAX_DEVICES_ALLOWED; i++)
InitEntry(i); InitEntry(i);
hubCounter = 0; hubCounter = 0;
@ -172,22 +172,22 @@ public:
// Returns a pointer to a specified address entry // Returns a pointer to a specified address entry
virtual UsbDevice* GetUsbDevicePtr(uint8_t addr) { virtual UsbDevice* GetUsbDevicePtr(uint8_t addr) {
if (!addr) if(!addr)
return thePool; return thePool;
uint8_t index = FindAddressIndex(addr); uint8_t index = FindAddressIndex(addr);
return (!index) ? NULL : thePool + index; return(!index) ? NULL : thePool + index;
}; };
// Performs an operation specified by pfunc for each addressed device // Performs an operation specified by pfunc for each addressed device
void ForEachUsbDevice(UsbDeviceHandleFunc pfunc) { void ForEachUsbDevice(UsbDeviceHandleFunc pfunc) {
if (!pfunc) if(!pfunc)
return; return;
for (uint8_t i = 1; i < MAX_DEVICES_ALLOWED; i++) for(uint8_t i = 1; i < MAX_DEVICES_ALLOWED; i++)
if (thePool[i].address) if(thePool[i].address)
pfunc(thePool + i); pfunc(thePool + i);
}; };
// Allocates new address // Allocates new address
@ -196,20 +196,20 @@ public:
/* if (parent != 0 && port == 0) /* if (parent != 0 && port == 0)
Serial.println("PRT:0"); */ Serial.println("PRT:0"); */
if (parent > 127 || port > 7) if(parent > 127 || port > 7)
return 0; return 0;
if (is_hub && hubCounter == 7) if(is_hub && hubCounter == 7)
return 0; return 0;
// finds first empty address entry starting from one // finds first empty address entry starting from one
uint8_t index = FindAddressIndex(0); uint8_t index = FindAddressIndex(0);
if (!index) // if empty entry is not found if(!index) // if empty entry is not found
return 0; return 0;
if (parent == 0) { if(parent == 0) {
if (is_hub) { if(is_hub) {
thePool[index].address = 0x41; thePool[index].address = 0x41;
hubCounter++; hubCounter++;
} else } else
@ -222,7 +222,7 @@ public:
addr.bmParent = ((UsbDeviceAddress*) & parent)->bmAddress; addr.bmParent = ((UsbDeviceAddress*) & parent)->bmAddress;
if (is_hub) { if(is_hub) {
addr.bmHub = 1; addr.bmHub = 1;
addr.bmAddress = ++hubCounter; addr.bmAddress = ++hubCounter;
} else { } else {
@ -244,7 +244,7 @@ public:
virtual void FreeAddress(uint8_t addr) { virtual void FreeAddress(uint8_t addr) {
// if the root hub is disconnected all the addresses should be initialized // if the root hub is disconnected all the addresses should be initialized
if (addr == 0x41) { if(addr == 0x41) {
InitAllAddresses(); InitAllAddresses();
return; return;
} }

15
adk.cpp
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;
@ -101,7 +100,7 @@ uint8_t ADK::Init(uint8_t parent, uint8_t port, bool lowspeed) {
p->lowspeed = lowspeed; p->lowspeed = lowspeed;
// Get device descriptor // Get device descriptor
rcode = pUsb->getDevDescr(0, 0, sizeof (USB_DEVICE_DESCRIPTOR), (uint8_t*) buf); rcode = pUsb->getDevDescr(0, 0, sizeof (USB_DEVICE_DESCRIPTOR), (uint8_t*)buf);
// Restore p->epinfo // Restore p->epinfo
p->epinfo = oldep_ptr; p->epinfo = oldep_ptr;
@ -114,7 +113,7 @@ uint8_t ADK::Init(uint8_t parent, uint8_t port, bool lowspeed) {
bAddress = addrPool.AllocAddress(parent, false, port); bAddress = addrPool.AllocAddress(parent, false, port);
// Extract Max Packet Size from device descriptor // Extract Max Packet Size from device descriptor
epInfo[0].maxPktSize = (uint8_t) ((USB_DEVICE_DESCRIPTOR*) buf)->bMaxPacketSize0; epInfo[0].maxPktSize = (uint8_t)((USB_DEVICE_DESCRIPTOR*)buf)->bMaxPacketSize0;
// Assign new address to the device // Assign new address to the device
rcode = pUsb->setAddr(0, 0, bAddress); rcode = pUsb->setAddr(0, 0, bAddress);
@ -145,11 +144,11 @@ uint8_t ADK::Init(uint8_t parent, uint8_t port, bool lowspeed) {
} }
//check if ADK device is already in accessory mode; if yes, configure and exit //check if ADK device is already in accessory mode; if yes, configure and exit
if (((USB_DEVICE_DESCRIPTOR*) buf)->idVendor == ADK_VID && if (((USB_DEVICE_DESCRIPTOR*)buf)->idVendor == ADK_VID &&
(((USB_DEVICE_DESCRIPTOR*) buf)->idProduct == ADK_PID || ((USB_DEVICE_DESCRIPTOR*) buf)->idProduct == ADB_PID)) { (((USB_DEVICE_DESCRIPTOR*)buf)->idProduct == ADK_PID || ((USB_DEVICE_DESCRIPTOR*)buf)->idProduct == ADB_PID)) {
USBTRACE("\r\nAcc.mode device detected"); USBTRACE("\r\nAcc.mode device detected");
/* go through configurations, find first bulk-IN, bulk-OUT EP, fill epInfo and quit */ /* go through configurations, find first bulk-IN, bulk-OUT EP, fill epInfo and quit */
num_of_conf = ((USB_DEVICE_DESCRIPTOR*) buf)->bNumConfigurations; num_of_conf = ((USB_DEVICE_DESCRIPTOR*)buf)->bNumConfigurations;
//USBTRACE2("\r\nNC:",num_of_conf); //USBTRACE2("\r\nNC:",num_of_conf);
@ -286,7 +285,7 @@ void ADK::EndpointXtract(uint8_t conf, uint8_t iface, uint8_t alt, uint8_t proto
// Fill in the endpoint info structure // Fill in the endpoint info structure
epInfo[index].epAddr = (pep->bEndpointAddress & 0x0F); epInfo[index].epAddr = (pep->bEndpointAddress & 0x0F);
epInfo[index].maxPktSize = (uint8_t) pep->wMaxPacketSize; epInfo[index].maxPktSize = (uint8_t)pep->wMaxPacketSize;
bNumEP++; bNumEP++;

6
adk.h
View file

@ -133,17 +133,17 @@ public:
/* returns 2 bytes in *adkproto */ /* returns 2 bytes in *adkproto */
inline uint8_t ADK::getProto(uint8_t* adkproto) { inline uint8_t ADK::getProto(uint8_t* adkproto) {
return ( pUsb->ctrlReq(bAddress, 0, bmREQ_ADK_GET, ADK_GETPROTO, 0, 0, 0, 2, 2, adkproto, NULL)); return( pUsb->ctrlReq(bAddress, 0, bmREQ_ADK_GET, ADK_GETPROTO, 0, 0, 0, 2, 2, adkproto, NULL));
} }
/* send ADK string */ /* send ADK string */
inline uint8_t ADK::sendStr(uint8_t index, const char* str) { inline uint8_t ADK::sendStr(uint8_t index, const char* str) {
return ( pUsb->ctrlReq(bAddress, 0, bmREQ_ADK_SEND, ADK_SENDSTR, 0, 0, index, strlen(str) + 1, strlen(str) + 1, (uint8_t*) str, NULL)); return( pUsb->ctrlReq(bAddress, 0, bmREQ_ADK_SEND, ADK_SENDSTR, 0, 0, index, strlen(str) + 1, strlen(str) + 1, (uint8_t*) str, NULL));
} }
/* switch to accessory mode */ /* switch to accessory mode */
inline uint8_t ADK::switchAcc(void) { inline uint8_t ADK::switchAcc(void) {
return ( pUsb->ctrlReq(bAddress, 0, bmREQ_ADK_SEND, ADK_ACCSTART, 0, 0, 0, 0, 0, NULL, NULL)); return( pUsb->ctrlReq(bAddress, 0, bmREQ_ADK_SEND, ADK_ACCSTART, 0, 0, 0, 0, 0, NULL, NULL));
} }
#endif // _ADK_H_ #endif // _ADK_H_

View file

@ -178,13 +178,13 @@ public:
} }
static void Set(uint8_t val) { static void Set(uint8_t val) {
if (val) if(val)
Set(); Set();
else Clear(); else Clear();
} }
static void SetDir(uint8_t val) { static void SetDir(uint8_t val) {
if (val) if(val)
SetDirWrite(); SetDirWrite();
else SetDirRead(); else SetDirRead();
} }
@ -210,12 +210,12 @@ public:
} }
static void WaiteForSet() { static void WaiteForSet() {
while (IsSet() == 0) { while(IsSet() == 0) {
} }
} }
static void WaiteForClear() { static void WaiteForClear() {
while (IsSet()) { while(IsSet()) {
} }
} }
}; //class TPin... }; //class TPin...
@ -411,7 +411,7 @@ class Tp_Tc {
public: public:
static void SetDir(uint8_t val) { static void SetDir(uint8_t val) {
if (val) if(val)
SetDirWrite(); SetDirWrite();
else SetDirRead(); else SetDirRead();
} }

View file

@ -79,7 +79,7 @@ uint8_t ACM::Init(uint8_t parent, uint8_t port, bool lowspeed) {
p->lowspeed = lowspeed; p->lowspeed = lowspeed;
// Get device descriptor // Get device descriptor
rcode = pUsb->getDevDescr(0, 0, constBufSize, (uint8_t*) buf); rcode = pUsb->getDevDescr(0, 0, constBufSize, (uint8_t*)buf);
// Restore p->epinfo // Restore p->epinfo
p->epinfo = oldep_ptr; p->epinfo = oldep_ptr;
@ -94,7 +94,7 @@ uint8_t ACM::Init(uint8_t parent, uint8_t port, bool lowspeed) {
return USB_ERROR_OUT_OF_ADDRESS_SPACE_IN_POOL; return USB_ERROR_OUT_OF_ADDRESS_SPACE_IN_POOL;
// Extract Max Packet Size from the device descriptor // Extract Max Packet Size from the device descriptor
epInfo[0].maxPktSize = (uint8_t) ((USB_DEVICE_DESCRIPTOR*) buf)->bMaxPacketSize0; epInfo[0].maxPktSize = (uint8_t)((USB_DEVICE_DESCRIPTOR*)buf)->bMaxPacketSize0;
// Assign new address to the device // Assign new address to the device
rcode = pUsb->setAddr(0, 0, bAddress); rcode = pUsb->setAddr(0, 0, bAddress);
@ -118,7 +118,7 @@ uint8_t ACM::Init(uint8_t parent, uint8_t port, bool lowspeed) {
p->lowspeed = lowspeed; p->lowspeed = lowspeed;
num_of_conf = ((USB_DEVICE_DESCRIPTOR*) buf)->bNumConfigurations; num_of_conf = ((USB_DEVICE_DESCRIPTOR*)buf)->bNumConfigurations;
// Assign epInfo to epinfo pointer // Assign epInfo to epinfo pointer
rcode = pUsb->setEpInfoEntry(bAddress, 1, epInfo); rcode = pUsb->setEpInfoEntry(bAddress, 1, epInfo);
@ -226,7 +226,7 @@ void ACM::EndpointXtract(uint8_t conf, uint8_t iface, uint8_t alt, uint8_t proto
// Fill in the endpoint info structure // Fill in the endpoint info structure
epInfo[index].epAddr = (pep->bEndpointAddress & 0x0F); epInfo[index].epAddr = (pep->bEndpointAddress & 0x0F);
epInfo[index].maxPktSize = (uint8_t) pep->wMaxPacketSize; epInfo[index].maxPktSize = (uint8_t)pep->wMaxPacketSize;
epInfo[index].epAttribs = 0; epInfo[index].epAttribs = 0;
bNumEP++; bNumEP++;
@ -304,11 +304,11 @@ uint8_t ACM::ClearCommFeature(uint16_t fid) {
} }
uint8_t ACM::SetLineCoding(const LINE_CODING *dataptr) { uint8_t ACM::SetLineCoding(const LINE_CODING *dataptr) {
return ( pUsb->ctrlReq(bAddress, 0, bmREQ_CDCOUT, CDC_SET_LINE_CODING, 0x00, 0x00, bControlIface, sizeof (LINE_CODING), sizeof (LINE_CODING), (uint8_t*) dataptr, NULL)); return ( pUsb->ctrlReq(bAddress, 0, bmREQ_CDCOUT, CDC_SET_LINE_CODING, 0x00, 0x00, bControlIface, sizeof (LINE_CODING), sizeof (LINE_CODING), (uint8_t*)dataptr, NULL));
} }
uint8_t ACM::GetLineCoding(LINE_CODING *dataptr) { uint8_t ACM::GetLineCoding(LINE_CODING *dataptr) {
return ( pUsb->ctrlReq(bAddress, 0, bmREQ_CDCIN, CDC_GET_LINE_CODING, 0x00, 0x00, bControlIface, sizeof (LINE_CODING), sizeof (LINE_CODING), (uint8_t*) dataptr, NULL)); return ( pUsb->ctrlReq(bAddress, 0, bmREQ_CDCIN, CDC_GET_LINE_CODING, 0x00, 0x00, bControlIface, sizeof (LINE_CODING), sizeof (LINE_CODING), (uint8_t*)dataptr, NULL));
} }
uint8_t ACM::SetControlLineState(uint8_t state) { uint8_t ACM::SetControlLineState(uint8_t state) {

View file

@ -78,7 +78,7 @@ uint8_t FTDI::Init(uint8_t parent, uint8_t port, bool lowspeed) {
p->lowspeed = lowspeed; p->lowspeed = lowspeed;
// Get device descriptor // Get device descriptor
rcode = pUsb->getDevDescr(0, 0, sizeof (USB_DEVICE_DESCRIPTOR), (uint8_t*) buf); rcode = pUsb->getDevDescr(0, 0, sizeof (USB_DEVICE_DESCRIPTOR), (uint8_t*)buf);
// Restore p->epinfo // Restore p->epinfo
p->epinfo = oldep_ptr; p->epinfo = oldep_ptr;
@ -86,11 +86,11 @@ uint8_t FTDI::Init(uint8_t parent, uint8_t port, bool lowspeed) {
if (rcode) if (rcode)
goto FailGetDevDescr; goto FailGetDevDescr;
if (((USB_DEVICE_DESCRIPTOR*) buf)->idVendor != FTDI_VID || ((USB_DEVICE_DESCRIPTOR*) buf)->idProduct != FTDI_PID) if (((USB_DEVICE_DESCRIPTOR*)buf)->idVendor != FTDI_VID || ((USB_DEVICE_DESCRIPTOR*)buf)->idProduct != FTDI_PID)
return USB_DEV_CONFIG_ERROR_DEVICE_NOT_SUPPORTED; return USB_DEV_CONFIG_ERROR_DEVICE_NOT_SUPPORTED;
// Save type of FTDI chip // Save type of FTDI chip
wFTDIType = ((USB_DEVICE_DESCRIPTOR*) buf)->bcdDevice; wFTDIType = ((USB_DEVICE_DESCRIPTOR*)buf)->bcdDevice;
// Allocate new address according to device class // Allocate new address according to device class
bAddress = addrPool.AllocAddress(parent, false, port); bAddress = addrPool.AllocAddress(parent, false, port);
@ -99,7 +99,7 @@ uint8_t FTDI::Init(uint8_t parent, uint8_t port, bool lowspeed) {
return USB_ERROR_OUT_OF_ADDRESS_SPACE_IN_POOL; return USB_ERROR_OUT_OF_ADDRESS_SPACE_IN_POOL;
// Extract Max Packet Size from the device descriptor // Extract Max Packet Size from the device descriptor
epInfo[0].maxPktSize = (uint8_t) ((USB_DEVICE_DESCRIPTOR*) buf)->bMaxPacketSize0; epInfo[0].maxPktSize = (uint8_t)((USB_DEVICE_DESCRIPTOR*)buf)->bMaxPacketSize0;
// Assign new address to the device // Assign new address to the device
rcode = pUsb->setAddr(0, 0, bAddress); rcode = pUsb->setAddr(0, 0, bAddress);
@ -123,7 +123,7 @@ uint8_t FTDI::Init(uint8_t parent, uint8_t port, bool lowspeed) {
p->lowspeed = lowspeed; p->lowspeed = lowspeed;
num_of_conf = ((USB_DEVICE_DESCRIPTOR*) buf)->bNumConfigurations; num_of_conf = ((USB_DEVICE_DESCRIPTOR*)buf)->bNumConfigurations;
// Assign epInfo to epinfo pointer // Assign epInfo to epinfo pointer
rcode = pUsb->setEpInfoEntry(bAddress, 1, epInfo); rcode = pUsb->setEpInfoEntry(bAddress, 1, epInfo);
@ -224,7 +224,7 @@ void FTDI::EndpointXtract(uint8_t conf, uint8_t iface, uint8_t alt, uint8_t prot
// Fill in the endpoint info structure // Fill in the endpoint info structure
epInfo[index].epAddr = (pep->bEndpointAddress & 0x0F); epInfo[index].epAddr = (pep->bEndpointAddress & 0x0F);
epInfo[index].maxPktSize = (uint8_t) pep->wMaxPacketSize; epInfo[index].maxPktSize = (uint8_t)pep->wMaxPacketSize;
epInfo[index].epAttribs = 0; epInfo[index].epAttribs = 0;
bNumEP++; bNumEP++;

View file

@ -57,7 +57,7 @@ uint8_t PL2303::Init(uint8_t parent, uint8_t port, bool lowspeed) {
p->lowspeed = lowspeed; p->lowspeed = lowspeed;
// Get device descriptor // Get device descriptor
rcode = pUsb->getDevDescr(0, 0, sizeof (USB_DEVICE_DESCRIPTOR), (uint8_t*) buf); rcode = pUsb->getDevDescr(0, 0, sizeof (USB_DEVICE_DESCRIPTOR), (uint8_t*)buf);
// Restore p->epinfo // Restore p->epinfo
p->epinfo = oldep_ptr; p->epinfo = oldep_ptr;
@ -65,11 +65,11 @@ uint8_t PL2303::Init(uint8_t parent, uint8_t port, bool lowspeed) {
if (rcode) if (rcode)
goto FailGetDevDescr; goto FailGetDevDescr;
if (((USB_DEVICE_DESCRIPTOR*) buf)->idVendor != PL_VID && ((USB_DEVICE_DESCRIPTOR*) buf)->idProduct != PL_PID) if (((USB_DEVICE_DESCRIPTOR*)buf)->idVendor != PL_VID && ((USB_DEVICE_DESCRIPTOR*)buf)->idProduct != PL_PID)
return USB_DEV_CONFIG_ERROR_DEVICE_NOT_SUPPORTED; return USB_DEV_CONFIG_ERROR_DEVICE_NOT_SUPPORTED;
// Save type of PL chip // Save type of PL chip
wPLType = ((USB_DEVICE_DESCRIPTOR*) buf)->bcdDevice; wPLType = ((USB_DEVICE_DESCRIPTOR*)buf)->bcdDevice;
// Allocate new address according to device class // Allocate new address according to device class
bAddress = addrPool.AllocAddress(parent, false, port); bAddress = addrPool.AllocAddress(parent, false, port);
@ -78,7 +78,7 @@ uint8_t PL2303::Init(uint8_t parent, uint8_t port, bool lowspeed) {
return USB_ERROR_OUT_OF_ADDRESS_SPACE_IN_POOL; return USB_ERROR_OUT_OF_ADDRESS_SPACE_IN_POOL;
// Extract Max Packet Size from the device descriptor // Extract Max Packet Size from the device descriptor
epInfo[0].maxPktSize = (uint8_t) ((USB_DEVICE_DESCRIPTOR*) buf)->bMaxPacketSize0; epInfo[0].maxPktSize = (uint8_t)((USB_DEVICE_DESCRIPTOR*)buf)->bMaxPacketSize0;
// Assign new address to the device // Assign new address to the device
rcode = pUsb->setAddr(0, 0, bAddress); rcode = pUsb->setAddr(0, 0, bAddress);
@ -102,7 +102,7 @@ uint8_t PL2303::Init(uint8_t parent, uint8_t port, bool lowspeed) {
p->lowspeed = lowspeed; p->lowspeed = lowspeed;
num_of_conf = ((USB_DEVICE_DESCRIPTOR*) buf)->bNumConfigurations; num_of_conf = ((USB_DEVICE_DESCRIPTOR*)buf)->bNumConfigurations;
// Assign epInfo to epinfo pointer // Assign epInfo to epinfo pointer
rcode = pUsb->setEpInfoEntry(bAddress, 1, epInfo); rcode = pUsb->setEpInfoEntry(bAddress, 1, epInfo);

View file

@ -85,8 +85,8 @@ void ConfigDescParser<CLASS_ID, SUBCLASS_ID, PROTOCOL_ID, MASK>::Parse(const uin
uint16_t cntdn = (uint16_t) len; uint16_t cntdn = (uint16_t) len;
uint8_t *p = (uint8_t*) pbuf; uint8_t *p = (uint8_t*) pbuf;
while (cntdn) while(cntdn)
if (!ParseDescriptor(&p, &cntdn)) if(!ParseDescriptor(&p, &cntdn))
return; return;
} }
@ -94,13 +94,13 @@ void ConfigDescParser<CLASS_ID, SUBCLASS_ID, PROTOCOL_ID, MASK>::Parse(const uin
compare masks for them. When the match is found, calls EndpointXtract passing buffer containing endpoint descriptor */ compare masks for them. When the match is found, calls EndpointXtract passing buffer containing endpoint descriptor */
template <const uint8_t CLASS_ID, const uint8_t SUBCLASS_ID, const uint8_t PROTOCOL_ID, const uint8_t MASK> template <const uint8_t CLASS_ID, const uint8_t SUBCLASS_ID, const uint8_t PROTOCOL_ID, const uint8_t MASK>
bool ConfigDescParser<CLASS_ID, SUBCLASS_ID, PROTOCOL_ID, MASK>::ParseDescriptor(uint8_t **pp, uint16_t *pcntdn) { bool ConfigDescParser<CLASS_ID, SUBCLASS_ID, PROTOCOL_ID, MASK>::ParseDescriptor(uint8_t **pp, uint16_t *pcntdn) {
switch (stateParseDescr) { switch(stateParseDescr) {
case 0: case 0:
theBuffer.valueSize = 2; theBuffer.valueSize = 2;
valParser.Initialize(&theBuffer); valParser.Initialize(&theBuffer);
stateParseDescr = 1; stateParseDescr = 1;
case 1: case 1:
if (!valParser.Parse(pp, pcntdn)) if(!valParser.Parse(pp, pcntdn))
return false; return false;
dscrLen = *((uint8_t*) theBuffer.pValue); dscrLen = *((uint8_t*) theBuffer.pValue);
dscrType = *((uint8_t*) theBuffer.pValue + 1); dscrType = *((uint8_t*) theBuffer.pValue + 1);
@ -114,14 +114,14 @@ bool ConfigDescParser<CLASS_ID, SUBCLASS_ID, PROTOCOL_ID, MASK>::ParseDescriptor
theBuffer.pValue = varBuffer + 2; theBuffer.pValue = varBuffer + 2;
stateParseDescr = 3; stateParseDescr = 3;
case 3: case 3:
switch (dscrType) { switch(dscrType) {
case USB_DESCRIPTOR_INTERFACE: case USB_DESCRIPTOR_INTERFACE:
isGoodInterface = false; isGoodInterface = false;
case USB_DESCRIPTOR_CONFIGURATION: case USB_DESCRIPTOR_CONFIGURATION:
theBuffer.valueSize = sizeof (USB_CONFIGURATION_DESCRIPTOR) - 2; theBuffer.valueSize = sizeof(USB_CONFIGURATION_DESCRIPTOR) - 2;
break; break;
case USB_DESCRIPTOR_ENDPOINT: case USB_DESCRIPTOR_ENDPOINT:
theBuffer.valueSize = sizeof (USB_ENDPOINT_DESCRIPTOR) - 2; theBuffer.valueSize = sizeof(USB_ENDPOINT_DESCRIPTOR) - 2;
break; break;
case HID_DESCRIPTOR_HID: case HID_DESCRIPTOR_HID:
theBuffer.valueSize = dscrLen - 2; theBuffer.valueSize = dscrLen - 2;
@ -130,20 +130,20 @@ bool ConfigDescParser<CLASS_ID, SUBCLASS_ID, PROTOCOL_ID, MASK>::ParseDescriptor
valParser.Initialize(&theBuffer); valParser.Initialize(&theBuffer);
stateParseDescr = 4; stateParseDescr = 4;
case 4: case 4:
switch (dscrType) { switch(dscrType) {
case USB_DESCRIPTOR_CONFIGURATION: case USB_DESCRIPTOR_CONFIGURATION:
if (!valParser.Parse(pp, pcntdn)) if(!valParser.Parse(pp, pcntdn))
return false; return false;
confValue = ((USB_CONFIGURATION_DESCRIPTOR*) varBuffer)->bConfigurationValue; confValue = ((USB_CONFIGURATION_DESCRIPTOR*) varBuffer)->bConfigurationValue;
break; break;
case USB_DESCRIPTOR_INTERFACE: case USB_DESCRIPTOR_INTERFACE:
if (!valParser.Parse(pp, pcntdn)) if(!valParser.Parse(pp, pcntdn))
return false; return false;
if ((MASK & CP_MASK_COMPARE_CLASS) && ((USB_INTERFACE_DESCRIPTOR*) varBuffer)->bInterfaceClass != CLASS_ID) if((MASK & CP_MASK_COMPARE_CLASS) && ((USB_INTERFACE_DESCRIPTOR*) varBuffer)->bInterfaceClass != CLASS_ID)
break; break;
if ((MASK & CP_MASK_COMPARE_SUBCLASS) && ((USB_INTERFACE_DESCRIPTOR*) varBuffer)->bInterfaceSubClass != SUBCLASS_ID) if((MASK & CP_MASK_COMPARE_SUBCLASS) && ((USB_INTERFACE_DESCRIPTOR*) varBuffer)->bInterfaceSubClass != SUBCLASS_ID)
break; break;
if ((MASK & CP_MASK_COMPARE_PROTOCOL) && ((USB_INTERFACE_DESCRIPTOR*) varBuffer)->bInterfaceProtocol != PROTOCOL_ID) if((MASK & CP_MASK_COMPARE_PROTOCOL) && ((USB_INTERFACE_DESCRIPTOR*) varBuffer)->bInterfaceProtocol != PROTOCOL_ID)
break; break;
isGoodInterface = true; isGoodInterface = true;
@ -152,10 +152,10 @@ bool ConfigDescParser<CLASS_ID, SUBCLASS_ID, PROTOCOL_ID, MASK>::ParseDescriptor
protoValue = ((USB_INTERFACE_DESCRIPTOR*) varBuffer)->bInterfaceProtocol; protoValue = ((USB_INTERFACE_DESCRIPTOR*) varBuffer)->bInterfaceProtocol;
break; break;
case USB_DESCRIPTOR_ENDPOINT: case USB_DESCRIPTOR_ENDPOINT:
if (!valParser.Parse(pp, pcntdn)) if(!valParser.Parse(pp, pcntdn))
return false; return false;
if (isGoodInterface) if(isGoodInterface)
if (theXtractor) if(theXtractor)
theXtractor->EndpointXtract(confValue, ifaceNumber, ifaceAltSet, protoValue, (USB_ENDPOINT_DESCRIPTOR*) varBuffer); theXtractor->EndpointXtract(confValue, ifaceNumber, ifaceAltSet, protoValue, (USB_ENDPOINT_DESCRIPTOR*) varBuffer);
break; break;
//case HID_DESCRIPTOR_HID: //case HID_DESCRIPTOR_HID:
@ -164,7 +164,7 @@ bool ConfigDescParser<CLASS_ID, SUBCLASS_ID, PROTOCOL_ID, MASK>::ParseDescriptor
// PrintHidDescriptor((const USB_HID_DESCRIPTOR*)varBuffer); // PrintHidDescriptor((const USB_HID_DESCRIPTOR*)varBuffer);
// break; // break;
default: default:
if (!theSkipper.Skip(pp, pcntdn, dscrLen - 2)) if(!theSkipper.Skip(pp, pcntdn, dscrLen - 2))
return false; return false;
} }
theBuffer.pValue = varBuffer; theBuffer.pValue = varBuffer;
@ -197,7 +197,7 @@ void ConfigDescParser<CLASS_ID, SUBCLASS_ID, PROTOCOL_ID, MASK>::PrintHidDescrip
//Notify(PSTR("\r\nwDescriptorLength:\t")); //Notify(PSTR("\r\nwDescriptorLength:\t"));
//PrintHex<uint16_t>(pDesc->wDescriptorLength); //PrintHex<uint16_t>(pDesc->wDescriptorLength);
for (uint8_t i = 0; i < pDesc->bNumDescriptors; i++) { for(uint8_t i = 0; i < pDesc->bNumDescriptors; i++) {
HID_CLASS_DESCRIPTOR_LEN_AND_TYPE *pLT = (HID_CLASS_DESCRIPTOR_LEN_AND_TYPE*)&(pDesc->bDescrType); HID_CLASS_DESCRIPTOR_LEN_AND_TYPE *pLT = (HID_CLASS_DESCRIPTOR_LEN_AND_TYPE*)&(pDesc->bDescrType);
Notify(PSTR("\r\nbDescrType:\t\t"), 0x80); Notify(PSTR("\r\nbDescrType:\t\t"), 0x80);

View file

@ -21,7 +21,7 @@
/* /*
This header file is used to store different enums for the controllers, This header file is used to store different enums for the controllers,
This is necessary so all the different libraries can be used at once This is necessary so all the different libraries can be used at once
*/ */
/** Enum used to turn on the LEDs on the different controllers. */ /** Enum used to turn on the LEDs on the different controllers. */
enum LED { enum LED {
@ -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 */

View file

@ -41,15 +41,15 @@ public:
template <class BASE_CLASS, class LEN_TYPE, class OFFSET_TYPE> template <class BASE_CLASS, class LEN_TYPE, class OFFSET_TYPE>
void HexDumper<BASE_CLASS, LEN_TYPE, OFFSET_TYPE>::Parse(const LEN_TYPE len, const uint8_t *pbuf, const OFFSET_TYPE &offset) { void HexDumper<BASE_CLASS, LEN_TYPE, OFFSET_TYPE>::Parse(const LEN_TYPE len, const uint8_t *pbuf, const OFFSET_TYPE &offset) {
for (LEN_TYPE j = 0; j < len; j++, byteCount++, byteTotal++) { for(LEN_TYPE j = 0; j < len; j++, byteCount++, byteTotal++) {
if (!byteCount) { if(!byteCount) {
SerialPrintHex<OFFSET_TYPE > (byteTotal); SerialPrintHex<OFFSET_TYPE > (byteTotal);
Serial.print(": "); Serial.print(": ");
} }
SerialPrintHex<uint8_t > (pbuf[j]); SerialPrintHex<uint8_t > (pbuf[j]);
Serial.print(" "); Serial.print(" ");
if (byteCount == 15) { if(byteCount == 15) {
Serial.println(""); Serial.println("");
byteCount = 0xFF; byteCount = 0xFF;
} }

View file

@ -7,7 +7,7 @@ uint8_t HID::GetReportDescr(uint8_t ep, USBReadParser *parser) {
uint8_t buf[constBufLen]; uint8_t buf[constBufLen];
uint8_t rcode = pUsb->ctrlReq(bAddress, ep, bmREQ_HIDREPORT, USB_REQUEST_GET_DESCRIPTOR, 0x00, uint8_t rcode = pUsb->ctrlReq(bAddress, ep, bmREQ_HIDREPORT, USB_REQUEST_GET_DESCRIPTOR, 0x00,
HID_DESCRIPTOR_REPORT, 0x0000, 128, constBufLen, buf, (USBReadParser*) parser); HID_DESCRIPTOR_REPORT, 0x0000, 128, constBufLen, buf, (USBReadParser*)parser);
//return ((rcode != hrSTALL) ? rcode : 0); //return ((rcode != hrSTALL) ? rcode : 0);
return rcode; return rcode;

View file

@ -17,7 +17,7 @@ e-mail : support@circuitsathome.com
#include "hidboot.h" #include "hidboot.h"
void MouseReportParser::Parse(HID *hid, bool is_rpt_id, uint8_t len, uint8_t *buf) { void MouseReportParser::Parse(HID *hid, bool is_rpt_id, uint8_t len, uint8_t *buf) {
MOUSEINFO *pmi = (MOUSEINFO*) buf; MOUSEINFO *pmi = (MOUSEINFO*)buf;
if (prevState.mouseInfo.bmLeftButton == 0 && pmi->bmLeftButton == 1) if (prevState.mouseInfo.bmLeftButton == 0 && pmi->bmLeftButton == 1)
OnLeftButtonDown(pmi); OnLeftButtonDown(pmi);
@ -112,20 +112,20 @@ uint8_t KeyboardReportParser::OemToAscii(uint8_t mod, uint8_t key) {
// Lower case letters // Lower case letters
else else
return (key - 4 + 'a'); return (key - 4 + 'a');
} // Numbers }// Numbers
else if (key > 0x1d && key < 0x27) { else if (key > 0x1d && key < 0x27) {
if (shift) if (shift)
return ((uint8_t) pgm_read_byte(&numKeys[key - 0x1e])); return ((uint8_t)pgm_read_byte(&numKeys[key - 0x1e]));
else else
return (key - 0x1e + '1'); return (key - 0x1e + '1');
} // Keypad Numbers }// Keypad Numbers
else if (key > 0x58 && key < 0x62) { else if (key > 0x58 && key < 0x62) {
if (kbdLockingKeys.kbdLeds.bmNumLock == 1) if (kbdLockingKeys.kbdLeds.bmNumLock == 1)
return (key - 0x59 + '1'); return (key - 0x59 + '1');
} else if (key > 0x2c && key < 0x39) } else if (key > 0x2c && key < 0x39)
return ((shift) ? (uint8_t) pgm_read_byte(&symKeysUp[key - 0x2d]) : (uint8_t) pgm_read_byte(&symKeysLo[key - 0x2d])); return ((shift) ? (uint8_t)pgm_read_byte(&symKeysUp[key - 0x2d]) : (uint8_t)pgm_read_byte(&symKeysLo[key - 0x2d]));
else if (key > 0x53 && key < 0x59) else if (key > 0x53 && key < 0x59)
return (uint8_t) pgm_read_byte(&padKeys[key - 0x54]); return (uint8_t)pgm_read_byte(&padKeys[key - 0x54]);
else { else {
switch (key) { switch (key) {
case KEY_SPACE: return (0x20); case KEY_SPACE: return (0x20);

View file

@ -60,7 +60,7 @@ class MouseReportParser : public HIDReportParser {
union { union {
MOUSEINFO mouseInfo; MOUSEINFO mouseInfo;
uint8_t bInfo[sizeof (MOUSEINFO)]; uint8_t bInfo[sizeof(MOUSEINFO)];
} prevState; } prevState;
public: public:
@ -140,7 +140,7 @@ protected:
union { union {
KBDINFO kbdInfo; KBDINFO kbdInfo;
uint8_t bInfo[sizeof (KBDINFO)]; uint8_t bInfo[sizeof(KBDINFO)];
} prevState; } prevState;
union { union {
@ -221,13 +221,13 @@ bPollEnable(false),
pRptParser(NULL) { pRptParser(NULL) {
Initialize(); Initialize();
if (pUsb) if(pUsb)
pUsb->RegisterDeviceClass(this); pUsb->RegisterDeviceClass(this);
} }
template <const uint8_t BOOT_PROTOCOL> template <const uint8_t BOOT_PROTOCOL>
void HIDBoot<BOOT_PROTOCOL>::Initialize() { void HIDBoot<BOOT_PROTOCOL>::Initialize() {
for (uint8_t i = 0; i < totalEndpoints; i++) { for(uint8_t i = 0; i < totalEndpoints; i++) {
epInfo[i].epAddr = 0; epInfo[i].epAddr = 0;
epInfo[i].maxPktSize = (i) ? 0 : 8; epInfo[i].maxPktSize = (i) ? 0 : 8;
epInfo[i].epAttribs = 0; epInfo[i].epAttribs = 0;
@ -240,7 +240,7 @@ void HIDBoot<BOOT_PROTOCOL>::Initialize() {
template <const uint8_t BOOT_PROTOCOL> template <const uint8_t BOOT_PROTOCOL>
uint8_t HIDBoot<BOOT_PROTOCOL>::Init(uint8_t parent, uint8_t port, bool lowspeed) { uint8_t HIDBoot<BOOT_PROTOCOL>::Init(uint8_t parent, uint8_t port, bool lowspeed) {
const uint8_t constBufSize = sizeof (USB_DEVICE_DESCRIPTOR); const uint8_t constBufSize = sizeof(USB_DEVICE_DESCRIPTOR);
uint8_t buf[constBufSize]; uint8_t buf[constBufSize];
uint8_t rcode; uint8_t rcode;
@ -256,16 +256,16 @@ uint8_t HIDBoot<BOOT_PROTOCOL>::Init(uint8_t parent, uint8_t port, bool lowspeed
USBTRACE("BM Init\r\n"); USBTRACE("BM Init\r\n");
if (bAddress) if(bAddress)
return USB_ERROR_CLASS_INSTANCE_ALREADY_IN_USE; return USB_ERROR_CLASS_INSTANCE_ALREADY_IN_USE;
// Get pointer to pseudo device with address 0 assigned // Get pointer to pseudo device with address 0 assigned
p = addrPool.GetUsbDevicePtr(0); p = addrPool.GetUsbDevicePtr(0);
if (!p) if(!p)
return USB_ERROR_ADDRESS_NOT_FOUND_IN_POOL; return USB_ERROR_ADDRESS_NOT_FOUND_IN_POOL;
if (!p->epinfo) { if(!p->epinfo) {
USBTRACE("epinfo\r\n"); USBTRACE("epinfo\r\n");
return USB_ERROR_EPINFO_IS_NULL; return USB_ERROR_EPINFO_IS_NULL;
} }
@ -281,10 +281,10 @@ uint8_t HIDBoot<BOOT_PROTOCOL>::Init(uint8_t parent, uint8_t port, bool lowspeed
// Get device descriptor // Get device descriptor
rcode = pUsb->getDevDescr(0, 0, 8, (uint8_t*) buf); rcode = pUsb->getDevDescr(0, 0, 8, (uint8_t*) buf);
if (!rcode) if(!rcode)
len = (buf[0] > constBufSize) ? constBufSize : buf[0]; len = (buf[0] > constBufSize) ? constBufSize : buf[0];
if (rcode) { if(rcode) {
// Restore p->epinfo // Restore p->epinfo
p->epinfo = oldep_ptr; p->epinfo = oldep_ptr;
@ -297,7 +297,7 @@ uint8_t HIDBoot<BOOT_PROTOCOL>::Init(uint8_t parent, uint8_t port, bool lowspeed
// Allocate new address according to device class // Allocate new address according to device class
bAddress = addrPool.AllocAddress(parent, false, port); bAddress = addrPool.AllocAddress(parent, false, port);
if (!bAddress) if(!bAddress)
return USB_ERROR_OUT_OF_ADDRESS_SPACE_IN_POOL; return USB_ERROR_OUT_OF_ADDRESS_SPACE_IN_POOL;
// Extract Max Packet Size from the device descriptor // Extract Max Packet Size from the device descriptor
@ -306,7 +306,7 @@ uint8_t HIDBoot<BOOT_PROTOCOL>::Init(uint8_t parent, uint8_t port, bool lowspeed
// Assign new address to the device // Assign new address to the device
rcode = pUsb->setAddr(0, 0, bAddress); rcode = pUsb->setAddr(0, 0, bAddress);
if (rcode) { if(rcode) {
p->lowspeed = false; p->lowspeed = false;
addrPool.FreeAddress(bAddress); addrPool.FreeAddress(bAddress);
bAddress = 0; bAddress = 0;
@ -320,15 +320,15 @@ uint8_t HIDBoot<BOOT_PROTOCOL>::Init(uint8_t parent, uint8_t port, bool lowspeed
p = addrPool.GetUsbDevicePtr(bAddress); p = addrPool.GetUsbDevicePtr(bAddress);
if (!p) if(!p)
return USB_ERROR_ADDRESS_NOT_FOUND_IN_POOL; return USB_ERROR_ADDRESS_NOT_FOUND_IN_POOL;
p->lowspeed = lowspeed; p->lowspeed = lowspeed;
if (len) if(len)
rcode = pUsb->getDevDescr(bAddress, 0, len, (uint8_t*) buf); rcode = pUsb->getDevDescr(bAddress, 0, len, (uint8_t*) buf);
if (rcode) if(rcode)
goto FailGetDevDescr; goto FailGetDevDescr;
num_of_conf = ((USB_DEVICE_DESCRIPTOR*) buf)->bNumConfigurations; num_of_conf = ((USB_DEVICE_DESCRIPTOR*) buf)->bNumConfigurations;
@ -336,12 +336,12 @@ uint8_t HIDBoot<BOOT_PROTOCOL>::Init(uint8_t parent, uint8_t port, bool lowspeed
// Assign epInfo to epinfo pointer // Assign epInfo to epinfo pointer
rcode = pUsb->setEpInfoEntry(bAddress, 1, epInfo); rcode = pUsb->setEpInfoEntry(bAddress, 1, epInfo);
if (rcode) if(rcode)
goto FailSetDevTblEntry; goto FailSetDevTblEntry;
//USBTRACE2("NC:", num_of_conf); //USBTRACE2("NC:", num_of_conf);
for (uint8_t i = 0; i < num_of_conf; i++) { for(uint8_t i = 0; i < num_of_conf; i++) {
ConfigDescParser< ConfigDescParser<
USB_CLASS_HID, USB_CLASS_HID,
HID_BOOT_INTF_SUBCLASS, HID_BOOT_INTF_SUBCLASS,
@ -350,11 +350,11 @@ uint8_t HIDBoot<BOOT_PROTOCOL>::Init(uint8_t parent, uint8_t port, bool lowspeed
rcode = pUsb->getConfDescr(bAddress, 0, i, &confDescrParser); rcode = pUsb->getConfDescr(bAddress, 0, i, &confDescrParser);
if (bNumEP > 1) if(bNumEP > 1)
break; break;
} // for } // for
if (bNumEP < 2) if(bNumEP < 2)
return USB_DEV_CONFIG_ERROR_DEVICE_NOT_SUPPORTED; return USB_DEV_CONFIG_ERROR_DEVICE_NOT_SUPPORTED;
//USBTRACE2("\r\nbAddr:", bAddress); //USBTRACE2("\r\nbAddr:", bAddress);
@ -368,20 +368,20 @@ uint8_t HIDBoot<BOOT_PROTOCOL>::Init(uint8_t parent, uint8_t port, bool lowspeed
// Set Configuration Value // Set Configuration Value
rcode = pUsb->setConf(bAddress, 0, bConfNum); rcode = pUsb->setConf(bAddress, 0, bConfNum);
if (rcode) if(rcode)
goto FailSetConfDescr; goto FailSetConfDescr;
//USBTRACE2("\r\nIf:", bIfaceNum); //USBTRACE2("\r\nIf:", bIfaceNum);
rcode = SetProtocol(bIfaceNum, HID_BOOT_PROTOCOL); rcode = SetProtocol(bIfaceNum, HID_BOOT_PROTOCOL);
if (rcode) if(rcode)
goto FailSetProtocol; goto FailSetProtocol;
if (BOOT_PROTOCOL == 1) { if(BOOT_PROTOCOL == 1) {
rcode = SetIdle(bIfaceNum, 0, 0); rcode = SetIdle(bIfaceNum, 0, 0);
if (rcode) if(rcode)
goto FailSetIdle; goto FailSetIdle;
} }
USBTRACE("BM configured\r\n"); USBTRACE("BM configured\r\n");
@ -424,7 +424,7 @@ Fail:
template <const uint8_t BOOT_PROTOCOL> template <const uint8_t BOOT_PROTOCOL>
void HIDBoot<BOOT_PROTOCOL>::EndpointXtract(uint8_t conf, uint8_t iface, uint8_t alt, uint8_t proto, const USB_ENDPOINT_DESCRIPTOR *pep) { void HIDBoot<BOOT_PROTOCOL>::EndpointXtract(uint8_t conf, uint8_t iface, uint8_t alt, uint8_t proto, const USB_ENDPOINT_DESCRIPTOR *pep) {
// If the first configuration satisfies, the others are not concidered. // If the first configuration satisfies, the others are not concidered.
if (bNumEP > 1 && conf != bConfNum) if(bNumEP > 1 && conf != bConfNum)
return; return;
bConfNum = conf; bConfNum = conf;
@ -432,7 +432,7 @@ void HIDBoot<BOOT_PROTOCOL>::EndpointXtract(uint8_t conf, uint8_t iface, uint8_t
uint8_t index; uint8_t index;
if ((pep->bmAttributes & 0x03) == 3 && (pep->bEndpointAddress & 0x80) == 0x80) { if((pep->bmAttributes & 0x03) == 3 && (pep->bEndpointAddress & 0x80) == 0x80) {
index = epInterruptInIndex; index = epInterruptInIndex;
// Fill in the endpoint info structure // Fill in the endpoint info structure
@ -461,10 +461,10 @@ template <const uint8_t BOOT_PROTOCOL>
uint8_t HIDBoot<BOOT_PROTOCOL>::Poll() { uint8_t HIDBoot<BOOT_PROTOCOL>::Poll() {
uint8_t rcode = 0; uint8_t rcode = 0;
if (!bPollEnable) if(!bPollEnable)
return 0; return 0;
if (qNextPollTime <= millis()) { if(qNextPollTime <= millis()) {
qNextPollTime = millis() + 10; qNextPollTime = millis() + 10;
const uint8_t const_buff_len = 16; const uint8_t const_buff_len = 16;
@ -474,8 +474,8 @@ uint8_t HIDBoot<BOOT_PROTOCOL>::Poll() {
uint8_t rcode = pUsb->inTransfer(bAddress, epInfo[epInterruptInIndex].epAddr, &read, buf); uint8_t rcode = pUsb->inTransfer(bAddress, epInfo[epInterruptInIndex].epAddr, &read, buf);
if (rcode) { if(rcode) {
if (rcode != hrNAK) if(rcode != hrNAK)
USBTRACE2("Poll:", rcode); USBTRACE2("Poll:", rcode);
return rcode; return rcode;
} }
@ -484,7 +484,7 @@ uint8_t HIDBoot<BOOT_PROTOCOL>::Poll() {
//if (read) //if (read)
// Serial.println(""); // Serial.println("");
if (pRptParser) if(pRptParser)
pRptParser->Parse((HID*)this, 0, (uint8_t) read, buf); pRptParser->Parse((HID*)this, 0, (uint8_t) read, buf);
} }
return rcode; return rcode;

View file

@ -1,6 +1,6 @@
#include "hidescriptorparser.h" #include "hidescriptorparser.h"
const char * const ReportDescParserBase::usagePageTitles0[] PROGMEM ={ const char * const ReportDescParserBase::usagePageTitles0[] PROGMEM = {
pstrUsagePageGenericDesktopControls, pstrUsagePageGenericDesktopControls,
pstrUsagePageSimulationControls, pstrUsagePageSimulationControls,
pstrUsagePageVRControls, pstrUsagePageVRControls,
@ -18,7 +18,7 @@ const char * const ReportDescParserBase::usagePageTitles0[] PROGMEM ={
pstrUsagePageUnicode pstrUsagePageUnicode
}; };
const char * const ReportDescParserBase::usagePageTitles1[] PROGMEM ={ const char * const ReportDescParserBase::usagePageTitles1[] PROGMEM = {
pstrUsagePageBarCodeScanner, pstrUsagePageBarCodeScanner,
pstrUsagePageScale, pstrUsagePageScale,
pstrUsagePageMSRDevices, pstrUsagePageMSRDevices,
@ -26,7 +26,7 @@ const char * const ReportDescParserBase::usagePageTitles1[] PROGMEM ={
pstrUsagePageCameraControl, pstrUsagePageCameraControl,
pstrUsagePageArcade pstrUsagePageArcade
}; };
const char * const ReportDescParserBase::genDesktopTitles0[] PROGMEM ={ const char * const ReportDescParserBase::genDesktopTitles0[] PROGMEM = {
pstrUsagePointer, pstrUsagePointer,
pstrUsageMouse, pstrUsageMouse,
pstrUsageJoystick, pstrUsageJoystick,
@ -37,7 +37,7 @@ const char * const ReportDescParserBase::genDesktopTitles0[] PROGMEM ={
pstrUsageTabletPCSystemControls pstrUsageTabletPCSystemControls
}; };
const char * const ReportDescParserBase::genDesktopTitles1[] PROGMEM ={ const char * const ReportDescParserBase::genDesktopTitles1[] PROGMEM = {
pstrUsageX, pstrUsageX,
pstrUsageY, pstrUsageY,
pstrUsageZ, pstrUsageZ,
@ -64,7 +64,7 @@ const char * const ReportDescParserBase::genDesktopTitles1[] PROGMEM ={
pstrUsageFeatureNotification, pstrUsageFeatureNotification,
pstrUsageResolutionMultiplier pstrUsageResolutionMultiplier
}; };
const char * const ReportDescParserBase::genDesktopTitles2[] PROGMEM ={ const char * const ReportDescParserBase::genDesktopTitles2[] PROGMEM = {
pstrUsageSystemControl, pstrUsageSystemControl,
pstrUsageSystemPowerDown, pstrUsageSystemPowerDown,
pstrUsageSystemSleep, pstrUsageSystemSleep,
@ -86,7 +86,7 @@ const char * const ReportDescParserBase::genDesktopTitles2[] PROGMEM ={
pstrUsageDPadRight, pstrUsageDPadRight,
pstrUsageDPadLeft pstrUsageDPadLeft
}; };
const char * const ReportDescParserBase::genDesktopTitles3[] PROGMEM ={ const char * const ReportDescParserBase::genDesktopTitles3[] PROGMEM = {
pstrUsageSystemDock, pstrUsageSystemDock,
pstrUsageSystemUndock, pstrUsageSystemUndock,
pstrUsageSystemSetup, pstrUsageSystemSetup,
@ -97,7 +97,7 @@ const char * const ReportDescParserBase::genDesktopTitles3[] PROGMEM ={
pstrUsageSystemSpeakerMute, pstrUsageSystemSpeakerMute,
pstrUsageSystemHibernate pstrUsageSystemHibernate
}; };
const char * const ReportDescParserBase::genDesktopTitles4[] PROGMEM ={ const char * const ReportDescParserBase::genDesktopTitles4[] PROGMEM = {
pstrUsageSystemDisplayInvert, pstrUsageSystemDisplayInvert,
pstrUsageSystemDisplayInternal, pstrUsageSystemDisplayInternal,
pstrUsageSystemDisplayExternal, pstrUsageSystemDisplayExternal,
@ -107,7 +107,7 @@ const char * const ReportDescParserBase::genDesktopTitles4[] PROGMEM ={
pstrUsageSystemDisplaySwapPriSec, pstrUsageSystemDisplaySwapPriSec,
pstrUsageSystemDisplayLCDAutoscale pstrUsageSystemDisplayLCDAutoscale
}; };
const char * const ReportDescParserBase::simuTitles0[] PROGMEM ={ const char * const ReportDescParserBase::simuTitles0[] PROGMEM = {
pstrUsageFlightSimulationDevice, pstrUsageFlightSimulationDevice,
pstrUsageAutomobileSimulationDevice, pstrUsageAutomobileSimulationDevice,
pstrUsageTankSimulationDevice, pstrUsageTankSimulationDevice,
@ -121,7 +121,7 @@ const char * const ReportDescParserBase::simuTitles0[] PROGMEM ={
pstrUsageMagicCarpetSimulationDevice, pstrUsageMagicCarpetSimulationDevice,
pstrUsageBicycleSimulationDevice pstrUsageBicycleSimulationDevice
}; };
const char * const ReportDescParserBase::simuTitles1[] PROGMEM ={ const char * const ReportDescParserBase::simuTitles1[] PROGMEM = {
pstrUsageFlightControlStick, pstrUsageFlightControlStick,
pstrUsageFlightStick, pstrUsageFlightStick,
pstrUsageCyclicControl, pstrUsageCyclicControl,
@ -129,7 +129,7 @@ const char * const ReportDescParserBase::simuTitles1[] PROGMEM ={
pstrUsageFlightYoke, pstrUsageFlightYoke,
pstrUsageTrackControl pstrUsageTrackControl
}; };
const char * const ReportDescParserBase::simuTitles2[] PROGMEM ={ const char * const ReportDescParserBase::simuTitles2[] PROGMEM = {
pstrUsageAileron, pstrUsageAileron,
pstrUsageAileronTrim, pstrUsageAileronTrim,
pstrUsageAntiTorqueControl, pstrUsageAntiTorqueControl,
@ -164,7 +164,7 @@ const char * const ReportDescParserBase::simuTitles2[] PROGMEM ={
pstrUsageFrontBrake, pstrUsageFrontBrake,
pstrUsageRearBrake pstrUsageRearBrake
}; };
const char * const ReportDescParserBase::vrTitles0[] PROGMEM ={ const char * const ReportDescParserBase::vrTitles0[] PROGMEM = {
pstrUsageBelt, pstrUsageBelt,
pstrUsageBodySuit, pstrUsageBodySuit,
pstrUsageFlexor, pstrUsageFlexor,
@ -176,17 +176,17 @@ const char * const ReportDescParserBase::vrTitles0[] PROGMEM ={
pstrUsageVest, pstrUsageVest,
pstrUsageAnimatronicDevice pstrUsageAnimatronicDevice
}; };
const char * const ReportDescParserBase::vrTitles1[] PROGMEM ={ const char * const ReportDescParserBase::vrTitles1[] PROGMEM = {
pstrUsageStereoEnable, pstrUsageStereoEnable,
pstrUsageDisplayEnable pstrUsageDisplayEnable
}; };
const char * const ReportDescParserBase::sportsCtrlTitles0[] PROGMEM ={ const char * const ReportDescParserBase::sportsCtrlTitles0[] PROGMEM = {
pstrUsageBaseballBat, pstrUsageBaseballBat,
pstrUsageGolfClub, pstrUsageGolfClub,
pstrUsageRowingMachine, pstrUsageRowingMachine,
pstrUsageTreadmill pstrUsageTreadmill
}; };
const char * const ReportDescParserBase::sportsCtrlTitles1[] PROGMEM ={ const char * const ReportDescParserBase::sportsCtrlTitles1[] PROGMEM = {
pstrUsageOar, pstrUsageOar,
pstrUsageSlope, pstrUsageSlope,
pstrUsageRate, pstrUsageRate,
@ -198,7 +198,7 @@ const char * const ReportDescParserBase::sportsCtrlTitles1[] PROGMEM ={
pstrUsageStickType, pstrUsageStickType,
pstrUsageStickHeight pstrUsageStickHeight
}; };
const char * const ReportDescParserBase::sportsCtrlTitles2[] PROGMEM ={ const char * const ReportDescParserBase::sportsCtrlTitles2[] PROGMEM = {
pstrUsagePutter, pstrUsagePutter,
pstrUsage1Iron, pstrUsage1Iron,
pstrUsage2Iron, pstrUsage2Iron,
@ -220,12 +220,12 @@ const char * const ReportDescParserBase::sportsCtrlTitles2[] PROGMEM ={
pstrUsage7Wood, pstrUsage7Wood,
pstrUsage9Wood pstrUsage9Wood
}; };
const char * const ReportDescParserBase::gameTitles0[] PROGMEM ={ const char * const ReportDescParserBase::gameTitles0[] PROGMEM = {
pstrUsage3DGameController, pstrUsage3DGameController,
pstrUsagePinballDevice, pstrUsagePinballDevice,
pstrUsageGunDevice pstrUsageGunDevice
}; };
const char * const ReportDescParserBase::gameTitles1[] PROGMEM ={ const char * const ReportDescParserBase::gameTitles1[] PROGMEM = {
pstrUsagePointOfView, pstrUsagePointOfView,
pstrUsageTurnRightLeft, pstrUsageTurnRightLeft,
pstrUsagePitchForwardBackward, pstrUsagePitchForwardBackward,
@ -252,7 +252,7 @@ const char * const ReportDescParserBase::gameTitles1[] PROGMEM ={
pstrUsageGamepadFireJump, pstrUsageGamepadFireJump,
pstrUsageGamepadTrigger pstrUsageGamepadTrigger
}; };
const char * const ReportDescParserBase::genDevCtrlTitles[] PROGMEM ={ const char * const ReportDescParserBase::genDevCtrlTitles[] PROGMEM = {
pstrUsageBatteryStrength, pstrUsageBatteryStrength,
pstrUsageWirelessChannel, pstrUsageWirelessChannel,
pstrUsageWirelessID, pstrUsageWirelessID,
@ -261,7 +261,7 @@ const char * const ReportDescParserBase::genDevCtrlTitles[] PROGMEM ={
pstrUsageSecurityCodeCharErased, pstrUsageSecurityCodeCharErased,
pstrUsageSecurityCodeCleared pstrUsageSecurityCodeCleared
}; };
const char * const ReportDescParserBase::ledTitles[] PROGMEM ={ const char * const ReportDescParserBase::ledTitles[] PROGMEM = {
pstrUsageNumLock, pstrUsageNumLock,
pstrUsageCapsLock, pstrUsageCapsLock,
pstrUsageScrollLock, pstrUsageScrollLock,
@ -340,7 +340,7 @@ const char * const ReportDescParserBase::ledTitles[] PROGMEM ={
pstrUsageSystemSuspend, pstrUsageSystemSuspend,
pstrUsageExternalPowerConnected pstrUsageExternalPowerConnected
}; };
const char * const ReportDescParserBase::telTitles0 [] PROGMEM ={ const char * const ReportDescParserBase::telTitles0 [] PROGMEM = {
pstrUsagePhone, pstrUsagePhone,
pstrUsageAnsweringMachine, pstrUsageAnsweringMachine,
pstrUsageMessageControls, pstrUsageMessageControls,
@ -349,7 +349,7 @@ const char * const ReportDescParserBase::telTitles0 [] PROGMEM ={
pstrUsageTelephonyKeyPad, pstrUsageTelephonyKeyPad,
pstrUsageProgrammableButton pstrUsageProgrammableButton
}; };
const char * const ReportDescParserBase::telTitles1 [] PROGMEM ={ const char * const ReportDescParserBase::telTitles1 [] PROGMEM = {
pstrUsageHookSwitch, pstrUsageHookSwitch,
pstrUsageFlash, pstrUsageFlash,
pstrUsageFeature, pstrUsageFeature,
@ -369,20 +369,20 @@ const char * const ReportDescParserBase::telTitles1 [] PROGMEM ={
pstrUsageCallerID, pstrUsageCallerID,
pstrUsageSend pstrUsageSend
}; };
const char * const ReportDescParserBase::telTitles2 [] PROGMEM ={ const char * const ReportDescParserBase::telTitles2 [] PROGMEM = {
pstrUsageSpeedDial, pstrUsageSpeedDial,
pstrUsageStoreNumber, pstrUsageStoreNumber,
pstrUsageRecallNumber, pstrUsageRecallNumber,
pstrUsagePhoneDirectory pstrUsagePhoneDirectory
}; };
const char * const ReportDescParserBase::telTitles3 [] PROGMEM ={ const char * const ReportDescParserBase::telTitles3 [] PROGMEM = {
pstrUsageVoiceMail, pstrUsageVoiceMail,
pstrUsageScreenCalls, pstrUsageScreenCalls,
pstrUsageDoNotDisturb, pstrUsageDoNotDisturb,
pstrUsageMessage, pstrUsageMessage,
pstrUsageAnswerOnOff pstrUsageAnswerOnOff
}; };
const char * const ReportDescParserBase::telTitles4 [] PROGMEM ={ const char * const ReportDescParserBase::telTitles4 [] PROGMEM = {
pstrUsageInsideDialTone, pstrUsageInsideDialTone,
pstrUsageOutsideDialTone, pstrUsageOutsideDialTone,
pstrUsageInsideRingTone, pstrUsageInsideRingTone,
@ -399,7 +399,7 @@ const char * const ReportDescParserBase::telTitles4 [] PROGMEM ={
pstrUsageOutsideRingback, pstrUsageOutsideRingback,
pstrUsageRinger pstrUsageRinger
}; };
const char * const ReportDescParserBase::telTitles5 [] PROGMEM ={ const char * const ReportDescParserBase::telTitles5 [] PROGMEM = {
pstrUsagePhoneKey0, pstrUsagePhoneKey0,
pstrUsagePhoneKey1, pstrUsagePhoneKey1,
pstrUsagePhoneKey2, pstrUsagePhoneKey2,
@ -417,7 +417,7 @@ const char * const ReportDescParserBase::telTitles5 [] PROGMEM ={
pstrUsagePhoneKeyC, pstrUsagePhoneKeyC,
pstrUsagePhoneKeyD pstrUsagePhoneKeyD
}; };
const char * const ReportDescParserBase::consTitles0[] PROGMEM ={ const char * const ReportDescParserBase::consTitles0[] PROGMEM = {
pstrUsageConsumerControl, pstrUsageConsumerControl,
pstrUsageNumericKeyPad, pstrUsageNumericKeyPad,
pstrUsageProgrammableButton, pstrUsageProgrammableButton,
@ -425,12 +425,12 @@ const char * const ReportDescParserBase::consTitles0[] PROGMEM ={
pstrUsageHeadphone, pstrUsageHeadphone,
pstrUsageGraphicEqualizer pstrUsageGraphicEqualizer
}; };
const char * const ReportDescParserBase::consTitles1[] PROGMEM ={ const char * const ReportDescParserBase::consTitles1[] PROGMEM = {
pstrUsagePlus10, pstrUsagePlus10,
pstrUsagePlus100, pstrUsagePlus100,
pstrUsageAMPM pstrUsageAMPM
}; };
const char * const ReportDescParserBase::consTitles2[] PROGMEM ={ const char * const ReportDescParserBase::consTitles2[] PROGMEM = {
pstrUsagePower, pstrUsagePower,
pstrUsageReset, pstrUsageReset,
pstrUsageSleep, pstrUsageSleep,
@ -440,7 +440,7 @@ const char * const ReportDescParserBase::consTitles2[] PROGMEM ={
pstrUsageFunctionButtons pstrUsageFunctionButtons
}; };
const char * const ReportDescParserBase::consTitles3[] PROGMEM ={ const char * const ReportDescParserBase::consTitles3[] PROGMEM = {
pstrUsageMenu, pstrUsageMenu,
pstrUsageMenuPick, pstrUsageMenuPick,
pstrUsageMenuUp, pstrUsageMenuUp,
@ -451,7 +451,7 @@ const char * const ReportDescParserBase::consTitles3[] PROGMEM ={
pstrUsageMenuValueIncrease, pstrUsageMenuValueIncrease,
pstrUsageMenuValueDecrease pstrUsageMenuValueDecrease
}; };
const char * const ReportDescParserBase::consTitles4[] PROGMEM ={ const char * const ReportDescParserBase::consTitles4[] PROGMEM = {
pstrUsageDataOnScreen, pstrUsageDataOnScreen,
pstrUsageClosedCaption, pstrUsageClosedCaption,
pstrUsageClosedCaptionSelect, pstrUsageClosedCaptionSelect,
@ -460,7 +460,7 @@ const char * const ReportDescParserBase::consTitles4[] PROGMEM ={
pstrUsageSnapshot, pstrUsageSnapshot,
pstrUsageStill pstrUsageStill
}; };
const char * const ReportDescParserBase::consTitles5[] PROGMEM ={ const char * const ReportDescParserBase::consTitles5[] PROGMEM = {
pstrUsageSelection, pstrUsageSelection,
pstrUsageAssignSelection, pstrUsageAssignSelection,
pstrUsageModeStep, pstrUsageModeStep,
@ -499,7 +499,7 @@ const char * const ReportDescParserBase::consTitles5[] PROGMEM ={
pstrUsageWeekly, pstrUsageWeekly,
pstrUsageMonthly pstrUsageMonthly
}; };
const char * const ReportDescParserBase::consTitles6[] PROGMEM ={ const char * const ReportDescParserBase::consTitles6[] PROGMEM = {
pstrUsagePlay, pstrUsagePlay,
pstrUsagePause, pstrUsagePause,
pstrUsageRecord, pstrUsageRecord,
@ -532,7 +532,7 @@ const char * const ReportDescParserBase::consTitles6[] PROGMEM ={
pstrUsagePlayPause, pstrUsagePlayPause,
pstrUsagePlaySkip pstrUsagePlaySkip
}; };
const char * const ReportDescParserBase::consTitles7[] PROGMEM ={ const char * const ReportDescParserBase::consTitles7[] PROGMEM = {
pstrUsageVolume, pstrUsageVolume,
pstrUsageBalance, pstrUsageBalance,
pstrUsageMute, pstrUsageMute,
@ -545,7 +545,7 @@ const char * const ReportDescParserBase::consTitles7[] PROGMEM ={
pstrUsageVolumeIncrement, pstrUsageVolumeIncrement,
pstrUsageVolumeDecrement pstrUsageVolumeDecrement
}; };
const char * const ReportDescParserBase::consTitles8[] PROGMEM ={ const char * const ReportDescParserBase::consTitles8[] PROGMEM = {
pstrUsageSpeedSelect, pstrUsageSpeedSelect,
pstrUsagePlaybackSpeed, pstrUsagePlaybackSpeed,
pstrUsageStandardPlay, pstrUsageStandardPlay,
@ -553,7 +553,7 @@ const char * const ReportDescParserBase::consTitles8[] PROGMEM ={
pstrUsageExtendedPlay, pstrUsageExtendedPlay,
pstrUsageSlow pstrUsageSlow
}; };
const char * const ReportDescParserBase::consTitles9[] PROGMEM ={ const char * const ReportDescParserBase::consTitles9[] PROGMEM = {
pstrUsageFanEnable, pstrUsageFanEnable,
pstrUsageFanSpeed, pstrUsageFanSpeed,
pstrUsageLightEnable, pstrUsageLightEnable,
@ -569,7 +569,7 @@ const char * const ReportDescParserBase::consTitles9[] PROGMEM ={
pstrUsageHoldupAlarm, pstrUsageHoldupAlarm,
pstrUsageMedicalAlarm pstrUsageMedicalAlarm
}; };
const char * const ReportDescParserBase::consTitlesA[] PROGMEM ={ const char * const ReportDescParserBase::consTitlesA[] PROGMEM = {
pstrUsageBalanceRight, pstrUsageBalanceRight,
pstrUsageBalanceLeft, pstrUsageBalanceLeft,
pstrUsageBassIncrement, pstrUsageBassIncrement,
@ -577,7 +577,7 @@ const char * const ReportDescParserBase::consTitlesA[] PROGMEM ={
pstrUsageTrebleIncrement, pstrUsageTrebleIncrement,
pstrUsageTrebleDecrement pstrUsageTrebleDecrement
}; };
const char * const ReportDescParserBase::consTitlesB[] PROGMEM ={ const char * const ReportDescParserBase::consTitlesB[] PROGMEM = {
pstrUsageSpeakerSystem, pstrUsageSpeakerSystem,
pstrUsageChannelLeft, pstrUsageChannelLeft,
pstrUsageChannelRight, pstrUsageChannelRight,
@ -590,14 +590,14 @@ const char * const ReportDescParserBase::consTitlesB[] PROGMEM ={
pstrUsageChannelTop, pstrUsageChannelTop,
pstrUsageChannelUnknown pstrUsageChannelUnknown
}; };
const char * const ReportDescParserBase::consTitlesC[] PROGMEM ={ const char * const ReportDescParserBase::consTitlesC[] PROGMEM = {
pstrUsageSubChannel, pstrUsageSubChannel,
pstrUsageSubChannelIncrement, pstrUsageSubChannelIncrement,
pstrUsageSubChannelDecrement, pstrUsageSubChannelDecrement,
pstrUsageAlternateAudioIncrement, pstrUsageAlternateAudioIncrement,
pstrUsageAlternateAudioDecrement pstrUsageAlternateAudioDecrement
}; };
const char * const ReportDescParserBase::consTitlesD[] PROGMEM ={ const char * const ReportDescParserBase::consTitlesD[] PROGMEM = {
pstrUsageApplicationLaunchButtons, pstrUsageApplicationLaunchButtons,
pstrUsageALLaunchButtonConfigTool, pstrUsageALLaunchButtonConfigTool,
pstrUsageALProgrammableButton, pstrUsageALProgrammableButton,
@ -671,7 +671,7 @@ const char * const ReportDescParserBase::consTitlesD[] PROGMEM ={
pstrUsageALResearchSearchBrowser, pstrUsageALResearchSearchBrowser,
pstrUsageALAudioPlayer pstrUsageALAudioPlayer
}; };
const char * const ReportDescParserBase::consTitlesE[] PROGMEM ={ const char * const ReportDescParserBase::consTitlesE[] PROGMEM = {
pstrUsageGenericGUIAppControls, pstrUsageGenericGUIAppControls,
pstrUsageACNew, pstrUsageACNew,
pstrUsageACOpen, pstrUsageACOpen,
@ -814,7 +814,7 @@ const char * const ReportDescParserBase::consTitlesE[] PROGMEM ={
pstrUsageACDistributeHorizontaly, pstrUsageACDistributeHorizontaly,
pstrUsageACDistributeVerticaly pstrUsageACDistributeVerticaly
}; };
const char * const ReportDescParserBase::digitTitles0[] PROGMEM ={ const char * const ReportDescParserBase::digitTitles0[] PROGMEM = {
pstrUsageDigitizer, pstrUsageDigitizer,
pstrUsagePen, pstrUsagePen,
pstrUsageLightPen, pstrUsageLightPen,
@ -829,13 +829,13 @@ const char * const ReportDescParserBase::digitTitles0[] PROGMEM ={
pstrUsageMultiplePointDigitizer, pstrUsageMultiplePointDigitizer,
pstrUsageFreeSpaceWand pstrUsageFreeSpaceWand
}; };
const char * const ReportDescParserBase::digitTitles1[] PROGMEM ={ const char * const ReportDescParserBase::digitTitles1[] PROGMEM = {
pstrUsageStylus, pstrUsageStylus,
pstrUsagePuck, pstrUsagePuck,
pstrUsageFinger pstrUsageFinger
}; };
const char * const ReportDescParserBase::digitTitles2[] PROGMEM ={ const char * const ReportDescParserBase::digitTitles2[] PROGMEM = {
pstrUsageTipPressure, pstrUsageTipPressure,
pstrUsageBarrelPressure, pstrUsageBarrelPressure,
pstrUsageInRange, pstrUsageInRange,
@ -860,11 +860,11 @@ const char * const ReportDescParserBase::digitTitles2[] PROGMEM ={
pstrUsageEraser, pstrUsageEraser,
pstrUsageTabletPick pstrUsageTabletPick
}; };
const char * const ReportDescParserBase::aplphanumTitles0[] PROGMEM ={ const char * const ReportDescParserBase::aplphanumTitles0[] PROGMEM = {
pstrUsageAlphanumericDisplay, pstrUsageAlphanumericDisplay,
pstrUsageBitmappedDisplay pstrUsageBitmappedDisplay
}; };
const char * const ReportDescParserBase::aplphanumTitles1[] PROGMEM ={ const char * const ReportDescParserBase::aplphanumTitles1[] PROGMEM = {
pstrUsageDisplayAttributesReport, pstrUsageDisplayAttributesReport,
pstrUsageASCIICharacterSet, pstrUsageASCIICharacterSet,
pstrUsageDataReadBack, pstrUsageDataReadBack,
@ -912,7 +912,7 @@ const char * const ReportDescParserBase::aplphanumTitles1[] PROGMEM ={
pstrUsageCharAttributeUnderline, pstrUsageCharAttributeUnderline,
pstrUsageCharAttributeBlink pstrUsageCharAttributeBlink
}; };
const char * const ReportDescParserBase::aplphanumTitles2[] PROGMEM ={ const char * const ReportDescParserBase::aplphanumTitles2[] PROGMEM = {
pstrUsageBitmapSizeX, pstrUsageBitmapSizeX,
pstrUsageBitmapSizeY, pstrUsageBitmapSizeY,
pstrUsagePageReserved, pstrUsagePageReserved,
@ -935,7 +935,7 @@ const char * const ReportDescParserBase::aplphanumTitles2[] PROGMEM ={
pstrUsageSoftButtonOffset2, pstrUsageSoftButtonOffset2,
pstrUsageSoftButtonReport pstrUsageSoftButtonReport
}; };
const char * const ReportDescParserBase::medInstrTitles0[] PROGMEM ={ const char * const ReportDescParserBase::medInstrTitles0[] PROGMEM = {
pstrUsageVCRAcquisition, pstrUsageVCRAcquisition,
pstrUsageFreezeThaw, pstrUsageFreezeThaw,
pstrUsageClipStore, pstrUsageClipStore,
@ -945,18 +945,18 @@ const char * const ReportDescParserBase::medInstrTitles0[] PROGMEM ={
pstrUsagePrint, pstrUsagePrint,
pstrUsageMicrophoneEnable pstrUsageMicrophoneEnable
}; };
const char * const ReportDescParserBase::medInstrTitles1[] PROGMEM ={ const char * const ReportDescParserBase::medInstrTitles1[] PROGMEM = {
pstrUsageCine, pstrUsageCine,
pstrUsageTransmitPower, pstrUsageTransmitPower,
pstrUsageVolume, pstrUsageVolume,
pstrUsageFocus, pstrUsageFocus,
pstrUsageDepth pstrUsageDepth
}; };
const char * const ReportDescParserBase::medInstrTitles2[] PROGMEM ={ const char * const ReportDescParserBase::medInstrTitles2[] PROGMEM = {
pstrUsageSoftStepPrimary, pstrUsageSoftStepPrimary,
pstrUsageSoftStepSecondary pstrUsageSoftStepSecondary
}; };
const char * const ReportDescParserBase::medInstrTitles3[] PROGMEM ={ const char * const ReportDescParserBase::medInstrTitles3[] PROGMEM = {
pstrUsageZoomSelect, pstrUsageZoomSelect,
pstrUsageZoomAdjust, pstrUsageZoomAdjust,
pstrUsageSpectralDopplerModeSelect, pstrUsageSpectralDopplerModeSelect,
@ -968,14 +968,14 @@ const char * const ReportDescParserBase::medInstrTitles3[] PROGMEM ={
pstrUsage2DModeSelect, pstrUsage2DModeSelect,
pstrUsage2DModeAdjust pstrUsage2DModeAdjust
}; };
const char * const ReportDescParserBase::medInstrTitles4[] PROGMEM ={ const char * const ReportDescParserBase::medInstrTitles4[] PROGMEM = {
pstrUsageSoftControlSelect, pstrUsageSoftControlSelect,
pstrUsageSoftControlAdjust pstrUsageSoftControlAdjust
}; };
void ReportDescParserBase::Parse(const uint16_t len, const uint8_t *pbuf, const uint16_t &offset) { void ReportDescParserBase::Parse(const uint16_t len, const uint8_t *pbuf, const uint16_t &offset) {
uint16_t cntdn = (uint16_t) len; uint16_t cntdn = (uint16_t)len;
uint8_t *p = (uint8_t*) pbuf; uint8_t *p = (uint8_t*)pbuf;
totalSize = 0; totalSize = 0;
@ -1108,13 +1108,13 @@ uint8_t ReportDescParserBase::ParseItem(uint8_t **pp, uint16_t *pcntdn) {
itemParseState = 3; itemParseState = 3;
case 3: case 3:
{ {
uint8_t data = *((uint8_t*) varBuffer); uint8_t data = *((uint8_t*)varBuffer);
switch (itemPrefix & (TYPE_MASK | TAG_MASK)) { switch (itemPrefix & (TYPE_MASK | TAG_MASK)) {
case (TYPE_LOCAL | TAG_LOCAL_USAGE): case (TYPE_LOCAL | TAG_LOCAL_USAGE):
if (pfUsage) { if (pfUsage) {
if (theBuffer.valueSize > 1) if (theBuffer.valueSize > 1)
pfUsage(*((uint16_t*) varBuffer)); pfUsage(*((uint16_t*)varBuffer));
else else
pfUsage(data); pfUsage(data);
} }
@ -1179,7 +1179,7 @@ uint8_t ReportDescParserBase::ParseItem(uint8_t **pp, uint16_t *pcntdn) {
case (TYPE_MAIN | TAG_MAIN_INPUT): case (TYPE_MAIN | TAG_MAIN_INPUT):
case (TYPE_MAIN | TAG_MAIN_OUTPUT): case (TYPE_MAIN | TAG_MAIN_OUTPUT):
case (TYPE_MAIN | TAG_MAIN_FEATURE): case (TYPE_MAIN | TAG_MAIN_FEATURE):
totalSize += (uint16_t) rptSize * (uint16_t) rptCount; totalSize += (uint16_t)rptSize * (uint16_t)rptCount;
rptSize = 0; rptSize = 0;
rptCount = 0; rptCount = 0;
Notify(PSTR("("), 0x80); Notify(PSTR("("), 0x80);
@ -1193,7 +1193,7 @@ uint8_t ReportDescParserBase::ParseItem(uint8_t **pp, uint16_t *pcntdn) {
return enErrorSuccess; return enErrorSuccess;
} }
ReportDescParserBase::UsagePageFunc ReportDescParserBase::usagePageFunctions[] /*PROGMEM*/ ={ ReportDescParserBase::UsagePageFunc ReportDescParserBase::usagePageFunctions[] /*PROGMEM*/ = {
&ReportDescParserBase::PrintGenericDesktopPageUsage, &ReportDescParserBase::PrintGenericDesktopPageUsage,
&ReportDescParserBase::PrintSimulationControlsPageUsage, &ReportDescParserBase::PrintSimulationControlsPageUsage,
&ReportDescParserBase::PrintVRControlsPageUsage, &ReportDescParserBase::PrintVRControlsPageUsage,
@ -1240,13 +1240,13 @@ void ReportDescParserBase::PrintUsagePage(uint16_t page) {
Notify(pstrSpace, 0x80); Notify(pstrSpace, 0x80);
if (page > 0x00 && page < 0x11) if (page > 0x00 && page < 0x11)
Notify((char*) pgm_read_word(&usagePageTitles0[page - 1]), 0x80); Notify((char*)pgm_read_word(&usagePageTitles0[page - 1]), 0x80);
else if (page > 0x7f && page < 0x84) else if (page > 0x7f && page < 0x84)
Notify(pstrUsagePageMonitor, 0x80); Notify(pstrUsagePageMonitor, 0x80);
else if (page > 0x83 && page < 0x8c) else if (page > 0x83 && page < 0x8c)
Notify(pstrUsagePagePower, 0x80); Notify(pstrUsagePagePower, 0x80);
else if (page > 0x8b && page < 0x92) else if (page > 0x8b && page < 0x92)
Notify((char*) pgm_read_word(&usagePageTitles1[page - 0x8c]), 0x80); Notify((char*)pgm_read_word(&usagePageTitles1[page - 0x8c]), 0x80);
else if (page > 0xfeff && page <= 0xffff) else if (page > 0xfeff && page <= 0xffff)
Notify(pstrUsagePageVendorDefined, 0x80); Notify(pstrUsagePageVendorDefined, 0x80);
else else
@ -1283,15 +1283,15 @@ void ReportDescParserBase::PrintGenericDesktopPageUsage(uint16_t usage) {
Notify(pstrSpace, 0x80); Notify(pstrSpace, 0x80);
if (usage > 0x00 && usage < 0x0a) if (usage > 0x00 && usage < 0x0a)
Notify((char*) pgm_read_word(&genDesktopTitles0[usage - 1]), 0x80); Notify((char*)pgm_read_word(&genDesktopTitles0[usage - 1]), 0x80);
else if (usage > 0x2f && usage < 0x49) else if (usage > 0x2f && usage < 0x49)
Notify((char*) pgm_read_word(&genDesktopTitles1[usage - 0x30]), 0x80); Notify((char*)pgm_read_word(&genDesktopTitles1[usage - 0x30]), 0x80);
else if (usage > 0x7f && usage < 0x94) else if (usage > 0x7f && usage < 0x94)
Notify((char*) pgm_read_word(&genDesktopTitles2[usage - 0x80]), 0x80); Notify((char*)pgm_read_word(&genDesktopTitles2[usage - 0x80]), 0x80);
else if (usage > 0x9f && usage < 0xa9) else if (usage > 0x9f && usage < 0xa9)
Notify((char*) pgm_read_word(&genDesktopTitles3[usage - 0xa0]), 0x80); Notify((char*)pgm_read_word(&genDesktopTitles3[usage - 0xa0]), 0x80);
else if (usage > 0xaf && usage < 0xb8) else if (usage > 0xaf && usage < 0xb8)
Notify((char*) pgm_read_word(&genDesktopTitles4[usage - 0xb0]), 0x80); Notify((char*)pgm_read_word(&genDesktopTitles4[usage - 0xb0]), 0x80);
else else
Notify(pstrUsagePageUndefined, 0x80); Notify(pstrUsagePageUndefined, 0x80);
} }
@ -1300,11 +1300,11 @@ void ReportDescParserBase::PrintSimulationControlsPageUsage(uint16_t usage) {
Notify(pstrSpace, 0x80); Notify(pstrSpace, 0x80);
if (usage > 0x00 && usage < 0x0d) if (usage > 0x00 && usage < 0x0d)
Notify((char*) pgm_read_word(&simuTitles0[usage - 1]), 0x80); Notify((char*)pgm_read_word(&simuTitles0[usage - 1]), 0x80);
else if (usage > 0x1f && usage < 0x26) else if (usage > 0x1f && usage < 0x26)
Notify((char*) pgm_read_word(&simuTitles1[usage - 0x20]), 0x80); Notify((char*)pgm_read_word(&simuTitles1[usage - 0x20]), 0x80);
else if (usage > 0xaf && usage < 0xd1) else if (usage > 0xaf && usage < 0xd1)
Notify((char*) pgm_read_word(&simuTitles2[usage - 0xb0]), 0x80); Notify((char*)pgm_read_word(&simuTitles2[usage - 0xb0]), 0x80);
else else
Notify(pstrUsagePageUndefined, 0x80); Notify(pstrUsagePageUndefined, 0x80);
} }
@ -1313,9 +1313,9 @@ void ReportDescParserBase::PrintVRControlsPageUsage(uint16_t usage) {
Notify(pstrSpace, 0x80); Notify(pstrSpace, 0x80);
if (usage > 0x00 && usage < 0x0b) if (usage > 0x00 && usage < 0x0b)
Notify((char*) pgm_read_word(&vrTitles0[usage - 1]), 0x80); Notify((char*)pgm_read_word(&vrTitles0[usage - 1]), 0x80);
else if (usage > 0x1f && usage < 0x22) else if (usage > 0x1f && usage < 0x22)
Notify((char*) pgm_read_word(&vrTitles1[usage - 0x20]), 0x80); Notify((char*)pgm_read_word(&vrTitles1[usage - 0x20]), 0x80);
else else
Notify(pstrUsagePageUndefined, 0x80); Notify(pstrUsagePageUndefined, 0x80);
} }
@ -1324,11 +1324,11 @@ void ReportDescParserBase::PrintSportsControlsPageUsage(uint16_t usage) {
Notify(pstrSpace, 0x80); Notify(pstrSpace, 0x80);
if (usage > 0x00 && usage < 0x05) if (usage > 0x00 && usage < 0x05)
Notify((char*) pgm_read_word(&sportsCtrlTitles0[usage - 1]), 0x80); Notify((char*)pgm_read_word(&sportsCtrlTitles0[usage - 1]), 0x80);
else if (usage > 0x2f && usage < 0x3a) else if (usage > 0x2f && usage < 0x3a)
Notify((char*) pgm_read_word(&sportsCtrlTitles1[usage - 0x30]), 0x80); Notify((char*)pgm_read_word(&sportsCtrlTitles1[usage - 0x30]), 0x80);
else if (usage > 0x4f && usage < 0x64) else if (usage > 0x4f && usage < 0x64)
Notify((char*) pgm_read_word(&sportsCtrlTitles2[usage - 0x50]), 0x80); Notify((char*)pgm_read_word(&sportsCtrlTitles2[usage - 0x50]), 0x80);
else else
Notify(pstrUsagePageUndefined, 0x80); Notify(pstrUsagePageUndefined, 0x80);
} }
@ -1337,9 +1337,9 @@ void ReportDescParserBase::PrintGameControlsPageUsage(uint16_t usage) {
Notify(pstrSpace, 0x80); Notify(pstrSpace, 0x80);
if (usage > 0x00 && usage < 0x04) if (usage > 0x00 && usage < 0x04)
Notify((char*) pgm_read_word(&gameTitles0[usage - 1]), 0x80); Notify((char*)pgm_read_word(&gameTitles0[usage - 1]), 0x80);
else if (usage > 0x1f && usage < 0x3a) else if (usage > 0x1f && usage < 0x3a)
Notify((char*) pgm_read_word(&gameTitles1[usage - 0x20]), 0x80); Notify((char*)pgm_read_word(&gameTitles1[usage - 0x20]), 0x80);
else else
Notify(pstrUsagePageUndefined, 0x80); Notify(pstrUsagePageUndefined, 0x80);
} }
@ -1348,7 +1348,7 @@ void ReportDescParserBase::PrintGenericDeviceControlsPageUsage(uint16_t usage) {
Notify(pstrSpace, 0x80); Notify(pstrSpace, 0x80);
if (usage > 0x1f && usage < 0x27) if (usage > 0x1f && usage < 0x27)
Notify((char*) pgm_read_word(&genDevCtrlTitles[usage - 0x20]), 0x80); Notify((char*)pgm_read_word(&genDevCtrlTitles[usage - 0x20]), 0x80);
else else
Notify(pstrUsagePageUndefined, 0x80); Notify(pstrUsagePageUndefined, 0x80);
} }
@ -1357,7 +1357,7 @@ void ReportDescParserBase::PrintLEDPageUsage(uint16_t usage) {
Notify(pstrSpace, 0x80); Notify(pstrSpace, 0x80);
if (usage > 0x00 && usage < 0x4e) if (usage > 0x00 && usage < 0x4e)
Notify((char*) pgm_read_word(&ledTitles[usage - 1]), 0x80); Notify((char*)pgm_read_word(&ledTitles[usage - 1]), 0x80);
else else
Notify(pstrUsagePageUndefined, 0x80); Notify(pstrUsagePageUndefined, 0x80);
} }
@ -1366,17 +1366,17 @@ void ReportDescParserBase::PrintTelephonyPageUsage(uint16_t usage) {
Notify(pstrSpace, 0x80); Notify(pstrSpace, 0x80);
if (usage > 0x00 && usage < 0x08) if (usage > 0x00 && usage < 0x08)
Notify((char*) pgm_read_word(&telTitles0[usage - 1]), 0x80); Notify((char*)pgm_read_word(&telTitles0[usage - 1]), 0x80);
else if (usage > 0x1f && usage < 0x32) else if (usage > 0x1f && usage < 0x32)
Notify((char*) pgm_read_word(&telTitles1[usage - 0x1f]), 0x80); Notify((char*)pgm_read_word(&telTitles1[usage - 0x1f]), 0x80);
else if (usage > 0x4f && usage < 0x54) else if (usage > 0x4f && usage < 0x54)
Notify((char*) pgm_read_word(&telTitles2[usage - 0x4f]), 0x80); Notify((char*)pgm_read_word(&telTitles2[usage - 0x4f]), 0x80);
else if (usage > 0x6f && usage < 0x75) else if (usage > 0x6f && usage < 0x75)
Notify((char*) pgm_read_word(&telTitles3[usage - 0x6f]), 0x80); Notify((char*)pgm_read_word(&telTitles3[usage - 0x6f]), 0x80);
else if (usage > 0x8f && usage < 0x9f) else if (usage > 0x8f && usage < 0x9f)
Notify((char*) pgm_read_word(&telTitles4[usage - 0x8f]), 0x80); Notify((char*)pgm_read_word(&telTitles4[usage - 0x8f]), 0x80);
else if (usage > 0xaf && usage < 0xc0) else if (usage > 0xaf && usage < 0xc0)
Notify((char*) pgm_read_word(&telTitles5[usage - 0xaf]), 0x80); Notify((char*)pgm_read_word(&telTitles5[usage - 0xaf]), 0x80);
else else
Notify(pstrUsagePageUndefined, 0x80); Notify(pstrUsagePageUndefined, 0x80);
} }
@ -1385,35 +1385,35 @@ void ReportDescParserBase::PrintConsumerPageUsage(uint16_t usage) {
Notify(pstrSpace, 0x80); Notify(pstrSpace, 0x80);
if (usage > 0x00 && usage < 0x07) if (usage > 0x00 && usage < 0x07)
Notify((char*) pgm_read_word(&consTitles0[usage - 1]), 0x80); Notify((char*)pgm_read_word(&consTitles0[usage - 1]), 0x80);
else if (usage > 0x1f && usage < 0x23) else if (usage > 0x1f && usage < 0x23)
Notify((char*) pgm_read_word(&consTitles1[usage - 0x1f]), 0x80); Notify((char*)pgm_read_word(&consTitles1[usage - 0x1f]), 0x80);
else if (usage > 0x2f && usage < 0x37) else if (usage > 0x2f && usage < 0x37)
Notify((char*) pgm_read_word(&consTitles2[usage - 0x2f]), 0x80); Notify((char*)pgm_read_word(&consTitles2[usage - 0x2f]), 0x80);
else if (usage > 0x3f && usage < 0x49) else if (usage > 0x3f && usage < 0x49)
Notify((char*) pgm_read_word(&consTitles3[usage - 0x3f]), 0x80); Notify((char*)pgm_read_word(&consTitles3[usage - 0x3f]), 0x80);
else if (usage > 0x5f && usage < 0x67) else if (usage > 0x5f && usage < 0x67)
Notify((char*) pgm_read_word(&consTitles4[usage - 0x5f]), 0x80); Notify((char*)pgm_read_word(&consTitles4[usage - 0x5f]), 0x80);
else if (usage > 0x7f && usage < 0xa5) else if (usage > 0x7f && usage < 0xa5)
Notify((char*) pgm_read_word(&consTitles5[usage - 0x7f]), 0x80); Notify((char*)pgm_read_word(&consTitles5[usage - 0x7f]), 0x80);
else if (usage > 0xaf && usage < 0xcf) else if (usage > 0xaf && usage < 0xcf)
Notify((char*) pgm_read_word(&consTitles6[usage - 0xaf]), 0x80); Notify((char*)pgm_read_word(&consTitles6[usage - 0xaf]), 0x80);
else if (usage > 0xdf && usage < 0xeb) else if (usage > 0xdf && usage < 0xeb)
Notify((char*) pgm_read_word(&consTitles7[usage - 0xdf]), 0x80); Notify((char*)pgm_read_word(&consTitles7[usage - 0xdf]), 0x80);
else if (usage > 0xef && usage < 0xf6) else if (usage > 0xef && usage < 0xf6)
Notify((char*) pgm_read_word(&consTitles8[usage - 0xef]), 0x80); Notify((char*)pgm_read_word(&consTitles8[usage - 0xef]), 0x80);
else if (usage > 0xff && usage < 0x10e) else if (usage > 0xff && usage < 0x10e)
Notify((char*) pgm_read_word(&consTitles9[usage - 0xff]), 0x80); Notify((char*)pgm_read_word(&consTitles9[usage - 0xff]), 0x80);
else if (usage > 0x14f && usage < 0x156) else if (usage > 0x14f && usage < 0x156)
Notify((char*) pgm_read_word(&consTitlesA[usage - 0x14f]), 0x80); Notify((char*)pgm_read_word(&consTitlesA[usage - 0x14f]), 0x80);
else if (usage > 0x15f && usage < 0x16b) else if (usage > 0x15f && usage < 0x16b)
Notify((char*) pgm_read_word(&consTitlesB[usage - 0x15f]), 0x80); Notify((char*)pgm_read_word(&consTitlesB[usage - 0x15f]), 0x80);
else if (usage > 0x16f && usage < 0x175) else if (usage > 0x16f && usage < 0x175)
Notify((char*) pgm_read_word(&consTitlesC[usage - 0x16f]), 0x80); Notify((char*)pgm_read_word(&consTitlesC[usage - 0x16f]), 0x80);
else if (usage > 0x17f && usage < 0x1c8) else if (usage > 0x17f && usage < 0x1c8)
Notify((char*) pgm_read_word(&consTitlesD[usage - 0x17f]), 0x80); Notify((char*)pgm_read_word(&consTitlesD[usage - 0x17f]), 0x80);
else if (usage > 0x1ff && usage < 0x29d) else if (usage > 0x1ff && usage < 0x29d)
Notify((char*) pgm_read_word(&consTitlesE[usage - 0x1ff]), 0x80); Notify((char*)pgm_read_word(&consTitlesE[usage - 0x1ff]), 0x80);
else else
Notify(pstrUsagePageUndefined, 0x80); Notify(pstrUsagePageUndefined, 0x80);
} }
@ -1422,11 +1422,11 @@ void ReportDescParserBase::PrintDigitizerPageUsage(uint16_t usage) {
Notify(pstrSpace, 0x80); Notify(pstrSpace, 0x80);
if (usage > 0x00 && usage < 0x0e) if (usage > 0x00 && usage < 0x0e)
Notify((char*) pgm_read_word(&digitTitles0[usage - 1]), 0x80); Notify((char*)pgm_read_word(&digitTitles0[usage - 1]), 0x80);
else if (usage > 0x1f && usage < 0x23) else if (usage > 0x1f && usage < 0x23)
Notify((char*) pgm_read_word(&digitTitles1[usage - 0x1f]), 0x80); Notify((char*)pgm_read_word(&digitTitles1[usage - 0x1f]), 0x80);
else if (usage > 0x2f && usage < 0x47) else if (usage > 0x2f && usage < 0x47)
Notify((char*) pgm_read_word(&digitTitles2[usage - 0x2f]), 0x80); Notify((char*)pgm_read_word(&digitTitles2[usage - 0x2f]), 0x80);
else else
Notify(pstrUsagePageUndefined, 0x80); Notify(pstrUsagePageUndefined, 0x80);
} }
@ -1435,11 +1435,11 @@ void ReportDescParserBase::PrintAlphanumDisplayPageUsage(uint16_t usage) {
Notify(pstrSpace, 0x80); Notify(pstrSpace, 0x80);
if (usage > 0x00 && usage < 0x03) if (usage > 0x00 && usage < 0x03)
Notify((char*) pgm_read_word(&aplphanumTitles0[usage - 1]), 0x80); Notify((char*)pgm_read_word(&aplphanumTitles0[usage - 1]), 0x80);
else if (usage > 0x1f && usage < 0x4e) else if (usage > 0x1f && usage < 0x4e)
Notify((char*) pgm_read_word(&aplphanumTitles1[usage - 0x1f]), 0x80); Notify((char*)pgm_read_word(&aplphanumTitles1[usage - 0x1f]), 0x80);
else if (usage > 0x7f && usage < 0x96) else if (usage > 0x7f && usage < 0x96)
Notify((char*) pgm_read_word(&digitTitles2[usage - 0x80]), 0x80); Notify((char*)pgm_read_word(&digitTitles2[usage - 0x80]), 0x80);
else else
Notify(pstrUsagePageUndefined, 0x80); Notify(pstrUsagePageUndefined, 0x80);
} }
@ -1450,17 +1450,17 @@ void ReportDescParserBase::PrintMedicalInstrumentPageUsage(uint16_t usage) {
if (usage == 1) if (usage == 1)
Notify(pstrUsageMedicalUltrasound, 0x80); Notify(pstrUsageMedicalUltrasound, 0x80);
else if (usage > 0x1f && usage < 0x28) else if (usage > 0x1f && usage < 0x28)
Notify((char*) pgm_read_word(&medInstrTitles0[usage - 0x1f]), 0x80); Notify((char*)pgm_read_word(&medInstrTitles0[usage - 0x1f]), 0x80);
else if (usage > 0x3f && usage < 0x45) else if (usage > 0x3f && usage < 0x45)
Notify((char*) pgm_read_word(&medInstrTitles1[usage - 0x40]), 0x80); Notify((char*)pgm_read_word(&medInstrTitles1[usage - 0x40]), 0x80);
else if (usage > 0x5f && usage < 0x62) else if (usage > 0x5f && usage < 0x62)
Notify((char*) pgm_read_word(&medInstrTitles2[usage - 0x60]), 0x80); Notify((char*)pgm_read_word(&medInstrTitles2[usage - 0x60]), 0x80);
else if (usage == 0x70) else if (usage == 0x70)
Notify(pstrUsageDepthGainCompensation, 0x80); Notify(pstrUsageDepthGainCompensation, 0x80);
else if (usage > 0x7f && usage < 0x8a) else if (usage > 0x7f && usage < 0x8a)
Notify((char*) pgm_read_word(&medInstrTitles3[usage - 0x80]), 0x80); Notify((char*)pgm_read_word(&medInstrTitles3[usage - 0x80]), 0x80);
else if (usage > 0x9f && usage < 0xa2) else if (usage > 0x9f && usage < 0xa2)
Notify((char*) pgm_read_word(&medInstrTitles4[usage - 0xa0]), 0x80); Notify((char*)pgm_read_word(&medInstrTitles4[usage - 0xa0]), 0x80);
else else
Notify(pstrUsagePageUndefined, 0x80); Notify(pstrUsagePageUndefined, 0x80);
} }
@ -1497,13 +1497,13 @@ uint8_t ReportDescParser2::ParseItem(uint8_t **pp, uint16_t *pcntdn) {
itemParseState = 3; itemParseState = 3;
case 3: case 3:
{ {
uint8_t data = *((uint8_t*) varBuffer); uint8_t data = *((uint8_t*)varBuffer);
switch (itemPrefix & (TYPE_MASK | TAG_MASK)) { switch (itemPrefix & (TYPE_MASK | TAG_MASK)) {
case (TYPE_LOCAL | TAG_LOCAL_USAGE): case (TYPE_LOCAL | TAG_LOCAL_USAGE):
if (pfUsage) { if (pfUsage) {
if (theBuffer.valueSize > 1) if (theBuffer.valueSize > 1)
pfUsage(*((uint16_t*) varBuffer)); pfUsage(*((uint16_t*)varBuffer));
else else
pfUsage(data); pfUsage(data);
} }
@ -1536,7 +1536,7 @@ uint8_t ReportDescParser2::ParseItem(uint8_t **pp, uint16_t *pcntdn) {
case (TYPE_MAIN | TAG_MAIN_INPUT): case (TYPE_MAIN | TAG_MAIN_INPUT):
OnInputItem(data); OnInputItem(data);
totalSize += (uint16_t) rptSize * (uint16_t) rptCount; totalSize += (uint16_t)rptSize * (uint16_t)rptCount;
rptSize = 0; rptSize = 0;
rptCount = 0; rptCount = 0;

View file

@ -119,7 +119,7 @@ protected:
MultiValueBuffer theBuffer; MultiValueBuffer theBuffer;
MultiByteValueParser valParser; MultiByteValueParser valParser;
ByteSkipper theSkipper; ByteSkipper theSkipper;
uint8_t varBuffer[sizeof (USB_CONFIGURATION_DESCRIPTOR)]; uint8_t varBuffer[sizeof(USB_CONFIGURATION_DESCRIPTOR)];
uint8_t itemParseState; // Item parser state variable uint8_t itemParseState; // Item parser state variable
uint8_t itemSize; // Item size uint8_t itemSize; // Item size

View file

@ -112,7 +112,7 @@ uint8_t HIDUniversal::Init(uint8_t parent, uint8_t port, bool lowspeed) {
p->lowspeed = lowspeed; p->lowspeed = lowspeed;
// Get device descriptor // Get device descriptor
rcode = pUsb->getDevDescr(0, 0, 8, (uint8_t*) buf); rcode = pUsb->getDevDescr(0, 0, 8, (uint8_t*)buf);
if (!rcode) if (!rcode)
len = (buf[0] > constBufSize) ? constBufSize : buf[0]; len = (buf[0] > constBufSize) ? constBufSize : buf[0];
@ -134,7 +134,7 @@ uint8_t HIDUniversal::Init(uint8_t parent, uint8_t port, bool lowspeed) {
return USB_ERROR_OUT_OF_ADDRESS_SPACE_IN_POOL; return USB_ERROR_OUT_OF_ADDRESS_SPACE_IN_POOL;
// Extract Max Packet Size from the device descriptor // Extract Max Packet Size from the device descriptor
epInfo[0].maxPktSize = (uint8_t) ((USB_DEVICE_DESCRIPTOR*) buf)->bMaxPacketSize0; epInfo[0].maxPktSize = (uint8_t)((USB_DEVICE_DESCRIPTOR*)buf)->bMaxPacketSize0;
// Assign new address to the device // Assign new address to the device
rcode = pUsb->setAddr(0, 0, bAddress); rcode = pUsb->setAddr(0, 0, bAddress);
@ -159,12 +159,12 @@ uint8_t HIDUniversal::Init(uint8_t parent, uint8_t port, bool lowspeed) {
p->lowspeed = lowspeed; p->lowspeed = lowspeed;
if (len) if (len)
rcode = pUsb->getDevDescr(bAddress, 0, len, (uint8_t*) buf); rcode = pUsb->getDevDescr(bAddress, 0, len, (uint8_t*)buf);
if (rcode) if (rcode)
goto FailGetDevDescr; goto FailGetDevDescr;
num_of_conf = ((USB_DEVICE_DESCRIPTOR*) buf)->bNumConfigurations; num_of_conf = ((USB_DEVICE_DESCRIPTOR*)buf)->bNumConfigurations;
// Assign epInfo to epinfo pointer // Assign epInfo to epinfo pointer
rcode = pUsb->setEpInfoEntry(bAddress, 1, epInfo); rcode = pUsb->setEpInfoEntry(bAddress, 1, epInfo);
@ -287,7 +287,7 @@ void HIDUniversal::EndpointXtract(uint8_t conf, uint8_t iface, uint8_t alt, uint
if (index) { if (index) {
// Fill in the endpoint info structure // Fill in the endpoint info structure
epInfo[bNumEP].epAddr = (pep->bEndpointAddress & 0x0F); epInfo[bNumEP].epAddr = (pep->bEndpointAddress & 0x0F);
epInfo[bNumEP].maxPktSize = (uint8_t) pep->wMaxPacketSize; epInfo[bNumEP].maxPktSize = (uint8_t)pep->wMaxPacketSize;
epInfo[bNumEP].epAttribs = 0; epInfo[bNumEP].epAttribs = 0;
epInfo[bNumEP].bmNakPower = USB_NAK_NOWAIT; epInfo[bNumEP].bmNakPower = USB_NAK_NOWAIT;
@ -339,7 +339,7 @@ uint8_t HIDUniversal::Poll() {
for (uint8_t i = 0; i < bNumIface; i++) { for (uint8_t i = 0; i < bNumIface; i++) {
uint8_t index = hidInterfaces[i].epIndex[epInterruptInIndex]; uint8_t index = hidInterfaces[i].epIndex[epInterruptInIndex];
uint16_t read = (uint16_t) epInfo[index].maxPktSize; uint16_t read = (uint16_t)epInfo[index].maxPktSize;
ZeroMemory(constBuffLen, buf); ZeroMemory(constBuffLen, buf);
@ -371,7 +371,7 @@ uint8_t HIDUniversal::Poll() {
HIDReportParser *prs = GetReportParser(((bHasReportId) ? *buf : 0)); HIDReportParser *prs = GetReportParser(((bHasReportId) ? *buf : 0));
if (prs) if (prs)
prs->Parse(this, bHasReportId, (uint8_t) read, buf); prs->Parse(this, bHasReportId, (uint8_t)read, buf);
} }
} }
return rcode; return rcode;

View file

@ -82,7 +82,7 @@ uint8_t BulkOnly::Init(uint8_t parent, uint8_t port, bool lowspeed) {
p->lowspeed = lowspeed; p->lowspeed = lowspeed;
// Get device descriptor // Get device descriptor
rcode = pUsb->getDevDescr(0, 0, constBufSize, (uint8_t*) buf); rcode = pUsb->getDevDescr(0, 0, constBufSize, (uint8_t*)buf);
// Restore p->epinfo // Restore p->epinfo
p->epinfo = oldep_ptr; p->epinfo = oldep_ptr;
@ -97,7 +97,7 @@ uint8_t BulkOnly::Init(uint8_t parent, uint8_t port, bool lowspeed) {
return USB_ERROR_OUT_OF_ADDRESS_SPACE_IN_POOL; return USB_ERROR_OUT_OF_ADDRESS_SPACE_IN_POOL;
// Extract Max Packet Size from the device descriptor // Extract Max Packet Size from the device descriptor
epInfo[0].maxPktSize = (uint8_t) ((USB_DEVICE_DESCRIPTOR*) buf)->bMaxPacketSize0; epInfo[0].maxPktSize = (uint8_t)((USB_DEVICE_DESCRIPTOR*)buf)->bMaxPacketSize0;
// Assign new address to the device // Assign new address to the device
rcode = pUsb->setAddr(0, 0, bAddress); rcode = pUsb->setAddr(0, 0, bAddress);
@ -121,7 +121,7 @@ uint8_t BulkOnly::Init(uint8_t parent, uint8_t port, bool lowspeed) {
p->lowspeed = lowspeed; p->lowspeed = lowspeed;
num_of_conf = ((USB_DEVICE_DESCRIPTOR*) buf)->bNumConfigurations; num_of_conf = ((USB_DEVICE_DESCRIPTOR*)buf)->bNumConfigurations;
// Assign epInfo to epinfo pointer // Assign epInfo to epinfo pointer
rcode = pUsb->setEpInfoEntry(bAddress, 1, epInfo); rcode = pUsb->setEpInfoEntry(bAddress, 1, epInfo);
@ -220,7 +220,7 @@ uint8_t BulkOnly::Init(uint8_t parent, uint8_t port, bool lowspeed) {
PrintHex<uint8_t > (capacity.data[i], 0x80); PrintHex<uint8_t > (capacity.data[i], 0x80);
Notify(PSTR("\r\n\r\n"), 0x80); Notify(PSTR("\r\n\r\n"), 0x80);
// Only 512/1024/2048/4096 are valid values! // Only 512/1024/2048/4096 are valid values!
uint32_t c = ((uint32_t) capacity.data[4] << 24) + ((uint32_t) capacity.data[5] << 16) + ((uint32_t) capacity.data[6] << 8) + (uint32_t) capacity.data[7]; uint32_t c = ((uint32_t)capacity.data[4] << 24) + ((uint32_t)capacity.data[5] << 16) + ((uint32_t)capacity.data[6] << 8) + (uint32_t)capacity.data[7];
if (c != 0x0200LU && c != 0x0400LU && c != 0x0800LU && c != 0x1000LU) { if (c != 0x0200LU && c != 0x0400LU && c != 0x0800LU && c != 0x1000LU) {
rcode = 255; rcode = 255;
goto FailInvalidSectorSize; goto FailInvalidSectorSize;
@ -354,7 +354,7 @@ void BulkOnly::EndpointXtract(uint8_t conf, uint8_t iface, uint8_t alt, uint8_t
// Fill in the endpoint info structure // Fill in the endpoint info structure
epInfo[index].epAddr = (pep->bEndpointAddress & 0x0F); epInfo[index].epAddr = (pep->bEndpointAddress & 0x0F);
epInfo[index].maxPktSize = (uint8_t) pep->wMaxPacketSize; epInfo[index].maxPktSize = (uint8_t)pep->wMaxPacketSize;
epInfo[index].epAttribs = 0; epInfo[index].epAttribs = 0;
bNumEP++; bNumEP++;
@ -611,7 +611,7 @@ uint8_t BulkOnly::Read(uint8_t lun, uint32_t addr, uint16_t bsize, uint8_t block
cbw.dCBWSignature = MASS_CBW_SIGNATURE; cbw.dCBWSignature = MASS_CBW_SIGNATURE;
cbw.dCBWTag = ++dCBWTag; cbw.dCBWTag = ++dCBWTag;
cbw.dCBWDataTransferLength = ((uint32_t) bsize * blocks); cbw.dCBWDataTransferLength = ((uint32_t)bsize * blocks);
cbw.bmCBWFlags = MASS_CMD_DIR_IN, cbw.bmCBWFlags = MASS_CMD_DIR_IN,
cbw.bmCBWLUN = lun; cbw.bmCBWLUN = lun;
cbw.bmCBWCBLength = 10; cbw.bmCBWCBLength = 10;
@ -638,7 +638,7 @@ uint8_t BulkOnly::Read(uint8_t lun, uint32_t addr, uint16_t bsize, uint8_t block
cbw.dCBWSignature = MASS_CBW_SIGNATURE; cbw.dCBWSignature = MASS_CBW_SIGNATURE;
cbw.dCBWTag = ++dCBWTag; cbw.dCBWTag = ++dCBWTag;
cbw.dCBWDataTransferLength = ((uint32_t) bsize * blocks); cbw.dCBWDataTransferLength = ((uint32_t)bsize * blocks);
cbw.bmCBWFlags = MASS_CMD_DIR_IN, cbw.bmCBWFlags = MASS_CMD_DIR_IN,
cbw.bmCBWLUN = lun; cbw.bmCBWLUN = lun;
cbw.bmCBWCBLength = 10; cbw.bmCBWCBLength = 10;
@ -666,7 +666,7 @@ uint8_t BulkOnly::Write(uint8_t lun, uint32_t addr, uint16_t bsize, uint8_t bloc
cbw.dCBWSignature = MASS_CBW_SIGNATURE; cbw.dCBWSignature = MASS_CBW_SIGNATURE;
cbw.dCBWTag = ++dCBWTag; cbw.dCBWTag = ++dCBWTag;
cbw.dCBWDataTransferLength = ((uint32_t) bsize * blocks); cbw.dCBWDataTransferLength = ((uint32_t)bsize * blocks);
cbw.bmCBWFlags = MASS_CMD_DIR_OUT, cbw.bmCBWFlags = MASS_CMD_DIR_OUT,
cbw.bmCBWLUN = lun; cbw.bmCBWLUN = lun;
cbw.bmCBWCBLength = 10; cbw.bmCBWCBLength = 10;
@ -681,7 +681,7 @@ uint8_t BulkOnly::Write(uint8_t lun, uint32_t addr, uint16_t bsize, uint8_t bloc
cbw.CBWCB[3] = ((addr >> 16) & 0xff); cbw.CBWCB[3] = ((addr >> 16) & 0xff);
cbw.CBWCB[2] = ((addr >> 24) & 0xff); cbw.CBWCB[2] = ((addr >> 24) & 0xff);
return HandleSCSIError(Transaction(&cbw, bsize, (void*) buf, 0)); return HandleSCSIError(Transaction(&cbw, bsize, (void*)buf, 0));
} }
uint8_t BulkOnly::ModeSense(uint8_t lun, uint8_t pc, uint8_t page, uint8_t subpage, uint8_t len, uint8_t *pbuf) { uint8_t BulkOnly::ModeSense(uint8_t lun, uint8_t pc, uint8_t page, uint8_t subpage, uint8_t len, uint8_t *pbuf) {
@ -714,7 +714,7 @@ uint8_t BulkOnly::Transaction(CommandBlockWrapper *pcbw, uint16_t buf_size, void
ErrorMessage<uint8_t > (PSTR("CBW.dCBWTag"), pcbw->dCBWTag); ErrorMessage<uint8_t > (PSTR("CBW.dCBWTag"), pcbw->dCBWTag);
ret = HandleUsbError(pUsb->outTransfer(bAddress, epInfo[epDataOutIndex].epAddr, sizeof (CommandBlockWrapper), (uint8_t*) pcbw), epDataOutIndex); ret = HandleUsbError(pUsb->outTransfer(bAddress, epInfo[epDataOutIndex].epAddr, sizeof (CommandBlockWrapper), (uint8_t*)pcbw), epDataOutIndex);
if (ret) { if (ret) {
ErrorMessage<uint8_t > (PSTR("CBW"), ret); ErrorMessage<uint8_t > (PSTR("CBW"), ret);
@ -732,16 +732,16 @@ uint8_t BulkOnly::Transaction(CommandBlockWrapper *pcbw, uint16_t buf_size, void
uint8_t rbuf[read]; uint8_t rbuf[read];
uint8_t err = 0; uint8_t err = 0;
ret = pUsb->inTransfer(bAddress, epInfo[epDataInIndex].epAddr, &read, rbuf); ret = pUsb->inTransfer(bAddress, epInfo[epDataInIndex].epAddr, &read, rbuf);
if (ret == hrSUCCESS) ((USBReadParser*) buf)->Parse(read, rbuf, 0); if (ret == hrSUCCESS) ((USBReadParser*)buf)->Parse(read, rbuf, 0);
if (ret == hrSTALL) err = ClearEpHalt(epDataInIndex); if (ret == hrSTALL) err = ClearEpHalt(epDataInIndex);
if (ret) { if (ret) {
ErrorMessage<uint8_t > (PSTR("RDR"), err); ErrorMessage<uint8_t > (PSTR("RDR"), err);
return MASS_ERR_GENERAL_USB_ERROR; return MASS_ERR_GENERAL_USB_ERROR;
} }
} else } else
ret = pUsb->inTransfer(bAddress, epInfo[epDataInIndex].epAddr, &read, (uint8_t*) buf); ret = pUsb->inTransfer(bAddress, epInfo[epDataInIndex].epAddr, &read, (uint8_t*)buf);
} else } else
ret = pUsb->outTransfer(bAddress, epInfo[epDataOutIndex].epAddr, read, (uint8_t*) buf); ret = pUsb->outTransfer(bAddress, epInfo[epDataOutIndex].epAddr, read, (uint8_t*)buf);
ret = HandleUsbError(ret, (pcbw->bmCBWFlags & MASS_CMD_DIR_IN) ? epDataInIndex : epDataOutIndex); ret = HandleUsbError(ret, (pcbw->bmCBWFlags & MASS_CMD_DIR_IN) ? epDataInIndex : epDataOutIndex);

View file

@ -104,7 +104,7 @@ struct Capacity {
uint8_t data[8]; uint8_t data[8];
//uint32_t dwBlockAddress; //uint32_t dwBlockAddress;
//uint32_t dwBlockLength; //uint32_t dwBlockLength;
}__attribute__((packed)); } __attribute__((packed));
struct InquiryResponse { struct InquiryResponse {
uint8_t DeviceType : 5; uint8_t DeviceType : 5;
@ -136,14 +136,14 @@ struct InquiryResponse {
uint8_t VendorID[8]; uint8_t VendorID[8];
uint8_t ProductID[16]; uint8_t ProductID[16];
uint8_t RevisionID[4]; uint8_t RevisionID[4];
}__attribute__((packed)); } __attribute__((packed));
struct CommandBlockWrapperBase { struct CommandBlockWrapperBase {
uint32_t dCBWSignature; uint32_t dCBWSignature;
uint32_t dCBWTag; uint32_t dCBWTag;
uint32_t dCBWDataTransferLength; uint32_t dCBWDataTransferLength;
uint8_t bmCBWFlags; uint8_t bmCBWFlags;
}__attribute__((packed)); } __attribute__((packed));
struct CommandBlockWrapper : public CommandBlockWrapperBase { struct CommandBlockWrapper : public CommandBlockWrapperBase {
@ -158,14 +158,14 @@ struct CommandBlockWrapper : public CommandBlockWrapperBase {
}; };
uint8_t CBWCB[16]; uint8_t CBWCB[16];
}__attribute__((packed)); } __attribute__((packed));
struct CommandStatusWrapper { struct CommandStatusWrapper {
uint32_t dCSWSignature; uint32_t dCSWSignature;
uint32_t dCSWTag; uint32_t dCSWTag;
uint32_t dCSWDataResidue; uint32_t dCSWDataResidue;
uint8_t bCSWStatus; uint8_t bCSWStatus;
}__attribute__((packed)); } __attribute__((packed));
struct RequestSenseResponce { struct RequestSenseResponce {
uint8_t bResponseCode; uint8_t bResponseCode;
@ -184,7 +184,7 @@ struct RequestSenseResponce {
uint8_t bAdditionalSenseQualifier; uint8_t bAdditionalSenseQualifier;
uint8_t bFieldReplaceableUnitCode; uint8_t bFieldReplaceableUnitCode;
uint8_t SenseKeySpecific[3]; uint8_t SenseKeySpecific[3];
}__attribute__((packed)); } __attribute__((packed));
#define MASS_MAX_ENDPOINTS 3 #define MASS_MAX_ENDPOINTS 3

View file

@ -43,7 +43,7 @@ bool PTPListParser::Parse(uint8_t **pp, uint16_t *pcntdn, PTP_ARRAY_EL_FUNC pf,
return false; return false;
arLen = 0; arLen = 0;
arLen = (pBuf->valueSize >= 4) ? *((uint32_t*) pBuf->pValue) : (uint32_t) (*((uint16_t*) pBuf->pValue)); arLen = (pBuf->valueSize >= 4) ? *((uint32_t*)pBuf->pValue) : (uint32_t)(*((uint16_t*)pBuf->pValue));
arLenCntdn = arLen; arLenCntdn = arLen;
nStage = 2; nStage = 2;

View file

@ -32,7 +32,7 @@ e-mail : support@circuitsathome.com
struct MultiValueBuffer { struct MultiValueBuffer {
uint8_t valueSize; uint8_t valueSize;
void *pValue; void *pValue;
}__attribute__((packed)); } __attribute__((packed));
class MultiByteValueParser { class MultiByteValueParser {
uint8_t * pBuf; uint8_t * pBuf;
@ -72,17 +72,17 @@ public:
}; };
bool Skip(uint8_t **pp, uint16_t *pcntdn, uint16_t bytes_to_skip) { bool Skip(uint8_t **pp, uint16_t *pcntdn, uint16_t bytes_to_skip) {
switch (nStage) { switch(nStage) {
case 0: case 0:
countDown = bytes_to_skip; countDown = bytes_to_skip;
nStage++; nStage++;
case 1: case 1:
for (; countDown && (*pcntdn); countDown--, (*pp)++, (*pcntdn)--); for(; countDown && (*pcntdn); countDown--, (*pp)++, (*pcntdn)--);
if (!countDown) if(!countDown)
nStage = 0; nStage = 0;
}; };
return (!countDown); return(!countDown);
}; };
}; };
@ -132,7 +132,7 @@ public:
valSize = val_size; valSize = val_size;
prsMode = mode; prsMode = mode;
if (prsMode == modeRange) { if(prsMode == modeRange) {
arLenCntdn = arLen = 3; arLenCntdn = arLen = 3;
nStage = 2; nStage = 2;
} else { } else {

View file

@ -26,19 +26,19 @@ void Notifyc(char c, int lvl);
template <class T> template <class T>
void PrintHex(T val, int lvl) { void PrintHex(T val, int lvl) {
int num_nibbles = sizeof (T) * 2; int num_nibbles = sizeof(T) * 2;
do { do {
char v = 48 + (((val >> (num_nibbles - 1) * 4)) & 0x0f); char v = 48 + (((val >> (num_nibbles - 1) * 4)) & 0x0f);
if (v > 57) v += 7; if(v > 57) v += 7;
Notifyc(v, lvl); Notifyc(v, lvl);
} while (--num_nibbles); } while(--num_nibbles);
} }
template <class T> template <class T>
void PrintBin(T val, int lvl) { void PrintBin(T val, int lvl) {
for (T mask = (((T) 1) << ((sizeof (T) << 3) - 1)); mask; mask >>= 1) for(T mask = (((T) 1) << ((sizeof(T) << 3) - 1)); mask; mask >>= 1)
if (val & mask) if(val & mask)
Notifyc('1', lvl); Notifyc('1', lvl);
else else
Notifyc('0', lvl); Notifyc('0', lvl);
@ -46,21 +46,21 @@ void PrintBin(T val, int lvl) {
template <class T> template <class T>
void SerialPrintHex(T val) { void SerialPrintHex(T val) {
int num_nibbles = sizeof (T) * 2; int num_nibbles = sizeof(T) * 2;
do { do {
char v = 48 + (((val >> (num_nibbles - 1) * 4)) & 0x0f); char v = 48 + (((val >> (num_nibbles - 1) * 4)) & 0x0f);
if (v > 57) v += 7; if(v > 57) v += 7;
Serial.print(v); Serial.print(v);
} while (--num_nibbles); } while(--num_nibbles);
} }
template <class T> template <class T>
void PrintHex2(Print *prn, T val) { void PrintHex2(Print *prn, T val) {
T mask = (((T) 1) << (((sizeof (T) << 1) - 1) << 2)); T mask = (((T) 1) << (((sizeof(T) << 1) - 1) << 2));
while (mask > 1) { while(mask > 1) {
if (val < mask) if(val < mask)
prn->print("0"); prn->print("0");
mask >>= 4; mask >>= 4;

View file

@ -108,7 +108,7 @@ typedef struct {
uint8_t iProduct; // Index of String Descriptor describing the product. uint8_t iProduct; // Index of String Descriptor describing the product.
uint8_t iSerialNumber; // Index of String Descriptor with the device's serial number. uint8_t iSerialNumber; // Index of String Descriptor with the device's serial number.
uint8_t bNumConfigurations; // Number of possible configurations. uint8_t bNumConfigurations; // Number of possible configurations.
}__attribute__((packed)) USB_DEVICE_DESCRIPTOR; } __attribute__((packed)) USB_DEVICE_DESCRIPTOR;
/* Configuration descriptor structure */ /* Configuration descriptor structure */
typedef struct { typedef struct {
@ -120,7 +120,7 @@ typedef struct {
uint8_t iConfiguration; // Index of String Descriptor describing the configuration. uint8_t iConfiguration; // Index of String Descriptor describing the configuration.
uint8_t bmAttributes; // Configuration characteristics. uint8_t bmAttributes; // Configuration characteristics.
uint8_t bMaxPower; // Maximum power consumed by this configuration. uint8_t bMaxPower; // Maximum power consumed by this configuration.
}__attribute__((packed)) USB_CONFIGURATION_DESCRIPTOR; } __attribute__((packed)) USB_CONFIGURATION_DESCRIPTOR;
/* Interface descriptor structure */ /* Interface descriptor structure */
typedef struct { typedef struct {
@ -133,7 +133,7 @@ typedef struct {
uint8_t bInterfaceSubClass; // Subclass code (assigned by the USB-IF). uint8_t bInterfaceSubClass; // Subclass code (assigned by the USB-IF).
uint8_t bInterfaceProtocol; // Protocol code (assigned by the USB-IF). 0xFF-Vendor specific. uint8_t bInterfaceProtocol; // Protocol code (assigned by the USB-IF). 0xFF-Vendor specific.
uint8_t iInterface; // Index of String Descriptor describing the interface. uint8_t iInterface; // Index of String Descriptor describing the interface.
}__attribute__((packed)) USB_INTERFACE_DESCRIPTOR; } __attribute__((packed)) USB_INTERFACE_DESCRIPTOR;
/* Endpoint descriptor structure */ /* Endpoint descriptor structure */
typedef struct { typedef struct {
@ -143,7 +143,7 @@ typedef struct {
uint8_t bmAttributes; // Endpoint transfer type. uint8_t bmAttributes; // Endpoint transfer type.
uint16_t wMaxPacketSize; // Maximum packet size. uint16_t wMaxPacketSize; // Maximum packet size.
uint8_t bInterval; // Polling interval in frames. uint8_t bInterval; // Polling interval in frames.
}__attribute__((packed)) USB_ENDPOINT_DESCRIPTOR; } __attribute__((packed)) USB_ENDPOINT_DESCRIPTOR;
/* HID descriptor */ /* HID descriptor */
typedef struct { typedef struct {
@ -154,11 +154,11 @@ typedef struct {
uint8_t bNumDescriptors; // Number of additional class specific descriptors uint8_t bNumDescriptors; // Number of additional class specific descriptors
uint8_t bDescrType; // Type of class descriptor uint8_t bDescrType; // Type of class descriptor
uint16_t wDescriptorLength; // Total size of the Report descriptor uint16_t wDescriptorLength; // Total size of the Report descriptor
}__attribute__((packed)) USB_HID_DESCRIPTOR; } __attribute__((packed)) USB_HID_DESCRIPTOR;
typedef struct { typedef struct {
uint8_t bDescrType; // Type of class descriptor uint8_t bDescrType; // Type of class descriptor
uint16_t wDescriptorLength; // Total size of the Report descriptor uint16_t wDescriptorLength; // Total size of the Report descriptor
}__attribute__((packed)) HID_CLASS_DESCRIPTOR_LEN_AND_TYPE; } __attribute__((packed)) HID_CLASS_DESCRIPTOR_LEN_AND_TYPE;
#endif // _ch9_h_ #endif // _ch9_h_

View file

@ -96,9 +96,9 @@ template< typename SS, typename INTR >
void MAX3421e< SS, INTR >::regWr(uint8_t reg, uint8_t data) { void MAX3421e< SS, INTR >::regWr(uint8_t reg, uint8_t data) {
SS::Clear(); SS::Clear();
SPDR = (reg | 0x02); SPDR = (reg | 0x02);
while (!(SPSR & (1 << SPIF))); while(!(SPSR & (1 << SPIF)));
SPDR = data; SPDR = data;
while (!(SPSR & (1 << SPIF))); while(!(SPSR & (1 << SPIF)));
SS::Set(); SS::Set();
return; return;
}; };
@ -109,14 +109,14 @@ template< typename SS, typename INTR >
uint8_t* MAX3421e< SS, INTR >::bytesWr(uint8_t reg, uint8_t nbytes, uint8_t* data_p) { uint8_t* MAX3421e< SS, INTR >::bytesWr(uint8_t reg, uint8_t nbytes, uint8_t* data_p) {
SS::Clear(); SS::Clear();
SPDR = (reg | 0x02); //set WR bit and send register number SPDR = (reg | 0x02); //set WR bit and send register number
while (nbytes--) { while(nbytes--) {
while (!(SPSR & (1 << SPIF))); //check if previous byte was sent while(!(SPSR & (1 << SPIF))); //check if previous byte was sent
SPDR = (*data_p); // send next data byte SPDR = (*data_p); // send next data byte
data_p++; // advance data pointer data_p++; // advance data pointer
} }
while (!(SPSR & (1 << SPIF))); while(!(SPSR & (1 << SPIF)));
SS::Set(); SS::Set();
return ( data_p); return( data_p);
} }
/* GPIO write */ /* GPIO write */
/*GPIO byte is split between 2 registers, so two writes are needed to write one byte */ /*GPIO byte is split between 2 registers, so two writes are needed to write one byte */
@ -135,11 +135,11 @@ template< typename SS, typename INTR >
uint8_t MAX3421e< SS, INTR >::regRd(uint8_t reg) { uint8_t MAX3421e< SS, INTR >::regRd(uint8_t reg) {
SS::Clear(); SS::Clear();
SPDR = reg; SPDR = reg;
while (!(SPSR & (1 << SPIF))); while(!(SPSR & (1 << SPIF)));
SPDR = 0; //send empty byte SPDR = 0; //send empty byte
while (!(SPSR & (1 << SPIF))); while(!(SPSR & (1 << SPIF)));
SS::Set(); SS::Set();
return ( SPDR); return( SPDR);
} }
/* multiple-byte register read */ /* multiple-byte register read */
@ -148,16 +148,16 @@ template< typename SS, typename INTR >
uint8_t* MAX3421e< SS, INTR >::bytesRd(uint8_t reg, uint8_t nbytes, uint8_t* data_p) { uint8_t* MAX3421e< SS, INTR >::bytesRd(uint8_t reg, uint8_t nbytes, uint8_t* data_p) {
SS::Clear(); SS::Clear();
SPDR = reg; SPDR = reg;
while (!(SPSR & (1 << SPIF))); //wait while(!(SPSR & (1 << SPIF))); //wait
while (nbytes) { while(nbytes) {
SPDR = 0; //send empty byte SPDR = 0; //send empty byte
nbytes--; nbytes--;
while (!(SPSR & (1 << SPIF))); while(!(SPSR & (1 << SPIF)));
*data_p = SPDR; *data_p = SPDR;
data_p++; data_p++;
} }
SS::Set(); SS::Set();
return ( data_p); return( data_p);
} }
/* GPIO read. See gpioWr for explanation */ /* GPIO read. See gpioWr for explanation */
@ -168,7 +168,7 @@ uint8_t MAX3421e< SS, INTR >::gpioRd() {
gpin = regRd(rIOPINS2); //pins 4-7 gpin = regRd(rIOPINS2); //pins 4-7
gpin &= 0xf0; //clean lower nibble gpin &= 0xf0; //clean lower nibble
gpin |= (regRd(rIOPINS1) >> 4); //shift low bits and OR with upper from previous operation. gpin |= (regRd(rIOPINS1) >> 4); //shift low bits and OR with upper from previous operation.
return ( gpin); return( gpin);
} }
/* reset MAX3421E. Returns number of cycles it took for PLL to stabilize after reset /* reset MAX3421E. Returns number of cycles it took for PLL to stabilize after reset
@ -178,12 +178,12 @@ uint16_t MAX3421e< SS, INTR >::reset() {
uint16_t i = 0; uint16_t i = 0;
regWr(rUSBCTL, bmCHIPRES); regWr(rUSBCTL, bmCHIPRES);
regWr(rUSBCTL, 0x00); regWr(rUSBCTL, 0x00);
while (++i) { while(++i) {
if ((regRd(rUSBIRQ) & bmOSCOKIRQ)) { if((regRd(rUSBIRQ) & bmOSCOKIRQ)) {
break; break;
} }
} }
return ( i); return( i);
} }
///* initialize MAX3421E. Set Host mode, pullups, and stuff. Returns 0 if success, -1 if not */ ///* initialize MAX3421E. Set Host mode, pullups, and stuff. Returns 0 if success, -1 if not */
//template< typename SS, typename INTR > //template< typename SS, typename INTR >
@ -200,8 +200,8 @@ uint16_t MAX3421e< SS, INTR >::reset() {
/* initialize MAX3421E. Set Host mode, pullups, and stuff. Returns 0 if success, -1 if not */ /* initialize MAX3421E. Set Host mode, pullups, and stuff. Returns 0 if success, -1 if not */
template< typename SS, typename INTR > template< typename SS, typename INTR >
int8_t MAX3421e< SS, INTR >::Init() { int8_t MAX3421e< SS, INTR >::Init() {
if (reset() == 0) { //OSCOKIRQ hasn't asserted in time if(reset() == 0) { //OSCOKIRQ hasn't asserted in time
return ( -1); return( -1);
} }
regWr(rMODE, bmDPPULLDN | bmDMPULLDN | bmHOST); // set pull-downs, Host regWr(rMODE, bmDPPULLDN | bmDMPULLDN | bmHOST); // set pull-downs, Host
@ -209,13 +209,13 @@ int8_t MAX3421e< SS, INTR >::Init() {
/* check if device is connected */ /* check if device is connected */
regWr(rHCTL, bmSAMPLEBUS); // sample USB bus regWr(rHCTL, bmSAMPLEBUS); // sample USB bus
while (!(regRd(rHCTL) & bmSAMPLEBUS)); //wait for sample operation to finish while(!(regRd(rHCTL) & bmSAMPLEBUS)); //wait for sample operation to finish
busprobe(); //check if anything is connected busprobe(); //check if anything is connected
regWr(rHIRQ, bmCONDETIRQ); //clear connection detect interrupt regWr(rHIRQ, bmCONDETIRQ); //clear connection detect interrupt
regWr(rCPUCTL, 0x01); //enable interrupt pin regWr(rCPUCTL, 0x01); //enable interrupt pin
return ( 0); return( 0);
} }
/* probe bus to determine device presence and speed and switch host to this speed */ /* probe bus to determine device presence and speed and switch host to this speed */
@ -224,9 +224,9 @@ void MAX3421e< SS, INTR >::busprobe() {
uint8_t bus_sample; uint8_t bus_sample;
bus_sample = regRd(rHRSL); //Get J,K status bus_sample = regRd(rHRSL); //Get J,K status
bus_sample &= (bmJSTATUS | bmKSTATUS); //zero the rest of the byte bus_sample &= (bmJSTATUS | bmKSTATUS); //zero the rest of the byte
switch (bus_sample) { //start full-speed or low-speed host switch(bus_sample) { //start full-speed or low-speed host
case( bmJSTATUS): case( bmJSTATUS):
if ((regRd(rMODE) & bmLOWSPEED) == 0) { if((regRd(rMODE) & bmLOWSPEED) == 0) {
regWr(rMODE, MODE_FS_HOST); //start full-speed host regWr(rMODE, MODE_FS_HOST); //start full-speed host
vbusState = FSHOST; vbusState = FSHOST;
} else { } else {
@ -235,7 +235,7 @@ void MAX3421e< SS, INTR >::busprobe() {
} }
break; break;
case( bmKSTATUS): case( bmKSTATUS):
if ((regRd(rMODE) & bmLOWSPEED) == 0) { if((regRd(rMODE) & bmLOWSPEED) == 0) {
regWr(rMODE, MODE_LS_HOST); //start low-speed host regWr(rMODE, MODE_LS_HOST); //start low-speed host
vbusState = LSHOST; vbusState = LSHOST;
} else { } else {
@ -262,7 +262,7 @@ uint8_t MAX3421e< SS, INTR >::Task(void) {
//Serial.println( vbusState, HEX ); //Serial.println( vbusState, HEX );
pinvalue = INTR::IsSet(); //Read(); pinvalue = INTR::IsSet(); //Read();
//pinvalue = digitalRead( MAX_INT ); //pinvalue = digitalRead( MAX_INT );
if (pinvalue == 0) { if(pinvalue == 0) {
rcode = IntHandler(); rcode = IntHandler();
} }
// pinvalue = digitalRead( MAX_GPX ); // pinvalue = digitalRead( MAX_GPX );
@ -270,7 +270,7 @@ uint8_t MAX3421e< SS, INTR >::Task(void) {
// GpxHandler(); // GpxHandler();
// } // }
// usbSM(); //USB state machine // usbSM(); //USB state machine
return ( rcode); return( rcode);
} }
template< typename SS, typename INTR > template< typename SS, typename INTR >
@ -281,13 +281,13 @@ uint8_t MAX3421e< SS, INTR >::IntHandler() {
//if( HIRQ & bmFRAMEIRQ ) { //->1ms SOF interrupt handler //if( HIRQ & bmFRAMEIRQ ) { //->1ms SOF interrupt handler
// HIRQ_sendback |= bmFRAMEIRQ; // HIRQ_sendback |= bmFRAMEIRQ;
//}//end FRAMEIRQ handling //}//end FRAMEIRQ handling
if (HIRQ & bmCONDETIRQ) { if(HIRQ & bmCONDETIRQ) {
busprobe(); busprobe();
HIRQ_sendback |= bmCONDETIRQ; HIRQ_sendback |= bmCONDETIRQ;
} }
/* End HIRQ interrupts handling, clear serviced IRQs */ /* End HIRQ interrupts handling, clear serviced IRQs */
regWr(rHIRQ, HIRQ_sendback); regWr(rHIRQ, HIRQ_sendback);
return ( HIRQ_sendback); return( HIRQ_sendback);
} }
//template< typename SS, typename INTR > //template< typename SS, typename INTR >
//uint8_t MAX3421e< SS, INTR >::GpxHandler() //uint8_t MAX3421e< SS, INTR >::GpxHandler()

View file

@ -74,7 +74,7 @@ uint8_t USBHub::Init(uint8_t parent, uint8_t port, bool lowspeed) {
p->lowspeed = lowspeed; p->lowspeed = lowspeed;
// Get device descriptor // Get device descriptor
rcode = pUsb->getDevDescr(0, 0, 8, (uint8_t*) buf); rcode = pUsb->getDevDescr(0, 0, 8, (uint8_t*)buf);
p->lowspeed = false; p->lowspeed = false;
@ -89,17 +89,17 @@ uint8_t USBHub::Init(uint8_t parent, uint8_t port, bool lowspeed) {
// Extract device class from device descriptor // Extract device class from device descriptor
// If device class is not a hub return // If device class is not a hub return
if (((USB_DEVICE_DESCRIPTOR*) buf)->bDeviceClass != 0x09) if (((USB_DEVICE_DESCRIPTOR*)buf)->bDeviceClass != 0x09)
return USB_DEV_CONFIG_ERROR_DEVICE_NOT_SUPPORTED; return USB_DEV_CONFIG_ERROR_DEVICE_NOT_SUPPORTED;
// Allocate new address according to device class // Allocate new address according to device class
bAddress = addrPool.AllocAddress(parent, (((USB_DEVICE_DESCRIPTOR*) buf)->bDeviceClass == 0x09) ? true : false, port); bAddress = addrPool.AllocAddress(parent, (((USB_DEVICE_DESCRIPTOR*)buf)->bDeviceClass == 0x09) ? true : false, port);
if (!bAddress) if (!bAddress)
return USB_ERROR_OUT_OF_ADDRESS_SPACE_IN_POOL; return USB_ERROR_OUT_OF_ADDRESS_SPACE_IN_POOL;
// Extract Max Packet Size from the device descriptor // Extract Max Packet Size from the device descriptor
epInfo[0].maxPktSize = ((USB_DEVICE_DESCRIPTOR*) buf)->bMaxPacketSize0; epInfo[0].maxPktSize = ((USB_DEVICE_DESCRIPTOR*)buf)->bMaxPacketSize0;
// Assign new address to the device // Assign new address to the device
rcode = pUsb->setAddr(0, 0, bAddress); rcode = pUsb->setAddr(0, 0, bAddress);
@ -118,7 +118,7 @@ uint8_t USBHub::Init(uint8_t parent, uint8_t port, bool lowspeed) {
p->epinfo = oldep_ptr; p->epinfo = oldep_ptr;
if (len) if (len)
rcode = pUsb->getDevDescr(bAddress, 0, len, (uint8_t*) buf); rcode = pUsb->getDevDescr(bAddress, 0, len, (uint8_t*)buf);
if (rcode) if (rcode)
goto FailGetDevDescr; goto FailGetDevDescr;
@ -139,7 +139,7 @@ uint8_t USBHub::Init(uint8_t parent, uint8_t port, bool lowspeed) {
goto FailGetHubDescr; goto FailGetHubDescr;
// Save number of ports for future use // Save number of ports for future use
bNbrPorts = ((HubDescriptor*) buf)->bNbrPorts; bNbrPorts = ((HubDescriptor*)buf)->bNbrPorts;
bInitState = 2; bInitState = 2;
@ -148,7 +148,7 @@ uint8_t USBHub::Init(uint8_t parent, uint8_t port, bool lowspeed) {
rcode = pUsb->getConfDescr(bAddress, 0, 8, 0, buf); rcode = pUsb->getConfDescr(bAddress, 0, 8, 0, buf);
if (!rcode) { if (!rcode) {
cd_len = ((USB_CONFIGURATION_DESCRIPTOR*) buf)->wTotalLength; cd_len = ((USB_CONFIGURATION_DESCRIPTOR*)buf)->wTotalLength;
rcode = pUsb->getConfDescr(bAddress, 0, cd_len, 0, buf); rcode = pUsb->getConfDescr(bAddress, 0, cd_len, 0, buf);
} }
if (rcode) if (rcode)

View file

@ -155,11 +155,11 @@ struct HubDescriptor {
uint16_t TTThinkTime : 2; uint16_t TTThinkTime : 2;
uint16_t PortIndicatorsSupported : 1; uint16_t PortIndicatorsSupported : 1;
uint16_t Reserved : 8; uint16_t Reserved : 8;
}__attribute__((packed)); } __attribute__((packed));
uint8_t bPwrOn2PwrGood; uint8_t bPwrOn2PwrGood;
uint8_t bHubContrCurrent; uint8_t bHubContrCurrent;
}__attribute__((packed)); } __attribute__((packed));
struct HubEvent { struct HubEvent {
@ -168,11 +168,11 @@ struct HubEvent {
struct { struct {
uint16_t bmStatus; // port status bits uint16_t bmStatus; // port status bits
uint16_t bmChange; // port status change bits uint16_t bmChange; // port status change bits
}__attribute__((packed)); } __attribute__((packed));
uint32_t bmEvent; uint32_t bmEvent;
uint8_t evtBuff[4]; uint8_t evtBuff[4];
}; };
}__attribute__((packed)); } __attribute__((packed));
class USBHub : USBDeviceConfig { class USBHub : USBDeviceConfig {
static bool bResetInitiated; // True when reset is triggered static bool bResetInitiated; // True when reset is triggered
@ -216,42 +216,42 @@ public:
// Clear Hub Feature // Clear Hub Feature
inline uint8_t USBHub::ClearHubFeature(uint8_t fid) { inline uint8_t USBHub::ClearHubFeature(uint8_t fid) {
return ( pUsb->ctrlReq(bAddress, 0, bmREQ_CLEAR_HUB_FEATURE, USB_REQUEST_CLEAR_FEATURE, fid, 0, 0, 0, 0, NULL, NULL)); return( pUsb->ctrlReq(bAddress, 0, bmREQ_CLEAR_HUB_FEATURE, USB_REQUEST_CLEAR_FEATURE, fid, 0, 0, 0, 0, NULL, NULL));
} }
// Clear Port Feature // Clear Port Feature
inline uint8_t USBHub::ClearPortFeature(uint8_t fid, uint8_t port, uint8_t sel) { inline uint8_t USBHub::ClearPortFeature(uint8_t fid, uint8_t port, uint8_t sel) {
return ( pUsb->ctrlReq(bAddress, 0, bmREQ_CLEAR_PORT_FEATURE, USB_REQUEST_CLEAR_FEATURE, fid, 0, ((0x0000 | port) | (sel << 8)), 0, 0, NULL, NULL)); return( pUsb->ctrlReq(bAddress, 0, bmREQ_CLEAR_PORT_FEATURE, USB_REQUEST_CLEAR_FEATURE, fid, 0, ((0x0000 | port) | (sel << 8)), 0, 0, NULL, NULL));
} }
// Get Hub Descriptor // Get Hub Descriptor
inline uint8_t USBHub::GetHubDescriptor(uint8_t index, uint16_t nbytes, uint8_t *dataptr) { inline uint8_t USBHub::GetHubDescriptor(uint8_t index, uint16_t nbytes, uint8_t *dataptr) {
return ( pUsb->ctrlReq(bAddress, 0, bmREQ_GET_HUB_DESCRIPTOR, USB_REQUEST_GET_DESCRIPTOR, index, 0x29, 0, nbytes, nbytes, dataptr, NULL)); return( pUsb->ctrlReq(bAddress, 0, bmREQ_GET_HUB_DESCRIPTOR, USB_REQUEST_GET_DESCRIPTOR, index, 0x29, 0, nbytes, nbytes, dataptr, NULL));
} }
// Get Hub Status // Get Hub Status
inline uint8_t USBHub::GetHubStatus(uint16_t nbytes, uint8_t* dataptr) { inline uint8_t USBHub::GetHubStatus(uint16_t nbytes, uint8_t* dataptr) {
return ( pUsb->ctrlReq(bAddress, 0, bmREQ_GET_HUB_STATUS, USB_REQUEST_GET_STATUS, 0, 0, 0x0000, nbytes, nbytes, dataptr, NULL)); return( pUsb->ctrlReq(bAddress, 0, bmREQ_GET_HUB_STATUS, USB_REQUEST_GET_STATUS, 0, 0, 0x0000, nbytes, nbytes, dataptr, NULL));
} }
// Get Port Status // Get Port Status
inline uint8_t USBHub::GetPortStatus(uint8_t port, uint16_t nbytes, uint8_t* dataptr) { inline uint8_t USBHub::GetPortStatus(uint8_t port, uint16_t nbytes, uint8_t* dataptr) {
return ( pUsb->ctrlReq(bAddress, 0, bmREQ_GET_PORT_STATUS, USB_REQUEST_GET_STATUS, 0, 0, port, nbytes, nbytes, dataptr, NULL)); return( pUsb->ctrlReq(bAddress, 0, bmREQ_GET_PORT_STATUS, USB_REQUEST_GET_STATUS, 0, 0, port, nbytes, nbytes, dataptr, NULL));
} }
// Set Hub Descriptor // Set Hub Descriptor
inline uint8_t USBHub::SetHubDescriptor(uint8_t port, uint16_t nbytes, uint8_t* dataptr) { inline uint8_t USBHub::SetHubDescriptor(uint8_t port, uint16_t nbytes, uint8_t* dataptr) {
return ( pUsb->ctrlReq(bAddress, 0, bmREQ_SET_HUB_DESCRIPTOR, USB_REQUEST_SET_DESCRIPTOR, 0, 0, port, nbytes, nbytes, dataptr, NULL)); return( pUsb->ctrlReq(bAddress, 0, bmREQ_SET_HUB_DESCRIPTOR, USB_REQUEST_SET_DESCRIPTOR, 0, 0, port, nbytes, nbytes, dataptr, NULL));
} }
// Set Hub Feature // Set Hub Feature
inline uint8_t USBHub::SetHubFeature(uint8_t fid) { inline uint8_t USBHub::SetHubFeature(uint8_t fid) {
return ( pUsb->ctrlReq(bAddress, 0, bmREQ_SET_HUB_FEATURE, USB_REQUEST_SET_FEATURE, fid, 0, 0, 0, 0, NULL, NULL)); return( pUsb->ctrlReq(bAddress, 0, bmREQ_SET_HUB_FEATURE, USB_REQUEST_SET_FEATURE, fid, 0, 0, 0, 0, NULL, NULL));
} }
// Set Port Feature // Set Port Feature
inline uint8_t USBHub::SetPortFeature(uint8_t fid, uint8_t port, uint8_t sel) { inline uint8_t USBHub::SetPortFeature(uint8_t fid, uint8_t port, uint8_t sel) {
return ( pUsb->ctrlReq(bAddress, 0, bmREQ_SET_PORT_FEATURE, USB_REQUEST_SET_FEATURE, fid, 0, (((0x0000 | sel) << 8) | port), 0, 0, NULL, NULL)); return( pUsb->ctrlReq(bAddress, 0, bmREQ_SET_PORT_FEATURE, USB_REQUEST_SET_FEATURE, fid, 0, (((0x0000 | sel) << 8) | port), 0, 0, NULL, NULL));
} }
void PrintHubPortStatus(USB *usbptr, uint8_t addr, uint8_t port, bool print_changes = false); void PrintHubPortStatus(USB *usbptr, uint8_t addr, uint8_t port, bool print_changes = false);

View file

@ -35,7 +35,7 @@ const uint8_t XBOXLEDS[] PROGMEM = {
0x04, // LED3 0x04, // LED3
0x05, // LED4 0x05, // LED4
0x01 // ALL - Used to blink all LEDs 0x01 // ALL - Used to blink all LEDs
}; };
/** Buttons on the controllers */ /** Buttons on the controllers */
const uint16_t XBOXBUTTONS[] PROGMEM = { const uint16_t XBOXBUTTONS[] PROGMEM = {
0x0100, // UP 0x0100, // UP
@ -48,7 +48,7 @@ const uint16_t XBOXBUTTONS[] PROGMEM = {
0x4000, // L3 0x4000, // L3
0x8000, // R3 0x8000, // R3
0,0, // Skip L2 and R2 as these are analog buttons 0, 0, // Skip L2 and R2 as these are analog buttons
0x0001, // L1 0x0001, // L1
0x0002, // R1 0x0002, // R1