mirror of
https://github.com/felis/USB_Host_Shield_2.0.git
synced 2024-03-22 11:31:26 +01:00
Clean up code formatting to industry standards.
This commit is contained in:
parent
9b224b9899
commit
904f2ff25a
42 changed files with 5429 additions and 5202 deletions
35
BTD.h
35
BTD.h
|
@ -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
291
PS3BT.cpp
|
@ -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
|
||||||
|
|
4
PS3BT.h
4
PS3BT.h
|
@ -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
|
||||||
|
|
15
PS3Enums.h
15
PS3Enums.h
|
@ -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,
|
||||||
|
|
170
PS3USB.cpp
170
PS3USB.cpp
|
@ -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;
|
||||||
}
|
}
|
12
PS3USB.h
12
PS3USB.h
|
@ -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
425
SPP.cpp
|
@ -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
62
SPP.h
|
@ -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:
|
||||||
|
|
6
Usb.cpp
6
Usb.cpp
|
@ -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
20
Usb.h
|
@ -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)
|
||||||
|
|
89
Wii.h
89
Wii.h
|
@ -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;
|
||||||
|
|
159
XBOXRECV.cpp
159
XBOXRECV.cpp
|
@ -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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
26
XBOXRECV.h
26
XBOXRECV.h
|
@ -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.
|
||||||
|
|
74
XBOXUSB.cpp
74
XBOXUSB.cpp
|
@ -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;
|
||||||
|
|
25
XBOXUSB.h
25
XBOXUSB.h
|
@ -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.
|
||||||
|
|
52
address.h
52
address.h
|
@ -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
15
adk.cpp
|
@ -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
6
adk.h
|
@ -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_
|
10
avrpins.h
10
avrpins.h
|
@ -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();
|
||||||
}
|
}
|
||||||
|
|
12
cdcacm.cpp
12
cdcacm.cpp
|
@ -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) {
|
||||||
|
|
12
cdcftdi.cpp
12
cdcftdi.cpp
|
@ -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++;
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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 */
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
2
hid.cpp
2
hid.cpp
|
@ -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;
|
||||||
|
|
12
hidboot.cpp
12
hidboot.cpp
|
@ -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);
|
||||||
|
|
60
hidboot.h
60
hidboot.h
|
@ -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;
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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);
|
||||||
|
|
||||||
|
|
12
masstorage.h
12
masstorage.h
|
@ -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
|
||||||
|
|
||||||
|
|
|
@ -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;
|
||||||
|
|
||||||
|
|
12
parsetools.h
12
parsetools.h
|
@ -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 {
|
||||||
|
|
22
printhex.h
22
printhex.h
|
@ -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;
|
||||||
|
|
12
usb_ch9.h
12
usb_ch9.h
|
@ -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_
|
||||||
|
|
56
usbhost.h
56
usbhost.h
|
@ -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()
|
||||||
|
|
14
usbhub.cpp
14
usbhub.cpp
|
@ -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)
|
||||||
|
|
24
usbhub.h
24
usbhub.h
|
@ -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);
|
||||||
|
|
|
@ -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
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue