Clean up code formatting to industry standards.

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

581
BTD.h
View file

@ -134,17 +134,17 @@
/** All Bluetooth services should include this class. */
class BluetoothService {
public:
/**
* Used to pass acldata to the Bluetooth service.
* @param ACLData Pointer to the incoming acldata.
*/
virtual void ACLData(uint8_t* ACLData);
/** Used to run the different state machines in the Bluetooth service. */
virtual void Run();
/** Used to reset the Bluetooth service. */
virtual void Reset();
/** Used to disconnect both the L2CAP Channel and the HCI Connection for the Bluetooth service. */
virtual void disconnect();
/**
* Used to pass acldata to the Bluetooth service.
* @param ACLData Pointer to the incoming acldata.
*/
virtual void ACLData(uint8_t* ACLData);
/** Used to run the different state machines in the Bluetooth service. */
virtual void Run();
/** Used to reset the Bluetooth service. */
virtual void Reset();
/** Used to disconnect both the L2CAP Channel and the HCI Connection for the Bluetooth service. */
virtual void disconnect();
};
/**
@ -153,299 +153,312 @@ public:
*/
class BTD : public USBDeviceConfig, public UsbConfigXtracter {
public:
/**
* Constructor for the BTD class.
* @param p Pointer to USB class instance.
*/
BTD(USB *p);
/**
* Constructor for the BTD class.
* @param p Pointer to USB class instance.
*/
BTD(USB *p);
/** @name USBDeviceConfig implementation */
/**
* Initialize the Bluetooth dongle.
* @param parent Hub number.
* @param port Port number on the hub.
* @param lowspeed Speed of the device.
* @return 0 on success.
*/
virtual uint8_t Init(uint8_t parent, uint8_t port, bool lowspeed);
/**
* Release the USB device.
* @return 0 on success.
*/
virtual uint8_t Release();
/**
* Poll the USB Input endpoins and run the state machines.
* @return 0 on success.
*/
virtual uint8_t Poll();
/**
* Get the device address.
* @return The device address.
*/
virtual uint8_t GetAddress() { return bAddress; };
/**
* Used to check if the dongle has been initialized.
* @return True if it's ready.
*/
virtual bool isReady() { return bPollEnable; };
/**@}*/
/** @name USBDeviceConfig implementation */
/**
* Initialize the Bluetooth dongle.
* @param parent Hub number.
* @param port Port number on the hub.
* @param lowspeed Speed of the device.
* @return 0 on success.
*/
virtual uint8_t Init(uint8_t parent, uint8_t port, bool lowspeed);
/**
* Release the USB device.
* @return 0 on success.
*/
virtual uint8_t Release();
/**
* Poll the USB Input endpoins and run the state machines.
* @return 0 on success.
*/
virtual uint8_t Poll();
/** @name UsbConfigXtracter implementation */
/**
* UsbConfigXtracter implementation, used to extract endpoint information.
* @param conf Configuration value.
* @param iface Interface number.
* @param alt Alternate setting.
* @param proto Interface Protocol.
* @param ep Endpoint Descriptor.
*/
virtual void EndpointXtract(uint8_t conf, uint8_t iface, uint8_t alt, uint8_t proto, const USB_ENDPOINT_DESCRIPTOR *ep);
/**@}*/
/**
* Get the device address.
* @return The device address.
*/
virtual uint8_t GetAddress() {
return bAddress;
};
/** Disconnects both the L2CAP Channel and the HCI Connection for all Bluetooth services. */
void disconnect() {
for (uint8_t i=0; i<BTD_NUMSERVICES; i++)
if (btService[i])
btService[i]->disconnect();
};
/**
* Register bluetooth dongle members/services.
* @param pService Pointer to BluetoothService class instance.
* @return The serice ID on succes or -1 on fail.
*/
int8_t registerServiceClass(BluetoothService *pService) {
for (uint8_t i=0; i<BTD_NUMSERVICES; i++) {
if (!btService[i]) {
btService[i] = pService;
return i; // Return ID
}
}
return -1; // ErrorregisterServiceClass
};
/**
* Used to check if the dongle has been initialized.
* @return True if it's ready.
*/
virtual bool isReady() {
return bPollEnable;
};
/**@}*/
/** @name HCI Commands */
/**
* Used to send a HCI Command.
* @param data Data to send.
* @param nbytes Number of bytes to send.
*/
void HCI_Command(uint8_t* data, uint16_t nbytes);
/** Reset the Bluetooth dongle. */
void hci_reset();
/** Read the Bluetooth address of the dongle. */
void hci_read_bdaddr();
/** Read the HCI Version of the Bluetooth dongle. */
void hci_read_local_version_information();
/**
* Set the local name of the Bluetooth dongle.
* @param name Desired name.
*/
void hci_set_local_name(const char* name);
/** Enable visibility to other Bluetooth devices. */
void hci_write_scan_enable();
/** Disable visibility to other Bluetooth devices. */
void hci_write_scan_disable();
/** Read the remote devices name. */
void hci_remote_name();
/** Accept the connection with the Bluetooth device. */
void hci_accept_connection();
/**
* Disconnect the HCI connection.
* @param handle The HCI Handle for the connection.
*/
void hci_disconnect(uint16_t handle);
/**
* Respond with the pin for the connection.
* The pin is automatically set for the Wii library,
* but can be customized for the SPP library.
*/
void hci_pin_code_request_reply();
/** Respons when no pin was set. */
void hci_pin_code_negative_request_reply();
/**
* Command is used to reply to a Link Key Request event from the BR/EDR Controller
* if the Host does not have a stored Link Key for the connection.
*/
void hci_link_key_request_negative_reply();
/** Used to try to authenticate with the remote device. */
void hci_authentication_request();
/** Start a HCI inquiry. */
void hci_inquiry();
/** Cancel a HCI inquiry. */
void hci_inquiry_cancel();
/** Connect to a device. */
void hci_connect();
/** Used to a set the class of the device. */
void hci_write_class_of_device();
/**@}*/
/** @name UsbConfigXtracter implementation */
/**
* UsbConfigXtracter implementation, used to extract endpoint information.
* @param conf Configuration value.
* @param iface Interface number.
* @param alt Alternate setting.
* @param proto Interface Protocol.
* @param ep Endpoint Descriptor.
*/
virtual void EndpointXtract(uint8_t conf, uint8_t iface, uint8_t alt, uint8_t proto, const USB_ENDPOINT_DESCRIPTOR *ep);
/**@}*/
/** @name L2CAP Commands */
/**
* Used to send L2CAP Commands.
* @param handle HCI Handle.
* @param data Data to send.
* @param nbytes Number of bytes to send.
* @param channelLow,channelHigh Low and high byte of channel to send to.
* If argument is omitted then the Standard L2CAP header: Channel ID (0x01) for ACL-U will be used.
*/
void L2CAP_Command(uint16_t handle, uint8_t* data, uint8_t nbytes, uint8_t channelLow = 0x01, uint8_t channelHigh = 0x00);
/**
* L2CAP Connection Request.
* @param handle HCI handle.
* @param rxid Identifier.
* @param scid Source Channel Identifier.
* @param psm Protocol/Service Multiplexer - see: https://www.bluetooth.org/Technical/AssignedNumbers/logical_link.htm.
*/
void l2cap_connection_request(uint16_t handle, uint8_t rxid, uint8_t* scid, uint16_t psm);
/**
* L2CAP Connection Response.
* @param handle HCI handle.
* @param rxid Identifier.
* @param dcid Destination Channel Identifier.
* @param scid Source Channel Identifier.
* @param result Result - First send ::PENDING and then ::SUCCESSFUL.
*/
void l2cap_connection_response(uint16_t handle, uint8_t rxid, uint8_t* dcid, uint8_t* scid, uint8_t result);
/**
* L2CAP Config Request.
* @param handle HCI Handle.
* @param rxid Identifier.
* @param dcid Destination Channel Identifier.
*/
void l2cap_config_request(uint16_t handle, uint8_t rxid, uint8_t* dcid);
/**
* L2CAP Config Response.
* @param handle HCI Handle.
* @param rxid Identifier.
* @param scid Source Channel Identifier.
*/
void l2cap_config_response(uint16_t handle, uint8_t rxid, uint8_t* scid);
/**
* L2CAP Disconnection Request.
* @param handle HCI Handle.
* @param rxid Identifier.
* @param dcid Device Channel Identifier.
* @param scid Source Channel Identifier.
*/
void l2cap_disconnection_request(uint16_t handle, uint8_t rxid, uint8_t* dcid, uint8_t* scid);
/**
* L2CAP Disconnection Response.
* @param handle HCI Handle.
* @param rxid Identifier.
* @param dcid Device Channel Identifier.
* @param scid Source Channel Identifier.
*/
void l2cap_disconnection_response(uint16_t handle, uint8_t rxid, uint8_t* dcid, uint8_t* scid);
/**
* L2CAP Information Response.
* @param handle HCI Handle.
* @param rxid Identifier.
* @param infoTypeLow,infoTypeHigh Infotype.
*/
void l2cap_information_response(uint16_t handle, uint8_t rxid, uint8_t infoTypeLow, uint8_t infoTypeHigh);
/**@}*/
/** Disconnects both the L2CAP Channel and the HCI Connection for all Bluetooth services. */
void disconnect() {
for(uint8_t i = 0; i < BTD_NUMSERVICES; i++)
if(btService[i])
btService[i]->disconnect();
};
/** Use this to see if it is waiting for a incoming connection. */
bool watingForConnection;
/** This is used by the service to know when to store the device information. */
bool l2capConnectionClaimed;
/** This is used by the SPP library to claim the current SDP incoming request. */
bool sdpConnectionClaimed;
/** This is used by the SPP library to claim the current RFCOMM incoming request. */
bool rfcommConnectionClaimed;
/**
* Register bluetooth dongle members/services.
* @param pService Pointer to BluetoothService class instance.
* @return The serice ID on succes or -1 on fail.
*/
int8_t registerServiceClass(BluetoothService *pService) {
for(uint8_t i = 0; i < BTD_NUMSERVICES; i++) {
if(!btService[i]) {
btService[i] = pService;
return i; // Return ID
}
}
return -1; // ErrorregisterServiceClass
};
/** The name you wish to make the dongle show up as. It is set automatically by the SPP library. */
const char* btdName;
/** The pin you wish to make the dongle use for authentication. It is set automatically by the SPP library. */
const char* btdPin;
/** @name HCI Commands */
/**
* Used to send a HCI Command.
* @param data Data to send.
* @param nbytes Number of bytes to send.
*/
void HCI_Command(uint8_t* data, uint16_t nbytes);
/** Reset the Bluetooth dongle. */
void hci_reset();
/** Read the Bluetooth address of the dongle. */
void hci_read_bdaddr();
/** Read the HCI Version of the Bluetooth dongle. */
void hci_read_local_version_information();
/**
* Set the local name of the Bluetooth dongle.
* @param name Desired name.
*/
void hci_set_local_name(const char* name);
/** Enable visibility to other Bluetooth devices. */
void hci_write_scan_enable();
/** Disable visibility to other Bluetooth devices. */
void hci_write_scan_disable();
/** Read the remote devices name. */
void hci_remote_name();
/** Accept the connection with the Bluetooth device. */
void hci_accept_connection();
/**
* Disconnect the HCI connection.
* @param handle The HCI Handle for the connection.
*/
void hci_disconnect(uint16_t handle);
/**
* Respond with the pin for the connection.
* The pin is automatically set for the Wii library,
* but can be customized for the SPP library.
*/
void hci_pin_code_request_reply();
/** Respons when no pin was set. */
void hci_pin_code_negative_request_reply();
/**
* Command is used to reply to a Link Key Request event from the BR/EDR Controller
* if the Host does not have a stored Link Key for the connection.
*/
void hci_link_key_request_negative_reply();
/** Used to try to authenticate with the remote device. */
void hci_authentication_request();
/** Start a HCI inquiry. */
void hci_inquiry();
/** Cancel a HCI inquiry. */
void hci_inquiry_cancel();
/** Connect to a device. */
void hci_connect();
/** Used to a set the class of the device. */
void hci_write_class_of_device();
/**@}*/
/** The bluetooth dongles Bluetooth address. */
uint8_t my_bdaddr[6];
/** HCI handle for the last connection. */
uint16_t hci_handle;
/** Last incoming devices Bluetooth address. */
uint8_t disc_bdaddr[6];
/** First 30 chars of last remote name. */
uint8_t remote_name[30];
/**
* The supported HCI Version read from the Bluetooth dongle.
* Used by the PS3BT library to check the HCI Version of the Bluetooth dongle,
* it should be at least 3 to work properly with the library.
*/
uint8_t hci_version;
/** Call this function to pair with a Wiimote */
void pairWithWiimote() { pairWithWii = true; hci_state = HCI_CHECK_WII_SERVICE; };
/** Used to only send the ACL data to the wiimote. */
bool connectToWii;
/** True if a Wiimote is connecting. */
bool incomingWii;
/** True when it should pair with the incoming Wiimote. */
bool pairWithWii;
/** True if it's the new Wiimote with the Motion Plus Inside or a Wii U Pro Controller. */
bool motionPlusInside;
/** True if it's a Wii U Pro Controller. */
bool wiiUProController;
/** @name L2CAP Commands */
/**
* Used to send L2CAP Commands.
* @param handle HCI Handle.
* @param data Data to send.
* @param nbytes Number of bytes to send.
* @param channelLow,channelHigh Low and high byte of channel to send to.
* If argument is omitted then the Standard L2CAP header: Channel ID (0x01) for ACL-U will be used.
*/
void L2CAP_Command(uint16_t handle, uint8_t* data, uint8_t nbytes, uint8_t channelLow = 0x01, uint8_t channelHigh = 0x00);
/**
* L2CAP Connection Request.
* @param handle HCI handle.
* @param rxid Identifier.
* @param scid Source Channel Identifier.
* @param psm Protocol/Service Multiplexer - see: https://www.bluetooth.org/Technical/AssignedNumbers/logical_link.htm.
*/
void l2cap_connection_request(uint16_t handle, uint8_t rxid, uint8_t* scid, uint16_t psm);
/**
* L2CAP Connection Response.
* @param handle HCI handle.
* @param rxid Identifier.
* @param dcid Destination Channel Identifier.
* @param scid Source Channel Identifier.
* @param result Result - First send ::PENDING and then ::SUCCESSFUL.
*/
void l2cap_connection_response(uint16_t handle, uint8_t rxid, uint8_t* dcid, uint8_t* scid, uint8_t result);
/**
* L2CAP Config Request.
* @param handle HCI Handle.
* @param rxid Identifier.
* @param dcid Destination Channel Identifier.
*/
void l2cap_config_request(uint16_t handle, uint8_t rxid, uint8_t* dcid);
/**
* L2CAP Config Response.
* @param handle HCI Handle.
* @param rxid Identifier.
* @param scid Source Channel Identifier.
*/
void l2cap_config_response(uint16_t handle, uint8_t rxid, uint8_t* scid);
/**
* L2CAP Disconnection Request.
* @param handle HCI Handle.
* @param rxid Identifier.
* @param dcid Device Channel Identifier.
* @param scid Source Channel Identifier.
*/
void l2cap_disconnection_request(uint16_t handle, uint8_t rxid, uint8_t* dcid, uint8_t* scid);
/**
* L2CAP Disconnection Response.
* @param handle HCI Handle.
* @param rxid Identifier.
* @param dcid Device Channel Identifier.
* @param scid Source Channel Identifier.
*/
void l2cap_disconnection_response(uint16_t handle, uint8_t rxid, uint8_t* dcid, uint8_t* scid);
/**
* L2CAP Information Response.
* @param handle HCI Handle.
* @param rxid Identifier.
* @param infoTypeLow,infoTypeHigh Infotype.
*/
void l2cap_information_response(uint16_t handle, uint8_t rxid, uint8_t infoTypeLow, uint8_t infoTypeHigh);
/**@}*/
/**
* Read the poll interval taken from the endpoint descriptors.
* @return The poll interval in ms.
*/
uint8_t readPollInterval() { return pollInterval; };
/** Use this to see if it is waiting for a incoming connection. */
bool watingForConnection;
/** This is used by the service to know when to store the device information. */
bool l2capConnectionClaimed;
/** This is used by the SPP library to claim the current SDP incoming request. */
bool sdpConnectionClaimed;
/** This is used by the SPP library to claim the current RFCOMM incoming request. */
bool rfcommConnectionClaimed;
/** The name you wish to make the dongle show up as. It is set automatically by the SPP library. */
const char* btdName;
/** The pin you wish to make the dongle use for authentication. It is set automatically by the SPP library. */
const char* btdPin;
/** The bluetooth dongles Bluetooth address. */
uint8_t my_bdaddr[6];
/** HCI handle for the last connection. */
uint16_t hci_handle;
/** Last incoming devices Bluetooth address. */
uint8_t disc_bdaddr[6];
/** First 30 chars of last remote name. */
uint8_t remote_name[30];
/**
* The supported HCI Version read from the Bluetooth dongle.
* Used by the PS3BT library to check the HCI Version of the Bluetooth dongle,
* it should be at least 3 to work properly with the library.
*/
uint8_t hci_version;
/** Call this function to pair with a Wiimote */
void pairWithWiimote() {
pairWithWii = true;
hci_state = HCI_CHECK_WII_SERVICE;
};
/** Used to only send the ACL data to the wiimote. */
bool connectToWii;
/** True if a Wiimote is connecting. */
bool incomingWii;
/** True when it should pair with the incoming Wiimote. */
bool pairWithWii;
/** True if it's the new Wiimote with the Motion Plus Inside or a Wii U Pro Controller. */
bool motionPlusInside;
/** True if it's a Wii U Pro Controller. */
bool wiiUProController;
/**
* Read the poll interval taken from the endpoint descriptors.
* @return The poll interval in ms.
*/
uint8_t readPollInterval() {
return pollInterval;
};
protected:
/** Pointer to USB class instance. */
USB *pUsb;
/** Device address. */
uint8_t bAddress;
/** Endpoint info structure. */
EpInfo epInfo[BTD_MAX_ENDPOINTS];
/** Pointer to USB class instance. */
USB *pUsb;
/** Device address. */
uint8_t bAddress;
/** Endpoint info structure. */
EpInfo epInfo[BTD_MAX_ENDPOINTS];
/** Configuration number. */
uint8_t bConfNum;
/** Total number of endpoints in the configuration. */
uint8_t bNumEP;
/** Next poll time based on poll interval taken from the USB descriptor. */
uint32_t qNextPollTime;
/** Configuration number. */
uint8_t bConfNum;
/** Total number of endpoints in the configuration. */
uint8_t bNumEP;
/** Next poll time based on poll interval taken from the USB descriptor. */
uint32_t qNextPollTime;
/** Bluetooth dongle control endpoint. */
static const uint8_t BTD_CONTROL_PIPE;
/** HCI event endpoint index. */
static const uint8_t BTD_EVENT_PIPE;
/** ACL In endpoint index. */
static const uint8_t BTD_DATAIN_PIPE;
/** ACL Out endpoint index. */
static const uint8_t BTD_DATAOUT_PIPE;
/** Bluetooth dongle control endpoint. */
static const uint8_t BTD_CONTROL_PIPE;
/** HCI event endpoint index. */
static const uint8_t BTD_EVENT_PIPE;
/** ACL In endpoint index. */
static const uint8_t BTD_DATAIN_PIPE;
/** ACL Out endpoint index. */
static const uint8_t BTD_DATAOUT_PIPE;
/**
* Used to print the USB Endpoint Descriptor.
* @param ep_ptr Pointer to USB Endpoint Descriptor.
*/
void PrintEndpointDescriptor(const USB_ENDPOINT_DESCRIPTOR* ep_ptr);
/**
* Used to print the USB Endpoint Descriptor.
* @param ep_ptr Pointer to USB Endpoint Descriptor.
*/
void PrintEndpointDescriptor(const USB_ENDPOINT_DESCRIPTOR* ep_ptr);
private:
BluetoothService* btService[BTD_NUMSERVICES];
BluetoothService* btService[BTD_NUMSERVICES];
bool bPollEnable;
uint8_t pollInterval;
bool bPollEnable;
uint8_t pollInterval;
/* Variables used by high level HCI task */
uint8_t hci_state; //current state of bluetooth hci connection
uint16_t hci_counter; // counter used for bluetooth hci reset loops
uint8_t hci_num_reset_loops; // this value indicate how many times it should read before trying to reset
uint16_t hci_event_flag; // hci flags of received bluetooth events
uint8_t inquiry_counter;
/* Variables used by high level HCI task */
uint8_t hci_state; //current state of bluetooth hci connection
uint16_t hci_counter; // counter used for bluetooth hci reset loops
uint8_t hci_num_reset_loops; // this value indicate how many times it should read before trying to reset
uint16_t hci_event_flag; // hci flags of received bluetooth events
uint8_t inquiry_counter;
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 l2capoutbuf[BULK_MAXPKTSIZE];//General purpose buffer for l2cap out 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 l2capoutbuf[BULK_MAXPKTSIZE]; //General purpose buffer for l2cap out data
/* State machines */
void HCI_event_task(); // Poll the HCI event pipe
void HCI_task(); // HCI state machine
void ACL_event_task(); // ACL input pipe
/* State machines */
void HCI_event_task(); // Poll the HCI event pipe
void HCI_task(); // HCI state machine
void ACL_event_task(); // ACL input pipe
/* Used to set the Bluetooth Address internally to the PS3 Controllers */
void setBdaddr(uint8_t* BDADDR);
void setMoveBdaddr(uint8_t* BDADDR);
/* Used to set the Bluetooth Address internally to the PS3 Controllers */
void setBdaddr(uint8_t* BDADDR);
void setMoveBdaddr(uint8_t* BDADDR);
};
#endif

1013
PS3BT.cpp

File diff suppressed because it is too large Load diff

322
PS3BT.h
View file

@ -65,182 +65,182 @@
*/
class PS3BT : public BluetoothService {
public:
/**
* Constructor for the PS3BT class.
* @param pBtd Pointer to BTD class instance.
* @param btadr5,btadr4,btadr3,btadr2,btadr1,btadr0
* 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.
*/
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);
/**
* Constructor for the PS3BT class.
* @param pBtd Pointer to BTD class instance.
* @param btadr5,btadr4,btadr3,btadr2,btadr1,btadr0
* 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.
*/
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 */
/**
* Used to pass acldata to the services.
* @param ACLData Incoming acldata.
*/
virtual void ACLData(uint8_t* ACLData);
/** Used to run part of the state maschine. */
virtual void Run();
/** Use this to reset the service. */
virtual void Reset();
/** Used this to disconnect any of the controllers. */
virtual void disconnect();
/**@}*/
/** @name BluetoothService implementation */
/**
* Used to pass acldata to the services.
* @param ACLData Incoming acldata.
*/
virtual void ACLData(uint8_t* ACLData);
/** Used to run part of the state maschine. */
virtual void Run();
/** Use this to reset the service. */
virtual void Reset();
/** Used this to disconnect any of the controllers. */
virtual void disconnect();
/**@}*/
/** @name PS3 Controller functions */
/**
* getButtonPress(Button b) will return true as long as the button is held down.
*
* While getButtonClick(Button b) will only return it once.
*
* So you instance if you need to increase a variable once you would use getButtonClick(Button b),
* but if you need to drive a robot forward you would use getButtonPress(Button b).
*/
bool getButtonPress(Button b);
bool getButtonClick(Button b);
/**@}*/
/** @name PS3 Controller functions */
/**
* Used to get the analog value from button presses.
* @param a The ::Button to read.
* The supported buttons are:
* ::UP, ::RIGHT, ::DOWN, ::LEFT, ::L1, ::L2, ::R1, ::R2,
* ::TRIANGLE, ::CIRCLE, ::CROSS, ::SQUARE, and ::T.
* @return Analog value in the range of 0-255.
*/
uint8_t getAnalogButton(Button a);
/**
* Used to read the analog joystick.
* @param a ::LeftHatX, ::LeftHatY, ::RightHatX, and ::RightHatY.
* @return Return the analog value in the range of 0-255.
*/
uint8_t getAnalogHat(AnalogHat a);
/**
* Used to read the sensors inside the Dualshock 3 and Move controller.
* @param a
* The Dualshock 3 has a 3-axis accelerometer and a 1-axis gyro inside.
* The Move controller has a 3-axis accelerometer, a 3-axis gyro, a 3-axis magnetometer
* and a temperature sensor inside.
* @return Return the raw sensor value.
*/
int16_t getSensor(Sensor a);
/**
* Use this to get ::Pitch and ::Roll calculated using the accelerometer.
* @param a Either ::Pitch or ::Roll.
* @return Return the angle in the range of 0-360.
*/
double getAngle(Angle a);
/**
* Read the sensors inside the Move controller.
* @param a ::aXmove, ::aYmove, ::aZmove, ::gXmove, ::gYmove, ::gZmove, ::mXmove, ::mYmove, and ::mXmove.
* @return The value in SI units.
*/
double get9DOFValues(Sensor a);
/**
* Get the ::Status from the controller.
* @param c The ::Status you want to read.
* @return True if correct and false if not.
*/
bool getStatus(Status c);
/**
* Read all the available ::Status from the controller.
* @return One large string with all the information.
*/
String getStatusString();
/**
* Read the temperature from the Move controller.
* @return The temperature in degrees celsius.
*/
String getTemperature();
/** @name PS3 Controller functions */
/**
* getButtonPress(Button b) will return true as long as the button is held down.
*
* While getButtonClick(Button b) will only return it once.
*
* So you instance if you need to increase a variable once you would use getButtonClick(Button b),
* but if you need to drive a robot forward you would use getButtonPress(Button b).
*/
bool getButtonPress(Button b);
bool getButtonClick(Button b);
/**@}*/
/** @name PS3 Controller functions */
/**
* Used to get the analog value from button presses.
* @param a The ::Button to read.
* The supported buttons are:
* ::UP, ::RIGHT, ::DOWN, ::LEFT, ::L1, ::L2, ::R1, ::R2,
* ::TRIANGLE, ::CIRCLE, ::CROSS, ::SQUARE, and ::T.
* @return Analog value in the range of 0-255.
*/
uint8_t getAnalogButton(Button a);
/**
* Used to read the analog joystick.
* @param a ::LeftHatX, ::LeftHatY, ::RightHatX, and ::RightHatY.
* @return Return the analog value in the range of 0-255.
*/
uint8_t getAnalogHat(AnalogHat a);
/**
* Used to read the sensors inside the Dualshock 3 and Move controller.
* @param a
* The Dualshock 3 has a 3-axis accelerometer and a 1-axis gyro inside.
* The Move controller has a 3-axis accelerometer, a 3-axis gyro, a 3-axis magnetometer
* and a temperature sensor inside.
* @return Return the raw sensor value.
*/
int16_t getSensor(Sensor a);
/**
* Use this to get ::Pitch and ::Roll calculated using the accelerometer.
* @param a Either ::Pitch or ::Roll.
* @return Return the angle in the range of 0-360.
*/
double getAngle(Angle a);
/**
* Read the sensors inside the Move controller.
* @param a ::aXmove, ::aYmove, ::aZmove, ::gXmove, ::gYmove, ::gZmove, ::mXmove, ::mYmove, and ::mXmove.
* @return The value in SI units.
*/
double get9DOFValues(Sensor a);
/**
* Get the ::Status from the controller.
* @param c The ::Status you want to read.
* @return True if correct and false if not.
*/
bool getStatus(Status c);
/**
* Read all the available ::Status from the controller.
* @return One large string with all the information.
*/
String getStatusString();
/**
* Read the temperature from the Move controller.
* @return The temperature in degrees celsius.
*/
String getTemperature();
/** Used to set all LEDs and ::Rumble off. */
void setAllOff();
/** Turn off ::Rumble. */
void setRumbleOff();
/**
* Turn on ::Rumble.
* @param mode Either ::RumbleHigh or ::RumbleLow.
*/
void setRumbleOn(Rumble mode);
/**
* Turn the specific ::LED off.
* @param a The ::LED to turn off.
*/
void setLedOff(LED a);
/**
* Turn the specific ::LED on.
* @param a The ::LED to turn on.
*/
void setLedOn(LED a);
/**
* Toggle the specific ::LED.
* @param a The ::LED to toggle.
*/
void setLedToggle(LED a);
/** Used to set all LEDs and ::Rumble off. */
void setAllOff();
/** Turn off ::Rumble. */
void setRumbleOff();
/**
* Turn on ::Rumble.
* @param mode Either ::RumbleHigh or ::RumbleLow.
*/
void setRumbleOn(Rumble mode);
/**
* Turn the specific ::LED off.
* @param a The ::LED to turn off.
*/
void setLedOff(LED a);
/**
* Turn the specific ::LED on.
* @param a The ::LED to turn on.
*/
void setLedOn(LED a);
/**
* Toggle the specific ::LED.
* @param a The ::LED to toggle.
*/
void setLedToggle(LED a);
/**
* Use this to set the Color using RGB values.
* @param r,g,b RGB value.
*/
void moveSetBulb(uint8_t r, uint8_t g, uint8_t b);
/**
* Use this to set the color using the predefined colors in ::Colors.
* @param color The desired color.
*/
void moveSetBulb(Colors color);
/**
* Set the rumble value inside the Move controller.
* @param rumble The desired value in the range from 64-255.
*/
void moveSetRumble(uint8_t rumble);
/**@}*/
/**
* Use this to set the Color using RGB values.
* @param r,g,b RGB value.
*/
void moveSetBulb(uint8_t r, uint8_t g, uint8_t b);
/**
* Use this to set the color using the predefined colors in ::Colors.
* @param color The desired color.
*/
void moveSetBulb(Colors color);
/**
* Set the rumble value inside the Move controller.
* @param rumble The desired value in the range from 64-255.
*/
void moveSetRumble(uint8_t rumble);
/**@}*/
/** Variable used to indicate if the normal playstation controller is successfully connected. */
bool PS3Connected;
/** Variable used to indicate if the move controller is successfully connected. */
bool PS3MoveConnected;
/** Variable used to indicate if the navigation controller is successfully connected. */
bool PS3NavigationConnected;
/** Variable used to indicate if the normal playstation controller is successfully connected. */
bool PS3Connected;
/** Variable used to indicate if the move controller is successfully connected. */
bool PS3MoveConnected;
/** Variable used to indicate if the navigation controller is successfully connected. */
bool PS3NavigationConnected;
private:
/* mandatory members */
BTD *pBtd;
/* mandatory members */
BTD *pBtd;
void L2CAP_task(); // L2CAP state machine
void L2CAP_task(); // L2CAP state machine
/* Variables filled from HCI event management */
int16_t hci_handle;
uint8_t remote_name[30]; // First 30 chars of remote name
bool activeConnection; // Used to indicate if it's already has established a connection
/* Variables filled from HCI event management */
int16_t hci_handle;
uint8_t remote_name[30]; // First 30 chars of remote name
bool activeConnection; // Used to indicate if it's already has established a connection
/* variables used by high level L2CAP task */
uint8_t l2cap_state;
uint16_t l2cap_event_flag; // L2CAP flags of received bluetooth events
/* variables used by high level L2CAP task */
uint8_t l2cap_state;
uint16_t l2cap_event_flag; // L2CAP flags of received bluetooth events
unsigned long timer;
unsigned long timer;
uint32_t ButtonState;
uint32_t OldButtonState;
uint32_t ButtonClickState;
uint32_t ButtonState;
uint32_t OldButtonState;
uint32_t ButtonClickState;
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 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
uint8_t l2capinbuf[BULK_MAXPKTSIZE]; // General purpose buffer for L2CAP in data
uint8_t HIDBuffer[HID_BUFFERSIZE]; // Used to store HID commands
uint8_t HIDMoveBuffer[HID_BUFFERSIZE]; // Used to store HID commands for the Move controller
uint8_t l2capinbuf[BULK_MAXPKTSIZE]; // General purpose buffer for L2CAP in data
uint8_t HIDBuffer[HID_BUFFERSIZE]; // Used to store HID commands
uint8_t HIDMoveBuffer[HID_BUFFERSIZE]; // Used to store HID commands for the Move controller
/* L2CAP Channels */
uint8_t control_scid[2]; // L2CAP source CID for HID_Control
uint8_t control_dcid[2]; // 0x0040
uint8_t interrupt_scid[2]; // L2CAP source CID for HID_Interrupt
uint8_t interrupt_dcid[2]; // 0x0041
uint8_t identifier; // Identifier for connection
/* L2CAP Channels */
uint8_t control_scid[2]; // L2CAP source CID for HID_Control
uint8_t control_dcid[2]; // 0x0040
uint8_t interrupt_scid[2]; // L2CAP source CID for HID_Interrupt
uint8_t interrupt_dcid[2]; // 0x0041
uint8_t identifier; // Identifier for connection
/* HID Commands */
void HID_Command(uint8_t* data, uint8_t nbytes);
void HIDMove_Command(uint8_t* data, uint8_t nbytes);
void enable_sixaxis(); // Command used to enable the Dualshock 3 and Navigation controller to send data via Bluetooth
/* HID Commands */
void HID_Command(uint8_t* data, uint8_t nbytes);
void HIDMove_Command(uint8_t* data, uint8_t nbytes);
void enable_sixaxis(); // Command used to enable the Dualshock 3 and Navigation controller to send data via Bluetooth
};
#endif

View file

@ -22,17 +22,17 @@
/** Used to set the LEDs on the controllers */
const uint8_t LEDS[] PROGMEM = {
0x01, // LED1
0x02, // LED2
0x04, // LED3
0x08, // LED4
0x01, // LED1
0x02, // LED2
0x04, // LED3
0x08, // LED4
0x09, // LED5
0x0A, // LED6
0x0C, // LED7
0x0D, // LED8
0x0E, // LED9
0x0F // LED10
0x09, // LED5
0x0A, // LED6
0x0C, // LED7
0x0D, // LED8
0x0E, // LED9
0x0F // LED10
};
/**
@ -41,29 +41,29 @@ const uint8_t LEDS[] PROGMEM = {
* <B>Note:</B> that the location is shiftet 9 when it's connected via USB.
*/
const uint32_t BUTTONS[] PROGMEM = {
0x10, // UP
0x20, // RIGHT
0x40, // DOWN
0x80, // LEFT
0x10, // UP
0x20, // RIGHT
0x40, // DOWN
0x80, // LEFT
0x01, // SELECT
0x08, // START
0x02, // L3
0x04, // R3
0x01, // SELECT
0x08, // START
0x02, // L3
0x04, // R3
0x0100, // L2
0x0200, // R2
0x0400, // L1
0x0800, // R1
0x0100, // L2
0x0200, // R2
0x0400, // L1
0x0800, // R1
0x1000, // TRIANGLE
0x2000, // CIRCLE
0x4000, // CROSS
0x8000, // SQUARE
0x1000, // TRIANGLE
0x2000, // CIRCLE
0x4000, // CROSS
0x8000, // SQUARE
0x010000, // PS
0x080000, // MOVE - covers 12 bits - we only need to read the top 8
0x100000 // T - covers 12 bits - we only need to read the top 8
0x010000, // PS
0x080000, // MOVE - covers 12 bits - we only need to read the top 8
0x100000 // T - covers 12 bits - we only need to read the top 8
};
/**
@ -72,46 +72,46 @@ const uint32_t BUTTONS[] PROGMEM = {
* <B>Note:</B> that the location is shiftet 9 when it's connected via USB.
*/
const uint8_t ANALOGBUTTONS[] PROGMEM = {
23, // UP_ANALOG
24, // RIGHT_ANALOG
25, // DOWN_ANALOG
26, // LEFT_ANALOG
0,0,0,0, // Skip SELECT, L3, R3 and START
23, // UP_ANALOG
24, // RIGHT_ANALOG
25, // DOWN_ANALOG
26, // LEFT_ANALOG
0, 0, 0, 0, // Skip SELECT, L3, R3 and START
27, // L2_ANALOG
28, // R2_ANALOG
29, // L1_ANALOG
30, // R1_ANALOG
31, // TRIANGLE_ANALOG
32, // CIRCLE_ANALOG
33, // CROSS_ANALOG
34, // SQUARE_ANALOG
0,0, // Skip PS and MOVE
27, // L2_ANALOG
28, // R2_ANALOG
29, // L1_ANALOG
30, // R1_ANALOG
31, // TRIANGLE_ANALOG
32, // CIRCLE_ANALOG
33, // CROSS_ANALOG
34, // SQUARE_ANALOG
0, 0, // Skip PS and MOVE
// Playstation Move Controller
15 // T_ANALOG - Both at byte 14 (last reading) and byte 15 (current reading)
// Playstation Move Controller
15 // T_ANALOG - Both at byte 14 (last reading) and byte 15 (current reading)
};
/** Used to set the colors of the move controller. */
enum Colors {
/** r = 255, g = 0, b = 0 */
Red = 0xFF0000,
/** r = 0, g = 255, b = 0 */
Green = 0xFF00,
/** r = 0, g = 0, b = 255 */
Blue = 0xFF,
/** r = 255, g = 0, b = 0 */
Red = 0xFF0000,
/** r = 0, g = 255, b = 0 */
Green = 0xFF00,
/** r = 0, g = 0, b = 255 */
Blue = 0xFF,
/** r = 255, g = 235, b = 4 */
Yellow = 0xFFEB04,
/** r = 0, g = 255, b = 255 */
Lightblue = 0xFFFF,
/** r = 255, g = 0, b = 255 */
Purble = 0xFF00FF,
/** r = 255, g = 235, b = 4 */
Yellow = 0xFFEB04,
/** r = 0, g = 255, b = 255 */
Lightblue = 0xFFFF,
/** r = 255, g = 0, b = 255 */
Purble = 0xFF00FF,
/** r = 255, g = 255, b = 255 */
White = 0xFFFFFF,
/** r = 0, g = 0, b = 0 */
Off = 0x00,
/** r = 255, g = 255, b = 255 */
White = 0xFFFFFF,
/** r = 0, g = 0, b = 0 */
Off = 0x00,
};
/**
@ -120,74 +120,77 @@ enum Colors {
* <B>Note:</B> that the location is shiftet 9 when it's connected via USB.
*/
enum Sensor {
/** Accelerometer x-axis */
aX = 50,
/** Accelerometer y-axis */
aY = 52,
/** Accelerometer z-axis */
aZ = 54,
/** Gyro z-axis */
gZ = 56,
/** Accelerometer x-axis */
aX = 50,
/** Accelerometer y-axis */
aY = 52,
/** Accelerometer z-axis */
aZ = 54,
/** Gyro z-axis */
gZ = 56,
/** Accelerometer x-axis */
aXmove = 28,
/** Accelerometer z-axis */
aZmove = 30,
/** Accelerometer y-axis */
aYmove = 32,
/** Accelerometer x-axis */
aXmove = 28,
/** Accelerometer z-axis */
aZmove = 30,
/** Accelerometer y-axis */
aYmove = 32,
/** Gyro x-axis */
gXmove = 40,
/** Gyro z-axis */
gZmove = 42,
/** Gyro y-axis */
gYmove = 44,
/** Gyro x-axis */
gXmove = 40,
/** Gyro z-axis */
gZmove = 42,
/** Gyro y-axis */
gYmove = 44,
/** Temperature sensor */
tempMove = 46,
/** Temperature sensor */
tempMove = 46,
/** Magnetometer x-axis */
mXmove = 47,
/** Magnetometer z-axis */
mZmove = 49,
/** Magnetometer y-axis */
mYmove = 50,
/** Magnetometer x-axis */
mXmove = 47,
/** Magnetometer z-axis */
mZmove = 49,
/** Magnetometer y-axis */
mYmove = 50,
};
/** Used to get the angle calculated using the accelerometer. */
enum Angle {
Pitch = 0x01,
Roll = 0x02,
Pitch = 0x01,
Roll = 0x02,
};
enum Status {
// Note that the location is shiftet 9 when it's connected via USB
// Byte location | bit location
Plugged = (38 << 8) | 0x02,
Unplugged = (38 << 8) | 0x03,
// Note that the location is shiftet 9 when it's connected via USB
// Byte location | bit location
Plugged = (38 << 8) | 0x02,
Unplugged = (38 << 8) | 0x03,
Charging = (39 << 8) | 0xEE,
NotCharging = (39 << 8) | 0xF1,
Shutdown = (39 << 8) | 0x01,
Dying = (39 << 8) | 0x02,
Low = (39 << 8) | 0x03,
High = (39 << 8) | 0x04,
Full = (39 << 8) | 0x05,
Charging = (39 << 8) | 0xEE,
NotCharging = (39 << 8) | 0xF1,
Shutdown = (39 << 8) | 0x01,
Dying = (39 << 8) | 0x02,
Low = (39 << 8) | 0x03,
High = (39 << 8) | 0x04,
Full = (39 << 8) | 0x05,
MoveCharging = (21 << 8) | 0xEE,
MoveNotCharging = (21 << 8) | 0xF1,
MoveShutdown = (21 << 8) | 0x01,
MoveDying = (21 << 8) | 0x02,
MoveLow = (21 << 8) | 0x03,
MoveHigh = (21 << 8) | 0x04,
MoveFull = (21 << 8) | 0x05,
MoveCharging = (21 << 8) | 0xEE,
MoveNotCharging = (21 << 8) | 0xF1,
MoveShutdown = (21 << 8) | 0x01,
MoveDying = (21 << 8) | 0x02,
MoveLow = (21 << 8) | 0x03,
MoveHigh = (21 << 8) | 0x04,
MoveFull = (21 << 8) | 0x05,
CableRumble = (40 << 8) | 0x10,//Opperating by USB and rumble is turned on
Cable = (40 << 8) | 0x12,//Opperating by USB and rumble is turned off
BluetoothRumble = (40 << 8) | 0x14,//Opperating by bluetooth and rumble is turned on
Bluetooth = (40 << 8) | 0x16,//Opperating by bluetooth and rumble is turned off
CableRumble = (40 << 8) | 0x10, //Opperating by USB and rumble is turned on
Cable = (40 << 8) | 0x12, //Opperating by USB and rumble is turned off
BluetoothRumble = (40 << 8) | 0x14, //Opperating by bluetooth and rumble is turned on
Bluetooth = (40 << 8) | 0x16, //Opperating by bluetooth and rumble is turned off
};
enum Rumble {
RumbleHigh = 0x10,
RumbleLow = 0x20,
RumbleHigh = 0x10,
RumbleLow = 0x20,
};
#endif

View file

@ -21,531 +21,547 @@
//#define PRINTREPORT // Uncomment to print the report send by the PS3 Controllers
const uint8_t PS3_REPORT_BUFFER[] PROGMEM = {
0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00,
0xff, 0x27, 0x10, 0x00, 0x32,
0xff, 0x27, 0x10, 0x00, 0x32,
0xff, 0x27, 0x10, 0x00, 0x32,
0xff, 0x27, 0x10, 0x00, 0x32,
0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00,
0xff, 0x27, 0x10, 0x00, 0x32,
0xff, 0x27, 0x10, 0x00, 0x32,
0xff, 0x27, 0x10, 0x00, 0x32,
0xff, 0x27, 0x10, 0x00, 0x32,
0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
};
const uint8_t MOVE_REPORT_BUFFER[] PROGMEM = {
0x02, 0x00, // Always 0x02, 0x00,
0x00, 0x00, 0x00, // r, g, b,
0x00, // Always 0x00,
0x00 // Rumble
0x02, 0x00, // Always 0x02, 0x00,
0x00, 0x00, 0x00, // r, g, b,
0x00, // Always 0x00,
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
bAddress(0), // device address - mandatory
bPollEnable(false) // don't start polling before dongle is connected
{
for(uint8_t i=0; i<PS3_MAX_ENDPOINTS; i++) {
epInfo[i].epAddr = 0;
epInfo[i].maxPktSize = (i) ? 0 : 8;
epInfo[i].epAttribs = 0;
epInfo[i].bmNakPower = (i) ? USB_NAK_NOWAIT : USB_NAK_MAX_POWER;
}
for (uint8_t i = 0; i < PS3_MAX_ENDPOINTS; i++) {
epInfo[i].epAddr = 0;
epInfo[i].maxPktSize = (i) ? 0 : 8;
epInfo[i].epAttribs = 0;
epInfo[i].bmNakPower = (i) ? USB_NAK_NOWAIT : USB_NAK_MAX_POWER;
}
if (pUsb) // register in USB subsystem
pUsb->RegisterDeviceClass(this); //set devConfig[] entry
if (pUsb) // register in USB subsystem
pUsb->RegisterDeviceClass(this); //set devConfig[] entry
my_bdaddr[5] = btadr5; // Change to your dongle's Bluetooth address instead
my_bdaddr[4] = btadr4;
my_bdaddr[3] = btadr3;
my_bdaddr[2] = btadr2;
my_bdaddr[1] = btadr1;
my_bdaddr[0] = btadr0;
my_bdaddr[5] = btadr5; // Change to your dongle's Bluetooth address instead
my_bdaddr[4] = btadr4;
my_bdaddr[3] = btadr3;
my_bdaddr[2] = btadr2;
my_bdaddr[1] = btadr1;
my_bdaddr[0] = btadr0;
}
uint8_t PS3USB::Init(uint8_t parent, uint8_t port, bool lowspeed) {
uint8_t buf[sizeof(USB_DEVICE_DESCRIPTOR)];
uint8_t rcode;
UsbDevice *p = NULL;
EpInfo *oldep_ptr = NULL;
uint16_t PID;
uint16_t VID;
uint8_t buf[sizeof (USB_DEVICE_DESCRIPTOR)];
uint8_t rcode;
UsbDevice *p = NULL;
EpInfo *oldep_ptr = NULL;
uint16_t PID;
uint16_t VID;
// get memory address of USB device address pool
AddressPool &addrPool = pUsb->GetAddressPool();
// get memory address of USB device address pool
AddressPool &addrPool = pUsb->GetAddressPool();
#ifdef EXTRADEBUG
Notify(PSTR("\r\nPS3USB Init"), 0x80);
Notify(PSTR("\r\nPS3USB Init"), 0x80);
#endif
// check if address has already been assigned to an instance
if (bAddress) {
// check if address has already been assigned to an instance
if (bAddress) {
#ifdef DEBUG
Notify(PSTR("\r\nAddress in use"), 0x80);
Notify(PSTR("\r\nAddress in use"), 0x80);
#endif
return USB_ERROR_CLASS_INSTANCE_ALREADY_IN_USE;
}
// Get pointer to pseudo device with address 0 assigned
p = addrPool.GetUsbDevicePtr(0);
if (!p) {
#ifdef DEBUG
Notify(PSTR("\r\nAddress not found"), 0x80);
#endif
return USB_ERROR_ADDRESS_NOT_FOUND_IN_POOL;
}
if (!p->epinfo) {
#ifdef DEBUG
Notify(PSTR("\r\nepinfo is null"), 0x80);
#endif
return USB_ERROR_EPINFO_IS_NULL;
}
// Save old pointer to EP_RECORD of address 0
oldep_ptr = p->epinfo;
// Temporary assign new pointer to epInfo to p->epinfo in order to avoid toggle inconsistence
p->epinfo = epInfo;
p->lowspeed = lowspeed;
// Get device descriptor
rcode = pUsb->getDevDescr(0, 0, sizeof(USB_DEVICE_DESCRIPTOR), (uint8_t*)buf);// Get device descriptor - addr, ep, nbytes, data
// Restore p->epinfo
p->epinfo = oldep_ptr;
if(rcode)
goto FailGetDevDescr;
VID = ((USB_DEVICE_DESCRIPTOR*)buf)->idVendor;
PID = ((USB_DEVICE_DESCRIPTOR*)buf)->idProduct;
if(VID != PS3_VID || (PID != PS3_PID && PID != PS3NAVIGATION_PID && PID != PS3MOVE_PID))
goto FailUnknownDevice;
// Allocate new address according to device class
bAddress = addrPool.AllocAddress(parent, false, port);
if (!bAddress)
return USB_ERROR_OUT_OF_ADDRESS_SPACE_IN_POOL;
// Extract Max Packet Size from device descriptor
epInfo[0].maxPktSize = (uint8_t)((USB_DEVICE_DESCRIPTOR*)buf)->bMaxPacketSize0;
// Assign new address to the device
rcode = pUsb->setAddr( 0, 0, bAddress );
if (rcode) {
p->lowspeed = false;
addrPool.FreeAddress(bAddress);
bAddress = 0;
#ifdef DEBUG
Notify(PSTR("\r\nsetAddr: "), 0x80);
#endif
PrintHex<uint8_t>(rcode, 0x80);
return rcode;
}
#ifdef EXTRADEBUG
Notify(PSTR("\r\nAddr: "), 0x80);
PrintHex<uint8_t>(bAddress, 0x80);
#endif
p->lowspeed = false;
//get pointer to assigned address record
p = addrPool.GetUsbDevicePtr(bAddress);
if (!p)
return USB_ERROR_ADDRESS_NOT_FOUND_IN_POOL;
p->lowspeed = lowspeed;
// Assign epInfo to epinfo pointer - only EP0 is known
rcode = pUsb->setEpInfoEntry(bAddress, 1, epInfo);
if (rcode)
goto FailSetDevTblEntry;
/* The application will work in reduced host mode, so we can save program and data
memory space. After verifying the PID and VID we will use known values for the
configuration values for device, interface, endpoints and HID for the PS3 Controllers */
/* Initialize data structures for endpoints of device */
epInfo[ PS3_OUTPUT_PIPE ].epAddr = 0x02; // PS3 output endpoint
epInfo[ PS3_OUTPUT_PIPE ].epAttribs = EP_INTERRUPT;
epInfo[ PS3_OUTPUT_PIPE ].bmNakPower = USB_NAK_NOWAIT; // Only poll once for interrupt endpoints
epInfo[ PS3_OUTPUT_PIPE ].maxPktSize = EP_MAXPKTSIZE;
epInfo[ PS3_OUTPUT_PIPE ].bmSndToggle = bmSNDTOG0;
epInfo[ PS3_OUTPUT_PIPE ].bmRcvToggle = bmRCVTOG0;
epInfo[ PS3_INPUT_PIPE ].epAddr = 0x01; // PS3 report endpoint
epInfo[ PS3_INPUT_PIPE ].epAttribs = EP_INTERRUPT;
epInfo[ PS3_INPUT_PIPE ].bmNakPower = USB_NAK_NOWAIT; // Only poll once for interrupt endpoints
epInfo[ PS3_INPUT_PIPE ].maxPktSize = EP_MAXPKTSIZE;
epInfo[ PS3_INPUT_PIPE ].bmSndToggle = bmSNDTOG0;
epInfo[ PS3_INPUT_PIPE ].bmRcvToggle = bmRCVTOG0;
rcode = pUsb->setEpInfoEntry(bAddress, 3, epInfo);
if( rcode )
goto FailSetDevTblEntry;
delay(200);//Give time for address change
rcode = pUsb->setConf(bAddress, epInfo[ PS3_CONTROL_PIPE ].epAddr, 1);
if( rcode )
goto FailSetConf;
if(PID == PS3_PID || PID == PS3NAVIGATION_PID) {
if(PID == PS3_PID) {
#ifdef DEBUG
Notify(PSTR("\r\nDualshock 3 Controller Connected"), 0x80);
#endif
PS3Connected = true;
} else { // must be a navigation controller
#ifdef DEBUG
Notify(PSTR("\r\nNavigation Controller Connected"), 0x80);
#endif
PS3NavigationConnected = true;
return USB_ERROR_CLASS_INSTANCE_ALREADY_IN_USE;
}
/* Set internal bluetooth address and request for data */
setBdaddr(my_bdaddr);
enable_sixaxis();
setLedOn(LED1);
// Needed for PS3 Dualshock and Navigation commands to work
for (uint8_t i = 0; i < PS3_REPORT_BUFFER_SIZE; i++)
writeBuf[i] = pgm_read_byte(&PS3_REPORT_BUFFER[i]);
// Get pointer to pseudo device with address 0 assigned
p = addrPool.GetUsbDevicePtr(0);
for (uint8_t i = 6; i < 10; i++)
readBuf[i] = 0x7F; // Set the analog joystick values to center position
}
else { // must be a Motion controller
if (!p) {
#ifdef DEBUG
Notify(PSTR("\r\nMotion Controller Connected"), 0x80);
Notify(PSTR("\r\nAddress not found"), 0x80);
#endif
PS3MoveConnected = true;
setMoveBdaddr(my_bdaddr); // Set internal bluetooth address
moveSetBulb(Red);
return USB_ERROR_ADDRESS_NOT_FOUND_IN_POOL;
}
// Needed for Move commands to work
for (uint8_t i = 0; i < MOVE_REPORT_BUFFER_SIZE; i++)
writeBuf[i] = pgm_read_byte(&MOVE_REPORT_BUFFER[i]);
}
if (!p->epinfo) {
#ifdef DEBUG
Notify(PSTR("\r\nepinfo is null"), 0x80);
#endif
return USB_ERROR_EPINFO_IS_NULL;
}
bPollEnable = true;
Notify(PSTR("\r\n"), 0x80);
timer = millis();
return 0; // successful configuration
// Save old pointer to EP_RECORD of address 0
oldep_ptr = p->epinfo;
/* diagnostic messages */
// Temporary assign new pointer to epInfo to p->epinfo in order to avoid toggle inconsistence
p->epinfo = epInfo;
p->lowspeed = lowspeed;
// Get device descriptor
rcode = pUsb->getDevDescr(0, 0, sizeof (USB_DEVICE_DESCRIPTOR), (uint8_t*)buf); // Get device descriptor - addr, ep, nbytes, data
// Restore p->epinfo
p->epinfo = oldep_ptr;
if (rcode)
goto FailGetDevDescr;
VID = ((USB_DEVICE_DESCRIPTOR*)buf)->idVendor;
PID = ((USB_DEVICE_DESCRIPTOR*)buf)->idProduct;
if (VID != PS3_VID || (PID != PS3_PID && PID != PS3NAVIGATION_PID && PID != PS3MOVE_PID))
goto FailUnknownDevice;
// Allocate new address according to device class
bAddress = addrPool.AllocAddress(parent, false, port);
if (!bAddress)
return USB_ERROR_OUT_OF_ADDRESS_SPACE_IN_POOL;
// Extract Max Packet Size from device descriptor
epInfo[0].maxPktSize = (uint8_t)((USB_DEVICE_DESCRIPTOR*)buf)->bMaxPacketSize0;
// Assign new address to the device
rcode = pUsb->setAddr(0, 0, bAddress);
if (rcode) {
p->lowspeed = false;
addrPool.FreeAddress(bAddress);
bAddress = 0;
#ifdef DEBUG
Notify(PSTR("\r\nsetAddr: "), 0x80);
#endif
PrintHex<uint8_t > (rcode, 0x80);
return rcode;
}
#ifdef EXTRADEBUG
Notify(PSTR("\r\nAddr: "), 0x80);
PrintHex<uint8_t > (bAddress, 0x80);
#endif
p->lowspeed = false;
//get pointer to assigned address record
p = addrPool.GetUsbDevicePtr(bAddress);
if (!p)
return USB_ERROR_ADDRESS_NOT_FOUND_IN_POOL;
p->lowspeed = lowspeed;
// Assign epInfo to epinfo pointer - only EP0 is known
rcode = pUsb->setEpInfoEntry(bAddress, 1, epInfo);
if (rcode)
goto FailSetDevTblEntry;
/* The application will work in reduced host mode, so we can save program and data
memory space. After verifying the PID and VID we will use known values for the
configuration values for device, interface, endpoints and HID for the PS3 Controllers */
/* Initialize data structures for endpoints of device */
epInfo[ PS3_OUTPUT_PIPE ].epAddr = 0x02; // PS3 output endpoint
epInfo[ PS3_OUTPUT_PIPE ].epAttribs = EP_INTERRUPT;
epInfo[ PS3_OUTPUT_PIPE ].bmNakPower = USB_NAK_NOWAIT; // Only poll once for interrupt endpoints
epInfo[ PS3_OUTPUT_PIPE ].maxPktSize = EP_MAXPKTSIZE;
epInfo[ PS3_OUTPUT_PIPE ].bmSndToggle = bmSNDTOG0;
epInfo[ PS3_OUTPUT_PIPE ].bmRcvToggle = bmRCVTOG0;
epInfo[ PS3_INPUT_PIPE ].epAddr = 0x01; // PS3 report endpoint
epInfo[ PS3_INPUT_PIPE ].epAttribs = EP_INTERRUPT;
epInfo[ PS3_INPUT_PIPE ].bmNakPower = USB_NAK_NOWAIT; // Only poll once for interrupt endpoints
epInfo[ PS3_INPUT_PIPE ].maxPktSize = EP_MAXPKTSIZE;
epInfo[ PS3_INPUT_PIPE ].bmSndToggle = bmSNDTOG0;
epInfo[ PS3_INPUT_PIPE ].bmRcvToggle = bmRCVTOG0;
rcode = pUsb->setEpInfoEntry(bAddress, 3, epInfo);
if (rcode)
goto FailSetDevTblEntry;
delay(200); //Give time for address change
rcode = pUsb->setConf(bAddress, epInfo[ PS3_CONTROL_PIPE ].epAddr, 1);
if (rcode)
goto FailSetConf;
if (PID == PS3_PID || PID == PS3NAVIGATION_PID) {
if (PID == PS3_PID) {
#ifdef DEBUG
Notify(PSTR("\r\nDualshock 3 Controller Connected"), 0x80);
#endif
PS3Connected = true;
} else { // must be a navigation controller
#ifdef DEBUG
Notify(PSTR("\r\nNavigation Controller Connected"), 0x80);
#endif
PS3NavigationConnected = true;
}
/* Set internal bluetooth address and request for data */
setBdaddr(my_bdaddr);
enable_sixaxis();
setLedOn(LED1);
// Needed for PS3 Dualshock and Navigation commands to work
for (uint8_t i = 0; i < PS3_REPORT_BUFFER_SIZE; i++)
writeBuf[i] = pgm_read_byte(&PS3_REPORT_BUFFER[i]);
for (uint8_t i = 6; i < 10; i++)
readBuf[i] = 0x7F; // Set the analog joystick values to center position
} else { // must be a Motion controller
#ifdef DEBUG
Notify(PSTR("\r\nMotion Controller Connected"), 0x80);
#endif
PS3MoveConnected = true;
setMoveBdaddr(my_bdaddr); // Set internal bluetooth address
moveSetBulb(Red);
// Needed for Move commands to work
for (uint8_t i = 0; i < MOVE_REPORT_BUFFER_SIZE; i++)
writeBuf[i] = pgm_read_byte(&MOVE_REPORT_BUFFER[i]);
}
bPollEnable = true;
Notify(PSTR("\r\n"), 0x80);
timer = millis();
return 0; // successful configuration
/* diagnostic messages */
FailGetDevDescr:
#ifdef DEBUG
Notify(PSTR("\r\ngetDevDescr:"), 0x80);
Notify(PSTR("\r\ngetDevDescr:"), 0x80);
#endif
goto Fail;
goto Fail;
FailSetDevTblEntry:
#ifdef DEBUG
Notify(PSTR("\r\nsetDevTblEn:"), 0x80);
Notify(PSTR("\r\nsetDevTblEn:"), 0x80);
#endif
goto Fail;
goto Fail;
FailSetConf:
#ifdef DEBUG
Notify(PSTR("\r\nsetConf:"), 0x80);
Notify(PSTR("\r\nsetConf:"), 0x80);
#endif
goto Fail;
goto Fail;
FailUnknownDevice:
#ifdef DEBUG
Notify(PSTR("\r\nUnknown Device Connected - VID: "), 0x80);
PrintHex<uint16_t>(VID, 0x80);
Notify(PSTR(" PID: "), 0x80);
PrintHex<uint16_t>(PID, 0x80);
Notify(PSTR("\r\nUnknown Device Connected - VID: "), 0x80);
PrintHex<uint16_t > (VID, 0x80);
Notify(PSTR(" PID: "), 0x80);
PrintHex<uint16_t > (PID, 0x80);
#endif
rcode = USB_DEV_CONFIG_ERROR_DEVICE_NOT_SUPPORTED;
goto Fail;
rcode = USB_DEV_CONFIG_ERROR_DEVICE_NOT_SUPPORTED;
goto Fail;
Fail:
#ifdef DEBUG
Notify(PSTR("\r\nPS3 Init Failed, error code: "), 0x80);
Serial.print(rcode,HEX);
Notify(PSTR("\r\nPS3 Init Failed, error code: "), 0x80);
Serial.print(rcode, HEX);
#endif
Release();
return rcode;
Release();
return rcode;
}
/* Performs a cleanup after failed Init() attempt */
uint8_t PS3USB::Release() {
PS3Connected = false;
PS3MoveConnected = false;
PS3NavigationConnected = false;
pUsb->GetAddressPool().FreeAddress(bAddress);
bAddress = 0;
bPollEnable = false;
return 0;
PS3Connected = false;
PS3MoveConnected = false;
PS3NavigationConnected = false;
pUsb->GetAddressPool().FreeAddress(bAddress);
bAddress = 0;
bPollEnable = false;
return 0;
}
uint8_t PS3USB::Poll() {
if (!bPollEnable)
return 0;
if(PS3Connected || PS3NavigationConnected) {
uint16_t BUFFER_SIZE = EP_MAXPKTSIZE;
pUsb->inTransfer(bAddress, epInfo[ PS3_INPUT_PIPE ].epAddr, &BUFFER_SIZE, readBuf); // input on endpoint 1
if(millis() - timer > 100) { // Loop 100ms before processing data
readReport();
uint8_t PS3USB::Poll() {
if (!bPollEnable)
return 0;
if (PS3Connected || PS3NavigationConnected) {
uint16_t BUFFER_SIZE = EP_MAXPKTSIZE;
pUsb->inTransfer(bAddress, epInfo[ PS3_INPUT_PIPE ].epAddr, &BUFFER_SIZE, readBuf); // input on endpoint 1
if (millis() - timer > 100) { // Loop 100ms before processing data
readReport();
#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
}
} 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
{
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
timer = millis();
}
}
}
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
{
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
timer = millis();
}
}
return 0;
return 0;
}
void PS3USB::readReport() {
if (readBuf == NULL)
return;
if (readBuf == NULL)
return;
ButtonState = (uint32_t)(readBuf[2] | ((uint16_t)readBuf[3] << 8) | ((uint32_t)readBuf[4] << 16));
ButtonState = (uint32_t)(readBuf[2] | ((uint16_t)readBuf[3] << 8) | ((uint32_t)readBuf[4] << 16));
//Notify(PSTR("\r\nButtonState", 0x80);
//PrintHex<uint32_t>(ButtonState, 0x80);
//Notify(PSTR("\r\nButtonState", 0x80);
//PrintHex<uint32_t>(ButtonState, 0x80);
if(ButtonState != OldButtonState) {
ButtonClickState = ButtonState & ~OldButtonState; // Update click state variable
OldButtonState = ButtonState;
}
if (ButtonState != OldButtonState) {
ButtonClickState = ButtonState & ~OldButtonState; // Update click state variable
OldButtonState = ButtonState;
}
}
void PS3USB::printReport() { //Uncomment "#define PRINTREPORT" to print the report send by the PS3 Controllers
#ifdef PRINTREPORT
if (readBuf == NULL)
return;
for(uint8_t i = 0; i < PS3_REPORT_BUFFER_SIZE;i++) {
PrintHex<uint8_t>(readBuf[i], 0x80);
Serial.print(" ");
}
Serial.println();
if (readBuf == NULL)
return;
for (uint8_t i = 0; i < PS3_REPORT_BUFFER_SIZE; i++) {
PrintHex<uint8_t > (readBuf[i], 0x80);
Serial.print(" ");
}
Serial.println();
#endif
}
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) {
uint32_t button = pgm_read_dword(&BUTTONS[(uint8_t)b]);
bool click = (ButtonClickState & button);
ButtonClickState &= ~button; // clear "click" event
return click;
uint32_t button = pgm_read_dword(&BUTTONS[(uint8_t)b]);
bool click = (ButtonClickState & button);
ButtonClickState &= ~button; // clear "click" event
return click;
}
uint8_t PS3USB::getAnalogButton(Button a) {
if (readBuf == NULL)
return 0;
return (uint8_t)(readBuf[(pgm_read_byte(&ANALOGBUTTONS[(uint8_t)a]))-9]);
if (readBuf == NULL)
return 0;
return (uint8_t)(readBuf[(pgm_read_byte(&ANALOGBUTTONS[(uint8_t)a])) - 9]);
}
uint8_t PS3USB::getAnalogHat(AnalogHat a) {
if (readBuf == NULL)
return 0;
return (uint8_t)(readBuf[((uint8_t)a+6)]);
if (readBuf == NULL)
return 0;
return (uint8_t)(readBuf[((uint8_t)a + 6)]);
}
uint16_t PS3USB::getSensor(Sensor a) {
if (readBuf == NULL)
return 0;
return ((readBuf[((uint16_t)a)-9] << 8) | readBuf[((uint16_t)a + 1)-9]);
if (readBuf == NULL)
return 0;
return ((readBuf[((uint16_t)a) - 9] << 8) | readBuf[((uint16_t)a + 1) - 9]);
}
double PS3USB::getAngle(Angle a) {
if(PS3Connected) {
double accXval;
double accYval;
double accZval;
if (PS3Connected) {
double accXval;
double accYval;
double accZval;
// Data for the Kionix KXPC4 used in the DualShock 3
const double zeroG = 511.5; // 1.65/3.3*1023 (1,65V)
accXval = -((double)getSensor(aX)-zeroG);
accYval = -((double)getSensor(aY)-zeroG);
accZval = -((double)getSensor(aZ)-zeroG);
// Data for the Kionix KXPC4 used in the DualShock 3
const double zeroG = 511.5; // 1.65/3.3*1023 (1,65V)
accXval = -((double)getSensor(aX) - zeroG);
accYval = -((double)getSensor(aY) - zeroG);
accZval = -((double)getSensor(aZ) - zeroG);
// Convert to 360 degrees resolution
// atan2 outputs the value of -π to π (radians)
// We are then converting it to 0 to 2π and then to degrees
if (a == Pitch) {
double angle = (atan2(accYval,accZval)+PI)*RAD_TO_DEG;
return angle;
} else {
double angle = (atan2(accXval,accZval)+PI)*RAD_TO_DEG;
return angle;
}
} else
return 0;
// Convert to 360 degrees resolution
// atan2 outputs the value of -π to π (radians)
// We are then converting it to 0 to 2π and then to degrees
if (a == Pitch) {
double angle = (atan2(accYval, accZval) + PI) * RAD_TO_DEG;
return angle;
} else {
double angle = (atan2(accXval, accZval) + PI) * RAD_TO_DEG;
return angle;
}
} else
return 0;
}
bool PS3USB::getStatus(Status c) {
if (readBuf == NULL)
if (readBuf == NULL)
return false;
if (readBuf[((uint16_t)c >> 8) - 9] == ((uint8_t)c & 0xff))
return true;
return false;
if (readBuf[((uint16_t)c >> 8)-9] == ((uint8_t)c & 0xff))
return true;
return false;
}
String PS3USB::getStatusString() {
if (PS3Connected || PS3NavigationConnected) {
char statusOutput[100];
if (PS3Connected || PS3NavigationConnected) {
char statusOutput[100];
strcpy(statusOutput,"ConnectionStatus: ");
strcpy(statusOutput, "ConnectionStatus: ");
if (getStatus(Plugged)) strcat(statusOutput,"Plugged");
else if (getStatus(Unplugged)) strcat(statusOutput,"Unplugged");
else strcat(statusOutput,"Error");
if (getStatus(Plugged)) strcat(statusOutput, "Plugged");
else if (getStatus(Unplugged)) strcat(statusOutput, "Unplugged");
else strcat(statusOutput, "Error");
strcat(statusOutput," - PowerRating: ");
strcat(statusOutput, " - PowerRating: ");
if (getStatus(Charging)) strcat(statusOutput,"Charging");
else if (getStatus(NotCharging)) strcat(statusOutput,"Not Charging");
else if (getStatus(Shutdown)) strcat(statusOutput,"Shutdown");
else if (getStatus(Dying)) strcat(statusOutput,"Dying");
else if (getStatus(Low)) strcat(statusOutput,"Low");
else if (getStatus(High)) strcat(statusOutput,"High");
else if (getStatus(Full)) strcat(statusOutput,"Full");
else strcat(statusOutput,"Error");
if (getStatus(Charging)) strcat(statusOutput, "Charging");
else if (getStatus(NotCharging)) strcat(statusOutput, "Not Charging");
else if (getStatus(Shutdown)) strcat(statusOutput, "Shutdown");
else if (getStatus(Dying)) strcat(statusOutput, "Dying");
else if (getStatus(Low)) strcat(statusOutput, "Low");
else if (getStatus(High)) strcat(statusOutput, "High");
else if (getStatus(Full)) strcat(statusOutput, "Full");
else strcat(statusOutput, "Error");
strcat(statusOutput," - WirelessStatus: ");
strcat(statusOutput, " - WirelessStatus: ");
if (getStatus(CableRumble)) strcat(statusOutput,"Cable - Rumble is on");
else if (getStatus(Cable)) strcat(statusOutput,"Cable - Rumble is off");
else if (getStatus(BluetoothRumble)) strcat(statusOutput,"Bluetooth - Rumble is on");
else if (getStatus(Bluetooth)) strcat(statusOutput,"Bluetooth - Rumble is off");
else strcat(statusOutput,"Error");
if (getStatus(CableRumble)) strcat(statusOutput, "Cable - Rumble is on");
else if (getStatus(Cable)) strcat(statusOutput, "Cable - Rumble is off");
else if (getStatus(BluetoothRumble)) strcat(statusOutput, "Bluetooth - Rumble is on");
else if (getStatus(Bluetooth)) strcat(statusOutput, "Bluetooth - Rumble is off");
else strcat(statusOutput, "Error");
return statusOutput;
}
return statusOutput;
}
}
/* Playstation Sixaxis Dualshock and Navigation Controller commands */
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)
pUsb->ctrlReq(bAddress,epInfo[PS3_CONTROL_PIPE].epAddr, bmREQ_HID_OUT, HID_REQUEST_SET_REPORT, 0x01, 0x02, 0x00, nbytes, nbytes, data, NULL);
//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);
}
void PS3USB::setAllOff() {
for (uint8_t i = 0; i < PS3_REPORT_BUFFER_SIZE; i++)
writeBuf[i] = pgm_read_byte(&PS3_REPORT_BUFFER[i]); // Reset buffer
for (uint8_t i = 0; i < PS3_REPORT_BUFFER_SIZE; i++)
writeBuf[i] = pgm_read_byte(&PS3_REPORT_BUFFER[i]); // Reset buffer
PS3_Command(writeBuf, PS3_REPORT_BUFFER_SIZE);
}
void PS3USB::setRumbleOff() {
writeBuf[1] = 0x00;
writeBuf[2] = 0x00;//low mode off
writeBuf[3] = 0x00;
writeBuf[4] = 0x00;//high mode off
PS3_Command(writeBuf, PS3_REPORT_BUFFER_SIZE);
}
void PS3USB::setRumbleOn(Rumble mode) {
/* Still not totally sure how it works, maybe something like this instead?
* 3 - duration_right
* 4 - power_right
* 5 - duration_left
* 6 - power_left
*/
if ((mode & 0x30) > 0) {
writeBuf[1] = 0xfe;
writeBuf[3] = 0xfe;
if (mode == RumbleHigh) {
writeBuf[2] = 0;//low mode off
writeBuf[4] = 0xff;//high mode on
}
else {
writeBuf[2] = 0xff;//low mode on
writeBuf[4] = 0;//high mode off
}
PS3_Command(writeBuf, PS3_REPORT_BUFFER_SIZE);
}
}
void PS3USB::setRumbleOff() {
writeBuf[1] = 0x00;
writeBuf[2] = 0x00; //low mode off
writeBuf[3] = 0x00;
writeBuf[4] = 0x00; //high mode off
PS3_Command(writeBuf, PS3_REPORT_BUFFER_SIZE);
}
void PS3USB::setRumbleOn(Rumble mode) {
/* Still not totally sure how it works, maybe something like this instead?
* 3 - duration_right
* 4 - power_right
* 5 - duration_left
* 6 - power_left
*/
if ((mode & 0x30) > 0) {
writeBuf[1] = 0xfe;
writeBuf[3] = 0xfe;
if (mode == RumbleHigh) {
writeBuf[2] = 0; //low mode off
writeBuf[4] = 0xff; //high mode on
} else {
writeBuf[2] = 0xff; //low mode on
writeBuf[4] = 0; //high mode off
}
PS3_Command(writeBuf, PS3_REPORT_BUFFER_SIZE);
}
}
void PS3USB::setLedOff(LED a) {
writeBuf[9] &= ~((uint8_t)((pgm_read_byte(&LEDS[(uint8_t)a]) & 0x0f) << 1));
PS3_Command(writeBuf, PS3_REPORT_BUFFER_SIZE);
writeBuf[9] &= ~((uint8_t)((pgm_read_byte(&LEDS[(uint8_t)a]) & 0x0f) << 1));
PS3_Command(writeBuf, PS3_REPORT_BUFFER_SIZE);
}
void PS3USB::setLedOn(LED a) {
writeBuf[9] |= (uint8_t)((pgm_read_byte(&LEDS[(uint8_t)a]) & 0x0f) << 1);
PS3_Command(writeBuf, PS3_REPORT_BUFFER_SIZE);
writeBuf[9] |= (uint8_t)((pgm_read_byte(&LEDS[(uint8_t)a]) & 0x0f) << 1);
PS3_Command(writeBuf, PS3_REPORT_BUFFER_SIZE);
}
void PS3USB::setLedToggle(LED a) {
writeBuf[9] ^= (uint8_t)((pgm_read_byte(&LEDS[(uint8_t)a]) & 0x0f) << 1);
PS3_Command(writeBuf, PS3_REPORT_BUFFER_SIZE);
writeBuf[9] ^= (uint8_t)((pgm_read_byte(&LEDS[(uint8_t)a]) & 0x0f) << 1);
PS3_Command(writeBuf, PS3_REPORT_BUFFER_SIZE);
}
void PS3USB::setBdaddr(uint8_t* BDADDR) {
/* Set the internal bluetooth address */
uint8_t buf[8];
buf[0] = 0x01;
buf[1] = 0x00;
for (uint8_t i = 0; i < 6; i++)
buf[i+2] = BDADDR[5 - i];//Copy into buffer, has to be written reversed
/* Set the internal bluetooth address */
uint8_t buf[8];
buf[0] = 0x01;
buf[1] = 0x00;
for (uint8_t i = 0; i < 6; i++)
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)
pUsb->ctrlReq(bAddress,epInfo[PS3_CONTROL_PIPE].epAddr, bmREQ_HID_OUT, HID_REQUEST_SET_REPORT, 0xF5, 0x03, 0x00, 8, 8, buf, NULL);
//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);
#ifdef DEBUG
Notify(PSTR("\r\nBluetooth Address was set to: "), 0x80);
for(int8_t i = 5; i > 0; i--) {
PrintHex<uint8_t>(my_bdaddr[i], 0x80);
Serial.print(":");
}
PrintHex<uint8_t>(my_bdaddr[0], 0x80);
Notify(PSTR("\r\nBluetooth Address was set to: "), 0x80);
for (int8_t i = 5; i > 0; i--) {
PrintHex<uint8_t > (my_bdaddr[i], 0x80);
Serial.print(":");
}
PrintHex<uint8_t > (my_bdaddr[0], 0x80);
#endif
return;
return;
}
void PS3USB::enable_sixaxis() { //Command used to enable the Dualshock 3 and Navigation controller to send data via USB
uint8_t cmd_buf[4];
cmd_buf[0] = 0x42;// Special PS3 Controller enable commands
cmd_buf[1] = 0x0c;
cmd_buf[2] = 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)
pUsb->ctrlReq(bAddress,epInfo[PS3_CONTROL_PIPE].epAddr, bmREQ_HID_OUT, HID_REQUEST_SET_REPORT, 0xF4, 0x03, 0x00, 4, 4, cmd_buf, NULL);
void PS3USB::enable_sixaxis() { //Command used to enable the Dualshock 3 and Navigation controller to send data via USB
uint8_t cmd_buf[4];
cmd_buf[0] = 0x42; // Special PS3 Controller enable commands
cmd_buf[1] = 0x0c;
cmd_buf[2] = 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)
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 */
void PS3USB::Move_Command(uint8_t* data, uint16_t nbytes) {
pUsb->outTransfer(bAddress, epInfo[ PS3_OUTPUT_PIPE ].epAddr, nbytes, data);
pUsb->outTransfer(bAddress, epInfo[ PS3_OUTPUT_PIPE ].epAddr, nbytes, data);
}
void PS3USB::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
writeBuf[2] = r;
writeBuf[3] = g;
writeBuf[4] = b;
// set the Bulb's values into the write buffer
writeBuf[2] = r;
writeBuf[3] = g;
writeBuf[4] = b;
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"
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) {
#ifdef DEBUG
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);
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);
#endif
//set the rumble value into the write buffer
writeBuf[6] = rumble;
//set the rumble value into the write buffer
writeBuf[6] = rumble;
Move_Command(writeBuf, MOVE_REPORT_BUFFER_SIZE);
Move_Command(writeBuf, MOVE_REPORT_BUFFER_SIZE);
}
void PS3USB::setMoveBdaddr(uint8_t* BDADDR) {
/* Set the internal bluetooth address */
uint8_t buf[11];
buf[0] = 0x05;
buf[7] = 0x10;
buf[8] = 0x01;
buf[9] = 0x02;
buf[10] = 0x12;
/* Set the internal bluetooth address */
uint8_t buf[11];
buf[0] = 0x05;
buf[7] = 0x10;
buf[8] = 0x01;
buf[9] = 0x02;
buf[10] = 0x12;
for (uint8_t i = 0; i < 6; i++)
buf[i + 1] = BDADDR[i];
for (uint8_t i = 0; i < 6; 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)
pUsb->ctrlReq(bAddress,epInfo[PS3_CONTROL_PIPE].epAddr, bmREQ_HID_OUT, HID_REQUEST_SET_REPORT, 0x05, 0x03, 0x00,11,11, buf, NULL);
//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);
#ifdef DEBUG
Notify(PSTR("\r\nBluetooth Address was set to: "), 0x80);
for(int8_t i = 5; i > 0; i--) {
PrintHex<uint8_t>(my_bdaddr[i], 0x80);
Serial.print(":");
}
PrintHex<uint8_t>(my_bdaddr[0], 0x80);
Notify(PSTR("\r\nBluetooth Address was set to: "), 0x80);
for (int8_t i = 5; i > 0; i--) {
PrintHex<uint8_t > (my_bdaddr[i], 0x80);
Serial.print(":");
}
PrintHex<uint8_t > (my_bdaddr[0], 0x80);
#endif
return;
return;
}

338
PS3USB.h
View file

@ -63,186 +63,192 @@
*/
class PS3USB : public USBDeviceConfig {
public:
/**
* Constructor for the PS3USB class.
* @param pUsb Pointer to USB class instance.
* @param btadr5,btadr4,btadr3,btadr2,btadr1,btadr0
* Pass your dongles Bluetooth address into the constructor,
* 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);
/**
* Constructor for the PS3USB class.
* @param pUsb Pointer to USB class instance.
* @param btadr5,btadr4,btadr3,btadr2,btadr1,btadr0
* Pass your dongles Bluetooth address into the constructor,
* 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);
/** @name USBDeviceConfig implementation */
/**
* Initialize the PS3 Controller.
* @param parent Hub number.
* @param port Port number on the hub.
* @param lowspeed Speed of the device.
* @return 0 on success.
*/
virtual uint8_t Init(uint8_t parent, uint8_t port, bool lowspeed);
/**
* Release the USB device.
* @return 0 on success.
*/
virtual uint8_t Release();
/**
* Poll the USB Input endpoins and run the state machines.
* @return 0 on success.
*/
virtual uint8_t Poll();
/**
* Get the device address.
* @return The device address.
*/
virtual uint8_t GetAddress() { return bAddress; };
/**
* Used to check if the controller has been initialized.
* @return True if it's ready.
*/
virtual bool isReady() { return bPollEnable; };
/**@}*/
/** @name USBDeviceConfig implementation */
/**
* Initialize the PS3 Controller.
* @param parent Hub number.
* @param port Port number on the hub.
* @param lowspeed Speed of the device.
* @return 0 on success.
*/
virtual uint8_t Init(uint8_t parent, uint8_t port, bool lowspeed);
/**
* Release the USB device.
* @return 0 on success.
*/
virtual uint8_t Release();
/**
* Poll the USB Input endpoins and run the state machines.
* @return 0 on success.
*/
virtual uint8_t Poll();
/**
* Used to set the Bluetooth address inside the Dualshock 3 and Navigation controller.
* @param BDADDR Your dongles Bluetooth address.
*/
void setBdaddr(uint8_t* BDADDR);
/**
* Used to set the Bluetooth address inside the Move controller.
* @param BDADDR Your dongles Bluetooth address.
*/
void setMoveBdaddr(uint8_t* BDADDR);
/**
* Get the device address.
* @return The device address.
*/
virtual uint8_t GetAddress() {
return bAddress;
};
/** @name PS3 Controller functions */
/**
* getButtonPress(Button b) will return true as long as the button is held down.
*
* While getButtonClick(Button b) will only return it once.
*
* So you instance if you need to increase a variable once you would use getButtonClick(Button b),
* but if you need to drive a robot forward you would use getButtonPress(Button b).
*/
bool getButtonPress(Button b);
bool getButtonClick(Button b);
/**@}*/
/** @name PS3 Controller functions */
/**
* Used to get the analog value from button presses.
* @param a The ::Button to read.
* The supported buttons are:
* ::UP, ::RIGHT, ::DOWN, ::LEFT, ::L1, ::L2, ::R1, ::R2,
* ::TRIANGLE, ::CIRCLE, ::CROSS, ::SQUARE, and ::T.
* @return Analog value in the range of 0-255.
*/
uint8_t getAnalogButton(Button a);
/**
* Used to read the analog joystick.
* @param a ::LeftHatX, ::LeftHatY, ::RightHatX, and ::RightHatY.
* @return Return the analog value in the range of 0-255.
*/
uint8_t getAnalogHat(AnalogHat a);
/**
* Used to read the sensors inside the Dualshock 3 controller.
* @param a
* The Dualshock 3 has a 3-axis accelerometer and a 1-axis gyro inside.
* @return Return the raw sensor value.
*/
uint16_t getSensor(Sensor a);
/**
* Use this to get ::Pitch and ::Roll calculated using the accelerometer.
* @param a Either ::Pitch or ::Roll.
* @return Return the angle in the range of 0-360.
*/
double getAngle(Angle a);
/**
* Get the ::Status from the controller.
* @param c The ::Status you want to read.
* @return True if correct and false if not.
*/
bool getStatus(Status c);
/**
* Read all the available ::Status from the controller.
* @return One large string with all the information.
*/
String getStatusString();
/**
* Used to check if the controller has been initialized.
* @return True if it's ready.
*/
virtual bool isReady() {
return bPollEnable;
};
/**@}*/
/** Used to set all LEDs and ::Rumble off. */
void setAllOff();
/** Turn off ::Rumble. */
void setRumbleOff();
/**
* Turn on ::Rumble.
* @param mode Either ::RumbleHigh or ::RumbleLow.
*/
void setRumbleOn(Rumble mode);
/**
* Turn the specific ::LED off.
* @param a The ::LED to turn off.
*/
void setLedOff(LED a);
/**
* Turn the specific ::LED on.
* @param a The ::LED to turn on.
*/
void setLedOn(LED a);
/**
* Toggle the specific ::LED.
* @param a The ::LED to toggle.
*/
void setLedToggle(LED a);
/**
* Used to set the Bluetooth address inside the Dualshock 3 and Navigation controller.
* @param BDADDR Your dongles Bluetooth address.
*/
void setBdaddr(uint8_t* BDADDR);
/**
* Used to set the Bluetooth address inside the Move controller.
* @param BDADDR Your dongles Bluetooth address.
*/
void setMoveBdaddr(uint8_t* BDADDR);
/**
* Use this to set the Color using RGB values.
* @param r,g,b RGB value.
*/
void moveSetBulb(uint8_t r, uint8_t g, uint8_t b);
/**
* Use this to set the color using the predefined colors in ::Colors.
* @param color The desired color.
*/
void moveSetBulb(Colors color);
/**
* Set the rumble value inside the Move controller.
* @param rumble The desired value in the range from 64-255.
*/
void moveSetRumble(uint8_t rumble);
/**@}*/
/** @name PS3 Controller functions */
/**
* getButtonPress(Button b) will return true as long as the button is held down.
*
* While getButtonClick(Button b) will only return it once.
*
* So you instance if you need to increase a variable once you would use getButtonClick(Button b),
* but if you need to drive a robot forward you would use getButtonPress(Button b).
*/
bool getButtonPress(Button b);
bool getButtonClick(Button b);
/**@}*/
/** @name PS3 Controller functions */
/**
* Used to get the analog value from button presses.
* @param a The ::Button to read.
* The supported buttons are:
* ::UP, ::RIGHT, ::DOWN, ::LEFT, ::L1, ::L2, ::R1, ::R2,
* ::TRIANGLE, ::CIRCLE, ::CROSS, ::SQUARE, and ::T.
* @return Analog value in the range of 0-255.
*/
uint8_t getAnalogButton(Button a);
/**
* Used to read the analog joystick.
* @param a ::LeftHatX, ::LeftHatY, ::RightHatX, and ::RightHatY.
* @return Return the analog value in the range of 0-255.
*/
uint8_t getAnalogHat(AnalogHat a);
/**
* Used to read the sensors inside the Dualshock 3 controller.
* @param a
* The Dualshock 3 has a 3-axis accelerometer and a 1-axis gyro inside.
* @return Return the raw sensor value.
*/
uint16_t getSensor(Sensor a);
/**
* Use this to get ::Pitch and ::Roll calculated using the accelerometer.
* @param a Either ::Pitch or ::Roll.
* @return Return the angle in the range of 0-360.
*/
double getAngle(Angle a);
/**
* Get the ::Status from the controller.
* @param c The ::Status you want to read.
* @return True if correct and false if not.
*/
bool getStatus(Status c);
/**
* Read all the available ::Status from the controller.
* @return One large string with all the information.
*/
String getStatusString();
/** Variable used to indicate if the normal playstation controller is successfully connected. */
bool PS3Connected;
/** Variable used to indicate if the move controller is successfully connected. */
bool PS3MoveConnected;
/** Variable used to indicate if the navigation controller is successfully connected. */
bool PS3NavigationConnected;
/** Used to set all LEDs and ::Rumble off. */
void setAllOff();
/** Turn off ::Rumble. */
void setRumbleOff();
/**
* Turn on ::Rumble.
* @param mode Either ::RumbleHigh or ::RumbleLow.
*/
void setRumbleOn(Rumble mode);
/**
* Turn the specific ::LED off.
* @param a The ::LED to turn off.
*/
void setLedOff(LED a);
/**
* Turn the specific ::LED on.
* @param a The ::LED to turn on.
*/
void setLedOn(LED a);
/**
* Toggle the specific ::LED.
* @param a The ::LED to toggle.
*/
void setLedToggle(LED a);
/**
* Use this to set the Color using RGB values.
* @param r,g,b RGB value.
*/
void moveSetBulb(uint8_t r, uint8_t g, uint8_t b);
/**
* Use this to set the color using the predefined colors in ::Colors.
* @param color The desired color.
*/
void moveSetBulb(Colors color);
/**
* Set the rumble value inside the Move controller.
* @param rumble The desired value in the range from 64-255.
*/
void moveSetRumble(uint8_t rumble);
/**@}*/
/** Variable used to indicate if the normal playstation controller is successfully connected. */
bool PS3Connected;
/** Variable used to indicate if the move controller is successfully connected. */
bool PS3MoveConnected;
/** Variable used to indicate if the navigation controller is successfully connected. */
bool PS3NavigationConnected;
protected:
/** Pointer to USB class instance. */
USB *pUsb;
/** Device address. */
uint8_t bAddress;
/** Endpoint info structure. */
EpInfo epInfo[PS3_MAX_ENDPOINTS];
/** Pointer to USB class instance. */
USB *pUsb;
/** Device address. */
uint8_t bAddress;
/** Endpoint info structure. */
EpInfo epInfo[PS3_MAX_ENDPOINTS];
private:
bool bPollEnable;
bool bPollEnable;
uint32_t timer; // used to continuously set PS3 Move controller Bulb and rumble values
uint32_t timer; // used to continuously set PS3 Move controller Bulb and rumble values
uint32_t ButtonState;
uint32_t OldButtonState;
uint32_t ButtonClickState;
uint32_t ButtonState;
uint32_t OldButtonState;
uint32_t ButtonClickState;
uint8_t my_bdaddr[6]; // Change to your dongles Bluetooth address in the constructor
uint8_t readBuf[EP_MAXPKTSIZE]; // General purpose buffer for input data
uint8_t writeBuf[EP_MAXPKTSIZE]; // General purpose buffer for output data
uint8_t my_bdaddr[6]; // Change to your dongles Bluetooth address in the constructor
uint8_t readBuf[EP_MAXPKTSIZE]; // General purpose buffer for input data
uint8_t writeBuf[EP_MAXPKTSIZE]; // General purpose buffer for output data
void readReport(); // read incoming data
void printReport(); // print incoming date - Uncomment for debugging
void readReport(); // read incoming data
void printReport(); // print incoming date - Uncomment for debugging
/* Private commands */
void PS3_Command(uint8_t* data, uint16_t nbytes);
void enable_sixaxis(); // Command used to enable the Dualshock 3 and Navigation controller to send data via USB
void Move_Command(uint8_t* data, uint16_t nbytes);
/* Private commands */
void PS3_Command(uint8_t* data, uint16_t nbytes);
void enable_sixaxis(); // Command used to enable the Dualshock 3 and Navigation controller to send data via USB
void Move_Command(uint8_t* data, uint16_t nbytes);
};
#endif

1425
SPP.cpp

File diff suppressed because it is too large Load diff

508
SPP.h
View file

@ -87,276 +87,310 @@
#define BT_RFCOMM_RLS_CMD 0x53
#define BT_RFCOMM_RLS_RSP 0x51
#define BT_RFCOMM_NSC_RSP 0x11
*/
*/
/** This BluetoothService class implements the Serial Port Protocol (SPP). */
class SPP : public BluetoothService {
public:
/**
* Constructor for the SPP class.
* @param p Pointer to BTD class instance.
* @param name Set the name to BTD#btdName. If argument is omitted, then "Arduino" will be used.
* @param pin Write the pin to BTD#btdPin. If argument is omitted, then "1234" will be used.
*/
SPP(BTD *p, const char* name = "Arduino", const char* pin = "1234");
/**
* Constructor for the SPP class.
* @param p Pointer to BTD class instance.
* @param name Set the name to BTD#btdName. If argument is omitted, then "Arduino" will be used.
* @param pin Write the pin to BTD#btdPin. If argument is omitted, then "1234" will be used.
*/
SPP(BTD *p, const char* name = "Arduino", const char* pin = "1234");
/** @name BluetoothService implementation */
/**
* Used to pass acldata to the services.
* @param ACLData Incoming acldata.
*/
virtual void ACLData(uint8_t* ACLData);
/** Used to establish the connection automatically. */
virtual void Run();
/** Use this to reset the service. */
virtual void Reset();
/** Used this to disconnect the virtual serial port. */
virtual void disconnect();
/**@}*/
/** @name BluetoothService implementation */
/**
* Used to pass acldata to the services.
* @param ACLData Incoming acldata.
*/
virtual void ACLData(uint8_t* ACLData);
/** Used to establish the connection automatically. */
virtual void Run();
/** Use this to reset the service. */
virtual void Reset();
/** Used this to disconnect the virtual serial port. */
virtual void disconnect();
/**@}*/
/** Variable used to indicate if the connection is established. */
bool connected;
/** Variable used to indicate if the connection is established. */
bool connected;
/** @name Serial port profile (SPP) Print functions */
/**
* Used to send Arduino String data type.
* @param str String to send.
*/
void print(const String &str);
/**
* Same as print(const String &str), but will include newline and carriage return.
* @param str String to send.
*/
void println(const String &str);
/** @name Serial port profile (SPP) Print functions */
/**
* Used to send Arduino String data type.
* @param str String to send.
*/
void print(const String &str);
/**
* Same as print(const String &str), but will include newline and carriage return.
* @param str String to send.
*/
void println(const String &str);
/**
* Used to send standard strings.
* @param str String to send.
*/
void print(const char* str);
/**
* Same as print(const char* str), but will include newline and carriage return.
* @param str String to send.
*/
void println(const char* str);
/**
* Used to send standard strings.
* @param str String to send.
*/
void print(const char* str);
/**
* Same as print(const char* str), but will include newline and carriage return.
* @param str String to send.
*/
void println(const char* str);
/**
* Used to send single bytes.
* @param data Data to send.
*/
void print(uint8_t data) { print(&data,1); };
/**
* Same as print(uint8_t data), but will include newline and carriage return.
* @param data Data to send.
*/
void println(uint8_t data);
/**
* Used to send single bytes.
* @param data Data to send.
*/
void print(uint8_t data) {
print(&data, 1);
};
/**
* Same as print(uint8_t data), but will include newline and carriage return.
* @param data Data to send.
*/
void println(uint8_t data);
/**
* Used to send arrays.
* @param array Array to send.
* @param length Number of bytes to send.
*/
void print(uint8_t* array, uint8_t length);
/**
* Same as print(uint8_t* array, uint8_t length), but will include newline and carriage return.
* @param array Array to send.
* @param length Number of bytes to send.
*/
void println(uint8_t* array, uint8_t length);
/**
* Used to send arrays.
* @param array Array to send.
* @param length Number of bytes to send.
*/
void print(uint8_t* array, uint8_t length);
/**
* Same as print(uint8_t* array, uint8_t length), but will include newline and carriage return.
* @param array Array to send.
* @param length Number of bytes to send.
*/
void println(uint8_t* array, uint8_t length);
/**
* Used to print strings 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.
*/
void print(const __FlashStringHelper *ifsh) { printFlashString(ifsh,false); };
/**
* 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.
*/
void println(const __FlashStringHelper *ifsh) { printFlashString(ifsh,true); };
/**
* Helper function to print a string stored in flash.
* @param ifsh String stored in flash you want to print.
* @param newline Set this to true to include newline and carriage return.
*/
void printFlashString(const __FlashStringHelper *ifsh, bool newline);
/**
* Used to print strings 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.
*/
void print(const __FlashStringHelper *ifsh) {
printFlashString(ifsh, false);
};
/**
* 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.
*/
void println(const __FlashStringHelper *ifsh) {
printFlashString(ifsh, true);
};
/**
* Helper function to print a string stored in flash.
* @param ifsh String stored in flash you want to print.
* @param newline Set this to true to include newline and carriage return.
*/
void printFlashString(const __FlashStringHelper *ifsh, bool newline);
/** Use this to print newline and carriage return. */
void println(void);
/** Use this to print newline and carriage return. */
void println(void);
/**
* Used to print unsigned integers.
* @param n Unsigned integer to send.
*/
void printNumber(uint8_t n) { printNumber((uint32_t)n); };
/**
* Same as printNumber(uint8_t n), but will include newline and carriage return.
* @param n Unsigned integer to send.
*/
void printNumberln(uint8_t n) { printNumberln((uint32_t)n); };
/**
* Used to print signed integers.
* @param n Signed integer to send.
*/
void printNumber(int8_t n) { printNumber((int32_t)n); };
/**
* Same as printNumber(int8_t n), but will include newline and carriage return.
* @param n Signed integer to send.
*/
void printNumberln(int8_t n) { printNumberln((int32_t)n); };
/**
* Used to print unsigned integers.
* @param n Unsigned integer to send.
*/
void printNumber(uint8_t n) {
printNumber((uint32_t) n);
};
/**
* Used to print unsigned integers.
* @param n Unsigned integer to send.
*/
void printNumber(uint16_t n) { printNumber((uint32_t)n); };
/**
* Same as printNumber(uint16_t n), but will include newline and carriage return.
* @param n Unsigned integer to send.
*/
void printNumberln(uint16_t n) { printNumberln((uint32_t)n); };
/**
* Used to print signed integers.
* @param n Signed integer to send.
*/
void printNumber(int16_t n) { printNumber((int32_t)n); };
/**
* Same as printNumber(int16_t n), but will include newline and carriage return.
* @param n Signed integer to send.
*/
void printNumberln(int16_t n) { printNumberln((int32_t)n); };
/**
* Same as printNumber(uint8_t n), but will include newline and carriage return.
* @param n Unsigned integer to send.
*/
void printNumberln(uint8_t n) {
printNumberln((uint32_t) n);
};
/**
* Used to print unsigned integers.
* @param n Unsigned integer to send.
*/
void printNumber(uint32_t n);
/**
* Same as printNumber(uint32_t n), but will include newline and carriage return.
* @param n Unsigned integer to send.
*/
void printNumberln(uint32_t n);
/**
* Used to print signed integers.
* @param n Signed integer to send.
*/
void printNumber(int8_t n) {
printNumber((int32_t) n);
};
/**
* Used to print signed integers.
* @param n Signed integer to send.
*/
void printNumber(int32_t n);
/**
* Same as printNumber(int32_t n), but will include newline and carriage return.
* @param n Signed integer to send.
*/
void printNumberln(int32_t n);
/**
* Same as printNumber(int8_t n), but will include newline and carriage return.
* @param n Signed integer to send.
*/
void printNumberln(int8_t n) {
printNumberln((int32_t) n);
};
/**
* Helper function to convert from an unsigned integer to a string.
* @param input Unsigned integer to convert.
* @param output Output buffer.
*/
void intToString(int32_t input, char* output);
/**
* Helper function to convert from a signed integer to a string.
* @param input Signed integer to convert.
* @param output Output buffer.
*/
void intToString(uint32_t input, char* output);
/**
* Used to print unsigned integers.
* @param n Unsigned integer to send.
*/
void printNumber(uint16_t n) {
printNumber((uint32_t) n);
};
/**
* Used to print floating-point numbers.
* @param n Floating-point number to print.
* @param digits Number of digits to send. If argument is omitted, then 2 digits will be used.
*/
void printNumber(double n, uint8_t digits = 2);
/**
* Same as printNumber(double n, uint8_t digits), but will include newline and carriage return.
* @param n Floating-point number to print.
* @param digits Number of digits to send. If argument is omitted, then 2 digits will be used.
*/
void printNumberln(double n, uint8_t digits = 2);
/**
* Helper function to convert from a double to a string.
* @param input Floating-point number to convert.
* @param output Output buffer.
* @param digits Number of digits to convert. If argument is omitted, then 2 digits will be used.
*/
void doubleToString(double input, char* output, uint8_t digits = 2);
/**
* Same as printNumber(uint16_t n), but will include newline and carriage return.
* @param n Unsigned integer to send.
*/
void printNumberln(uint16_t n) {
printNumberln((uint32_t) n);
};
/**
* Get number of bytes waiting to be read.
* @return Return the number of bytes ready to be read.
*/
uint8_t available() { return rfcommAvailable; };
/**
* Used to read the buffer.
* @return Return the byte. Will return 0 if no byte is available.
*/
uint8_t read();
/** Discard all the bytes in the buffer. */
void flush() { rfcommAvailable = 0; };
/**@}*/
/**
* Used to print signed integers.
* @param n Signed integer to send.
*/
void printNumber(int16_t n) {
printNumber((int32_t) n);
};
/**
* Same as printNumber(int16_t n), but will include newline and carriage return.
* @param n Signed integer to send.
*/
void printNumberln(int16_t n) {
printNumberln((int32_t) n);
};
/**
* Used to print unsigned integers.
* @param n Unsigned integer to send.
*/
void printNumber(uint32_t n);
/**
* Same as printNumber(uint32_t n), but will include newline and carriage return.
* @param n Unsigned integer to send.
*/
void printNumberln(uint32_t n);
/**
* Used to print signed integers.
* @param n Signed integer to send.
*/
void printNumber(int32_t n);
/**
* Same as printNumber(int32_t n), but will include newline and carriage return.
* @param n Signed integer to send.
*/
void printNumberln(int32_t n);
/**
* Helper function to convert from an unsigned integer to a string.
* @param input Unsigned integer to convert.
* @param output Output buffer.
*/
void intToString(int32_t input, char* output);
/**
* Helper function to convert from a signed integer to a string.
* @param input Signed integer to convert.
* @param output Output buffer.
*/
void intToString(uint32_t input, char* output);
/**
* Used to print floating-point numbers.
* @param n Floating-point number to print.
* @param digits Number of digits to send. If argument is omitted, then 2 digits will be used.
*/
void printNumber(double n, uint8_t digits = 2);
/**
* Same as printNumber(double n, uint8_t digits), but will include newline and carriage return.
* @param n Floating-point number to print.
* @param digits Number of digits to send. If argument is omitted, then 2 digits will be used.
*/
void printNumberln(double n, uint8_t digits = 2);
/**
* Helper function to convert from a double to a string.
* @param input Floating-point number to convert.
* @param output Output buffer.
* @param digits Number of digits to convert. If argument is omitted, then 2 digits will be used.
*/
void doubleToString(double input, char* output, uint8_t digits = 2);
/**
* Get number of bytes waiting to be read.
* @return Return the number of bytes ready to be read.
*/
uint8_t available() {
return rfcommAvailable;
};
/**
* Used to read the buffer.
* @return Return the byte. Will return 0 if no byte is available.
*/
uint8_t read();
/** Discard all the bytes in the buffer. */
void flush() {
rfcommAvailable = 0;
};
/**@}*/
private:
/* Bluetooth dongle library pointer */
BTD *pBtd;
/* Bluetooth dongle library pointer */
BTD *pBtd;
/* Set true when a channel is created */
bool SDPConnected;
bool RFCOMMConnected;
/* Set true when a channel is created */
bool SDPConnected;
bool RFCOMMConnected;
uint16_t hci_handle; // The HCI Handle for the connection
uint16_t hci_handle; // The HCI Handle for the connection
/* Variables used by L2CAP state maschines */
uint8_t l2cap_sdp_state;
uint8_t l2cap_rfcomm_state;
uint16_t l2cap_event_flag; // l2cap flags of received bluetooth events
/* Variables used by L2CAP state maschines */
uint8_t l2cap_sdp_state;
uint8_t l2cap_rfcomm_state;
uint16_t l2cap_event_flag; // l2cap flags of received bluetooth events
uint8_t l2capoutbuf[BULK_MAXPKTSIZE]; // General purpose buffer for l2cap out data
uint8_t rfcommbuf[10]; // Buffer for RFCOMM Commands
uint8_t l2capoutbuf[BULK_MAXPKTSIZE]; // General purpose buffer for l2cap out data
uint8_t rfcommbuf[10]; // Buffer for RFCOMM Commands
/* L2CAP Channels */
uint8_t sdp_scid[2]; // L2CAP source CID for SDP
uint8_t sdp_dcid[2]; // 0x0050
uint8_t rfcomm_scid[2]; // L2CAP source CID for RFCOMM
uint8_t rfcomm_dcid[2]; // 0x0051
uint8_t identifier; // Identifier for command
/* L2CAP Channels */
uint8_t sdp_scid[2]; // L2CAP source CID for SDP
uint8_t sdp_dcid[2]; // 0x0050
uint8_t rfcomm_scid[2]; // L2CAP source CID for RFCOMM
uint8_t rfcomm_dcid[2]; // 0x0051
uint8_t identifier; // Identifier for command
/* RFCOMM Variables */
uint8_t rfcommChannel;
uint8_t rfcommChannelConnection; // This is the channel the SPP chanel will be running at
uint8_t rfcommDirection;
uint8_t rfcommCommandResponse;
uint8_t rfcommChannelType;
uint8_t rfcommPfBit;
/* RFCOMM Variables */
uint8_t rfcommChannel;
uint8_t rfcommChannelConnection; // This is the channel the SPP chanel will be running at
uint8_t rfcommDirection;
uint8_t rfcommCommandResponse;
uint8_t rfcommChannelType;
uint8_t rfcommPfBit;
unsigned long timer;
bool waitForLastCommand;
bool creditSent;
unsigned long timer;
bool waitForLastCommand;
bool creditSent;
uint8_t rfcommDataBuffer[100]; // Create a 100 sized buffer for incoming data
uint8_t rfcommAvailable;
uint8_t rfcommDataBuffer[100]; // Create a 100 sized buffer for incoming data
uint8_t rfcommAvailable;
bool firstMessage; // Used to see if it's the first SDP request received
uint8_t bytesRead; // Counter to see when it's time to send more credit
bool firstMessage; // Used to see if it's the first SDP request received
uint8_t bytesRead; // Counter to see when it's time to send more credit
/* State machines */
void SDP_task(); // SDP state machine
void RFCOMM_task(); // RFCOMM state machine
/* State machines */
void SDP_task(); // SDP state machine
void RFCOMM_task(); // RFCOMM state machine
/* SDP Commands */
void SDP_Command(uint8_t* data, uint8_t nbytes);
void serviceNotSupported(uint8_t transactionIDHigh, uint8_t transactionIDLow);
void serialPortResponse1(uint8_t transactionIDHigh, uint8_t transactionIDLow);
void serialPortResponse2(uint8_t transactionIDHigh, uint8_t transactionIDLow);
void l2capResponse1(uint8_t transactionIDHigh, uint8_t transactionIDLow);
void l2capResponse2(uint8_t transactionIDHigh, uint8_t transactionIDLow);
/* SDP Commands */
void SDP_Command(uint8_t* data, uint8_t nbytes);
void serviceNotSupported(uint8_t transactionIDHigh, uint8_t transactionIDLow);
void serialPortResponse1(uint8_t transactionIDHigh, uint8_t transactionIDLow);
void serialPortResponse2(uint8_t transactionIDHigh, uint8_t transactionIDLow);
void l2capResponse1(uint8_t transactionIDHigh, uint8_t transactionIDLow);
void l2capResponse2(uint8_t transactionIDHigh, uint8_t transactionIDLow);
/* RFCOMM Commands */
void RFCOMM_Command(uint8_t* data, uint8_t nbytes);
void sendRfcomm(uint8_t channel, uint8_t direction, uint8_t CR, uint8_t channelType, uint8_t pfBit, uint8_t* data, uint8_t length);
void sendRfcommCredit(uint8_t channel, uint8_t direction, uint8_t CR, uint8_t channelType, uint8_t pfBit, uint8_t credit);
uint8_t calcFcs(uint8_t *data);
uint8_t __crc(uint8_t* data);
/* RFCOMM Commands */
void RFCOMM_Command(uint8_t* data, uint8_t nbytes);
void sendRfcomm(uint8_t channel, uint8_t direction, uint8_t CR, uint8_t channelType, uint8_t pfBit, uint8_t* data, uint8_t length);
void sendRfcommCredit(uint8_t channel, uint8_t direction, uint8_t CR, uint8_t channelType, uint8_t pfBit, uint8_t credit);
uint8_t calcFcs(uint8_t *data);
uint8_t __crc(uint8_t* data);
};
#endif

View file

@ -176,7 +176,7 @@ uint8_t USB::ctrlReq(uint8_t addr, uint8_t ep, uint8_t bmReqType, uint8_t bReque
// Invoke callback function if inTransfer completed successfuly and callback function pointer is specified
if (!rcode && p)
((USBReadParser*) p)->Parse(read, dataptr, total - left);
((USBReadParser*)p)->Parse(read, dataptr, total - left);
left -= read;
@ -236,14 +236,14 @@ uint8_t USB::InTransfer(EpInfo *pep, uint16_t nak_limit, uint16_t *nbytesptr, ui
/* the only case when absense of RCVDAVIRQ makes sense is when toggle error occured. Need to add handling for that */
if ((regRd(rHIRQ) & bmRCVDAVIRQ) == 0) {
//printf("Problem! NO RCVDAVIRQ!\r\n");
rcode = 0xf0; //receive error
rcode = 0xf0; //receive error
break;
}
pktsize = regRd(rRCVBC); //number of received bytes
//printf("Got %i bytes ", pktsize);
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)
mem_left = 0;
@ -591,7 +591,7 @@ uint8_t USB::getConfDescr(uint8_t addr, uint8_t ep, uint8_t conf, USBReadParser
if (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);

20
Usb.h
View file

@ -147,7 +147,7 @@ typedef struct {
uint8_t recipient : 5; // Recipient of the request
uint8_t type : 2; // Type of request
uint8_t direction : 1; // Direction of data X-fer
}__attribute__((packed));
} __attribute__((packed));
} ReqType_u;
uint8_t bRequest; // 1 Request
@ -157,7 +157,7 @@ typedef struct {
struct {
uint8_t wValueLo;
uint8_t wValueHi;
}__attribute__((packed));
} __attribute__((packed));
} wVal_u;
uint16_t wIndex; // 4 Depends on bRequest
uint16_t wLength; // 6 Depends on bRequest
@ -190,12 +190,12 @@ public:
};
AddressPool& GetAddressPool() {
return (AddressPool&) addrPool;
return(AddressPool&) addrPool;
};
uint8_t RegisterDeviceClass(USBDeviceConfig *pdev) {
for (uint8_t i = 0; i < USB_NUMDEVICES; i++) {
if (!devConfig[i]) {
for(uint8_t i = 0; i < USB_NUMDEVICES; i++) {
if(!devConfig[i]) {
devConfig[i] = pdev;
return 0;
}
@ -250,27 +250,27 @@ private:
//get device descriptor
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
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
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
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
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)

1851
Wii.cpp

File diff suppressed because it is too large Load diff

651
Wii.h
View file

@ -82,10 +82,10 @@
/** Enum used to read the joystick on the Nunchuck. */
enum Hat {
/** Read the x-axis on the Nunchuck joystick. */
HatX = 0,
/** Read the y-axis on the Nunchuck joystick. */
HatY = 1,
/** Read the x-axis on the Nunchuck joystick. */
HatX = 0,
/** Read the y-axis on the Nunchuck joystick. */
HatY = 1,
};
/**
@ -95,347 +95,394 @@ enum Hat {
*/
class WII : public BluetoothService {
public:
/**
* Constructor for the WII class.
* @param p Pointer to BTD class instance.
* @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.
*/
WII(BTD *p, bool pair=false);
/**
* Constructor for the WII class.
* @param p Pointer to BTD class instance.
* @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.
*/
WII(BTD *p, bool pair = false);
/** @name BluetoothService implementation */
/**
* Used to pass acldata to the services.
* @param ACLData Incoming acldata.
*/
virtual void ACLData(uint8_t* ACLData);
/** Used to run part of the state maschine. */
virtual void Run();
/** Use this to reset the service. */
virtual void Reset();
/** Used this to disconnect any of the controllers. */
virtual void disconnect();
/**@}*/
/** @name BluetoothService implementation */
/**
* Used to pass acldata to the services.
* @param ACLData Incoming acldata.
*/
virtual void ACLData(uint8_t* ACLData);
/** Used to run part of the state maschine. */
virtual void Run();
/** Use this to reset the service. */
virtual void Reset();
/** Used this to disconnect any of the controllers. */
virtual void disconnect();
/**@}*/
/** @name Wii Controller functions */
/**
* getButtonPress(Button b) will return true as long as the button is held down.
*
* While getButtonClick(Button b) will only return it once.
*
* So you instance if you need to increase a variable once you would use getButtonClick(Button b),
* but if you need to drive a robot forward you would use getButtonPress(Button b).
*/
bool getButtonPress(Button b);
bool getButtonClick(Button b);
/**@}*/
/** @name Wii Controller functions */
/**
* getButtonPress(Button b) will return true as long as the button is held down.
*
* While getButtonClick(Button b) will only return it once.
*
* So you instance if you need to increase a variable once you would use getButtonClick(Button b),
* but if you need to drive a robot forward you would use getButtonPress(Button b).
*/
bool getButtonPress(Button b);
bool getButtonClick(Button b);
/**@}*/
/** @name Wii Controller functions */
/**
* Used to read the joystick of the Nunchuck.
* @param a Either ::HatX or ::HatY.
* @return Return the analog value in the range from approximately 25-230.
*/
uint8_t getAnalogHat(Hat a);
/**
* Used to read the joystick of the Wii U Pro Controller.
* @param a Either ::LeftHatX, ::LeftHatY, ::RightHatX or ::RightHatY.
* @return Return the analog value in the range from approximately 800-3200.
*/
uint16_t getAnalogHat(AnalogHat a);
/** @name Wii Controller functions */
/**
* Used to read the joystick of the Nunchuck.
* @param a Either ::HatX or ::HatY.
* @return Return the analog value in the range from approximately 25-230.
*/
uint8_t getAnalogHat(Hat a);
/**
* Used to read the joystick of the Wii U Pro Controller.
* @param a Either ::LeftHatX, ::LeftHatY, ::RightHatX or ::RightHatY.
* @return Return the analog value in the range from approximately 800-3200.
*/
uint16_t getAnalogHat(AnalogHat a);
/**
* Pitch calculated from the Wiimote. A complimentary filter is used if the Motion Plus is connected.
* @return Pitch in the range from 0-360.
*/
double getPitch() { return pitch; };
/**
* Roll calculated from the Wiimote. A complimentary filter is used if the Motion Plus is connected.
* @return Roll in the range from 0-360.
*/
double getRoll() { return roll; };
/**
* 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.
* @return The angle calculated using the gyro.
*/
double getYaw() { return gyroYaw; };
/**
* Pitch calculated from the Wiimote. A complimentary filter is used if the Motion Plus is connected.
* @return Pitch in the range from 0-360.
*/
double getPitch() {
return pitch;
};
/** Used to set all LEDs and rumble off. */
void setAllOff();
/** Turn off rumble. */
void setRumbleOff();
/** Turn on rumble. */
void setRumbleOn();
/** Toggle rumble. */
void setRumbleToggle();
/**
* Turn the specific ::LED off.
* @param a The ::LED to turn off.
*/
void setLedOff(LED a);
/**
* Turn the specific ::LED on.
* @param a The ::LED to turn on.
*/
void setLedOn(LED a);
/**
* Toggle the specific ::LED.
* @param a The ::LED to toggle.
*/
void setLedToggle(LED a);
/**
* This will set the LEDs, so the user can see which connections are active.
*
* The first ::LED indicate that the Wiimote is connected,
*
* the second ::LED indicate indicate that a Motion Plus is also connected
*
* the third ::LED will indicate that a Nunchuck controller is also connected.
*/
void setLedStatus();
/**
* Roll calculated from the Wiimote. A complimentary filter is used if the Motion Plus is connected.
* @return Roll in the range from 0-360.
*/
double getRoll() {
return roll;
};
/**
* Return the battery level of the Wiimote.
* @return The battery level in the range 0-255.
*/
uint8_t getBatteryLevel() { return batteryLevel; };
/**
* Return the Wiimote state.
* @return See: http://wiibrew.org/wiki/Wiimote#0x20:_Status.
*/
uint8_t getWiiState() { return wiiState; };
/**@}*/
/**
* 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.
* @return The angle calculated using the gyro.
*/
double getYaw() {
return gyroYaw;
};
/**@{*/
/** Variable used to indicate if a Wiimote is connected. */
bool wiimoteConnected;
/** Variable used to indicate if a Nunchuck controller is connected. */
bool nunchuckConnected;
/** Variable used to indicate if a Nunchuck controller is connected. */
bool motionPlusConnected;
/** Variable used to indicate if a Wii U Pro controller is connected. */
bool wiiUProControllerConnected;
/**@}*/
/** Used to set all LEDs and rumble off. */
void setAllOff();
/** Turn off rumble. */
void setRumbleOff();
/** Turn on rumble. */
void setRumbleOn();
/** Toggle rumble. */
void setRumbleToggle();
/**
* Turn the specific ::LED off.
* @param a The ::LED to turn off.
*/
void setLedOff(LED a);
/**
* Turn the specific ::LED on.
* @param a The ::LED to turn on.
*/
void setLedOn(LED a);
/**
* Toggle the specific ::LED.
* @param a The ::LED to toggle.
*/
void setLedToggle(LED a);
/**
* This will set the LEDs, so the user can see which connections are active.
*
* The first ::LED indicate that the Wiimote is connected,
*
* the second ::LED indicate indicate that a Motion Plus is also connected
*
* the third ::LED will indicate that a Nunchuck controller is also connected.
*/
void setLedStatus();
/* IMU Data, might be usefull if you need to do something more advanced than just calculating the angle */
/**
* Return the battery level of the Wiimote.
* @return The battery level in the range 0-255.
*/
uint8_t getBatteryLevel() {
return batteryLevel;
};
/**@{*/
/** Pitch and roll calculated from the accelerometer inside the Wiimote. */
double wiimotePitch;
double wiimoteRoll;
/**@}*/
/**
* Return the Wiimote state.
* @return See: http://wiibrew.org/wiki/Wiimote#0x20:_Status.
*/
uint8_t getWiiState() {
return wiiState;
};
/**@}*/
/**@{*/
/** Pitch and roll calculated from the accelerometer inside the Nunchuck. */
double nunchuckPitch;
double nunchuckRoll;
/**@}*/
/**@{*/
/** Variable used to indicate if a Wiimote is connected. */
bool wiimoteConnected;
/** Variable used to indicate if a Nunchuck controller is connected. */
bool nunchuckConnected;
/** Variable used to indicate if a Nunchuck controller is connected. */
bool motionPlusConnected;
/** Variable used to indicate if a Wii U Pro controller is connected. */
bool wiiUProControllerConnected;
/**@}*/
/**@{*/
/** Accelerometer values used to calculate pitch and roll. */
int16_t accX;
int16_t accY;
int16_t accZ;
/**@}*/
/* IMU Data, might be usefull if you need to do something more advanced than just calculating the angle */
/* Variables for the gyro inside the Motion Plus */
/** This is the pitch calculated by the gyro - use this to tune WII#pitchGyroScale. */
double gyroPitch;
/** This is the roll calculated by the gyro - use this to tune WII#rollGyroScale. */
double gyroRoll;
/** This is the yaw calculated by the gyro - use this to tune WII#yawGyroScale. */
double gyroYaw;
/**@{*/
/** Pitch and roll calculated from the accelerometer inside the Wiimote. */
double wiimotePitch;
double wiimoteRoll;
/**@}*/
/**@{*/
/** The speed in deg/s from the gyro. */
double pitchGyroSpeed;
double rollGyroSpeed;
double yawGyroSpeed;
/**@}*/
/**@{*/
/** Pitch and roll calculated from the accelerometer inside the Nunchuck. */
double nunchuckPitch;
double nunchuckRoll;
/**@}*/
/**@{*/
/** You might need to fine-tune these values. */
uint16_t pitchGyroScale;
uint16_t rollGyroScale;
uint16_t yawGyroScale;
/**@}*/
/**@{*/
/** Accelerometer values used to calculate pitch and roll. */
int16_t accX;
int16_t accY;
int16_t accZ;
/**@}*/
/**@{*/
/** Raw value read directly from the Motion Plus. */
int16_t gyroYawRaw;
int16_t gyroRollRaw;
int16_t gyroPitchRaw;
/**@}*/
/* Variables for the gyro inside the Motion Plus */
/** This is the pitch calculated by the gyro - use this to tune WII#pitchGyroScale. */
double gyroPitch;
/** This is the roll calculated by the gyro - use this to tune WII#rollGyroScale. */
double gyroRoll;
/** This is the yaw calculated by the gyro - use this to tune WII#yawGyroScale. */
double gyroYaw;
/**@{*/
/** These values are set when the controller is first initialized. */
int16_t gyroYawZero;
int16_t gyroRollZero;
int16_t gyroPitchZero;
/**@}*/
/**@{*/
/** The speed in deg/s from the gyro. */
double pitchGyroSpeed;
double rollGyroSpeed;
double yawGyroSpeed;
/**@}*/
/**@{*/
/** You might need to fine-tune these values. */
uint16_t pitchGyroScale;
uint16_t rollGyroScale;
uint16_t yawGyroScale;
/**@}*/
/**@{*/
/** Raw value read directly from the Motion Plus. */
int16_t gyroYawRaw;
int16_t gyroRollRaw;
int16_t gyroPitchRaw;
/**@}*/
/**@{*/
/** These values are set when the controller is first initialized. */
int16_t gyroYawZero;
int16_t gyroRollZero;
int16_t gyroPitchZero;
/**@}*/
#ifdef WIICAMERA
/** @name Wiimote IR camera functions
* You will have to uncomment #WIICAMERA in Wii.h to use the IR camera.
*/
/** Initialises the camera as per the steps from: http://wiibrew.org/wiki/Wiimote#IR_Camera */
void IRinitialize();
/** @name Wiimote IR camera functions
* You will have to uncomment #WIICAMERA in Wii.h to use the IR camera.
*/
/** Initialises the camera as per the steps from: http://wiibrew.org/wiki/Wiimote#IR_Camera */
void IRinitialize();
/**
* IR object 1 x-position read from the Wii IR camera.
* @return The x-position of the object in the range 0-1023.
*/
uint16_t getIRx1() { return IR_object_x1; };
/**
* IR object 1 y-position read from the Wii IR camera.
* @return The y-position of the object in the range 0-767.
*/
uint16_t getIRy1() { return IR_object_y1; };
/**
* IR object 1 size read from the Wii IR camera.
* @return The size of the object in the range 0-15.
*/
uint8_t getIRs1() { return IR_object_s1; };
/**
* IR object 1 x-position read from the Wii IR camera.
* @return The x-position of the object in the range 0-1023.
*/
uint16_t getIRx1() {
return IR_object_x1;
};
/**
* IR object 2 x-position read from the Wii IR camera.
* @return The x-position of the object in the range 0-1023.
*/
uint16_t getIRx2() { return IR_object_x2; };
/**
* IR object 2 y-position read from the Wii IR camera.
* @return The y-position of the object in the range 0-767.
*/
uint16_t getIRy2() { return IR_object_y2; };
/**
* IR object 2 size read from the Wii IR camera.
* @return The size of the object in the range 0-15.
*/
uint8_t getIRs2() { return IR_object_s2; };
/**
* IR object 1 y-position read from the Wii IR camera.
* @return The y-position of the object in the range 0-767.
*/
uint16_t getIRy1() {
return IR_object_y1;
};
/**
* IR object 3 x-position read from the Wii IR camera.
* @return The x-position of the object in the range 0-1023.
*/
uint16_t getIRx3() { return IR_object_x3; };
/**
* IR object 3 y-position read from the Wii IR camera.
* @return The y-position of the object in the range 0-767.
*/
uint16_t getIRy3() { return IR_object_y3; };
/**
* IR object 3 size read from the Wii IR camera.
* @return The size of the object in the range 0-15.
*/
uint8_t getIRs3() { return IR_object_s3; };
/**
* IR object 1 size read from the Wii IR camera.
* @return The size of the object in the range 0-15.
*/
uint8_t getIRs1() {
return IR_object_s1;
};
/**
* IR object 4 x-position read from the Wii IR camera.
* @return The x-position of the object in the range 0-1023.
*/
uint16_t getIRx4() { return IR_object_x4; };
/**
* IR object 4 y-position read from the Wii IR camera.
* @return The y-position of the object in the range 0-767.
*/
uint16_t getIRy4() { return IR_object_y4; };
/**
* IR object 4 size read from the Wii IR camera.
* @return The size of the object in the range 0-15.
*/
uint8_t getIRs4() { return IR_object_s4; };
/**
* IR object 2 x-position read from the Wii IR camera.
* @return The x-position of the object in the range 0-1023.
*/
uint16_t getIRx2() {
return IR_object_x2;
};
/**
* Use this to check if the camera is enabled or not.
* If not call WII#IRinitialize to initialize the IR camera.
* @return True if it's enabled, false if not.
*/
bool isIRCameraEnabled() { return (wiiState & 0x08); };
/**@}*/
/**
* IR object 2 y-position read from the Wii IR camera.
* @return The y-position of the object in the range 0-767.
*/
uint16_t getIRy2() {
return IR_object_y2;
};
/**
* IR object 2 size read from the Wii IR camera.
* @return The size of the object in the range 0-15.
*/
uint8_t getIRs2() {
return IR_object_s2;
};
/**
* IR object 3 x-position read from the Wii IR camera.
* @return The x-position of the object in the range 0-1023.
*/
uint16_t getIRx3() {
return IR_object_x3;
};
/**
* IR object 3 y-position read from the Wii IR camera.
* @return The y-position of the object in the range 0-767.
*/
uint16_t getIRy3() {
return IR_object_y3;
};
/**
* IR object 3 size read from the Wii IR camera.
* @return The size of the object in the range 0-15.
*/
uint8_t getIRs3() {
return IR_object_s3;
};
/**
* IR object 4 x-position read from the Wii IR camera.
* @return The x-position of the object in the range 0-1023.
*/
uint16_t getIRx4() {
return IR_object_x4;
};
/**
* IR object 4 y-position read from the Wii IR camera.
* @return The y-position of the object in the range 0-767.
*/
uint16_t getIRy4() {
return IR_object_y4;
};
/**
* IR object 4 size read from the Wii IR camera.
* @return The size of the object in the range 0-15.
*/
uint8_t getIRs4() {
return IR_object_s4;
};
/**
* Use this to check if the camera is enabled or not.
* If not call WII#IRinitialize to initialize the IR camera.
* @return True if it's enabled, false if not.
*/
bool isIRCameraEnabled() {
return(wiiState & 0x08);
};
/**@}*/
#endif
private:
/* Mandatory members */
BTD *pBtd;
/* Mandatory members */
BTD *pBtd;
void L2CAP_task(); // L2CAP state machine
void L2CAP_task(); // L2CAP state machine
/* Variables filled from HCI event management */
uint16_t hci_handle;
bool activeConnection; // Used to indicate if it's already has established a connection
/* Variables filled from HCI event management */
uint16_t hci_handle;
bool activeConnection; // Used to indicate if it's already has established a connection
/* variables used by high level L2CAP task */
uint8_t l2cap_state;
uint16_t l2cap_event_flag;// l2cap flags of received bluetooth events
/* variables used by high level L2CAP task */
uint8_t l2cap_state;
uint16_t l2cap_event_flag; // l2cap flags of received bluetooth events
uint32_t ButtonState;
uint32_t OldButtonState;
uint32_t ButtonClickState;
uint16_t hatValues[4];
uint32_t ButtonState;
uint32_t OldButtonState;
uint32_t ButtonClickState;
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;
bool unknownExtensionConnected;
bool extensionConnected;
uint16_t stateCounter;
bool unknownExtensionConnected;
bool extensionConnected;
/* L2CAP Channels */
uint8_t control_scid[2]; // L2CAP source CID for HID_Control
uint8_t control_dcid[2]; // 0x0060
uint8_t interrupt_scid[2]; // L2CAP source CID for HID_Interrupt
uint8_t interrupt_dcid[2]; // 0x0061
uint8_t identifier; // Identifier for connection
/* L2CAP Channels */
uint8_t control_scid[2]; // L2CAP source CID for HID_Control
uint8_t control_dcid[2]; // 0x0060
uint8_t interrupt_scid[2]; // L2CAP source CID for HID_Interrupt
uint8_t interrupt_dcid[2]; // 0x0061
uint8_t identifier; // Identifier for connection
/* HID Commands */
void HID_Command(uint8_t* data, uint8_t nbytes);
void setReportMode(bool continuous, uint8_t mode);
void statusRequest();
/* HID Commands */
void HID_Command(uint8_t* data, uint8_t nbytes);
void setReportMode(bool continuous, uint8_t mode);
void statusRequest();
void writeData(uint32_t offset, uint8_t size, uint8_t* data);
void initExtension1();
void initExtension2();
void writeData(uint32_t offset, uint8_t size, uint8_t* data);
void initExtension1();
void initExtension2();
void readData(uint32_t offset, uint16_t size, bool EEPROM);
void readExtensionType();
void readCalData();
void readData(uint32_t offset, uint16_t size, bool EEPROM);
void readExtensionType();
void readCalData();
void checkMotionPresent(); // Used to see if a Motion Plus is connected to the Wiimote
void initMotionPlus();
void activateMotionPlus();
void checkMotionPresent(); // Used to see if a Motion Plus is connected to the Wiimote
void initMotionPlus();
void activateMotionPlus();
double pitch; // Fusioned angle using a complimentary filter if the Motion Plus is connected
double roll; // Fusioned angle using a complimentary filter if the Motion Plus is connected
double pitch; // Fusioned angle using a complimentary filter if the Motion Plus is connected
double roll; // Fusioned angle using a complimentary filter if the Motion Plus is connected
bool activateNunchuck;
bool motionValuesReset; // This bool is true when the gyro values has been reset
unsigned long timer;
bool activateNunchuck;
bool motionValuesReset; // This bool is true when the gyro values has been reset
unsigned long timer;
uint8_t wiiState; // Stores the value in l2capinbuf[12] - (0x01: Battery is nearly empty), (0x02: An Extension Controller is connected), (0x04: Speaker enabled), (0x08: IR enabled), (0x10: LED1, 0x20: LED2, 0x40: LED3, 0x80: LED4)
uint8_t batteryLevel;
uint8_t wiiState; // Stores the value in l2capinbuf[12] - (0x01: Battery is nearly empty), (0x02: An Extension Controller is connected), (0x04: Speaker enabled), (0x08: IR enabled), (0x10: LED1, 0x20: LED2, 0x40: LED3, 0x80: LED4)
uint8_t batteryLevel;
#ifdef WIICAMERA
/* Private function and variables for the readings from teh IR Camera */
void enableIRCamera1(); // Sets bit 2 of output report 13
void enableIRCamera2(); // Sets bit 2 of output report 1A
void writeSensitivityBlock1();
void writeSensitivityBlock2();
void write0x08Value();
void setWiiModeNumber(uint8_t mode_number);
/* Private function and variables for the readings from teh IR Camera */
void enableIRCamera1(); // Sets bit 2 of output report 13
void enableIRCamera2(); // Sets bit 2 of output report 1A
void writeSensitivityBlock1();
void writeSensitivityBlock2();
void write0x08Value();
void setWiiModeNumber(uint8_t mode_number);
uint16_t IR_object_x1; // IR x position 10 bits
uint16_t IR_object_y1; // IR y position 10 bits
uint8_t IR_object_s1; // IR size value
uint16_t IR_object_x2;
uint16_t IR_object_y2;
uint8_t IR_object_s2;
uint16_t IR_object_x3; // IR x position 10 bits
uint16_t IR_object_y3; // IR y position 10 bits
uint8_t IR_object_s3; // IR size value
uint16_t IR_object_x4;
uint16_t IR_object_y4;
uint8_t IR_object_s4;
uint16_t IR_object_x1; // IR x position 10 bits
uint16_t IR_object_y1; // IR y position 10 bits
uint8_t IR_object_s1; // IR size value
uint16_t IR_object_x2;
uint16_t IR_object_y2;
uint8_t IR_object_s2;
uint16_t IR_object_x3; // IR x position 10 bits
uint16_t IR_object_y3; // IR y position 10 bits
uint8_t IR_object_s3; // IR size value
uint16_t IR_object_x4;
uint16_t IR_object_y4;
uint8_t IR_object_s4;
#endif
};
#endif

View file

@ -22,395 +22,411 @@
//#define EXTRADEBUG // Uncomment to get even more debugging data
//#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
bAddress(0), // device address - mandatory
bPollEnable(false) { // don't start polling before dongle is connected
for(uint8_t i=0; i<XBOX_MAX_ENDPOINTS; i++) {
epInfo[i].epAddr = 0;
epInfo[i].maxPktSize = (i) ? 0 : 8;
epInfo[i].epAttribs = 0;
epInfo[i].bmNakPower = (i) ? USB_NAK_NOWAIT : USB_NAK_MAX_POWER;
}
for (uint8_t i = 0; i < XBOX_MAX_ENDPOINTS; i++) {
epInfo[i].epAddr = 0;
epInfo[i].maxPktSize = (i) ? 0 : 8;
epInfo[i].epAttribs = 0;
epInfo[i].bmNakPower = (i) ? USB_NAK_NOWAIT : USB_NAK_MAX_POWER;
}
if (pUsb) // register in USB subsystem
pUsb->RegisterDeviceClass(this); //set devConfig[] entry
if (pUsb) // register in USB subsystem
pUsb->RegisterDeviceClass(this); //set devConfig[] entry
}
uint8_t XBOXRECV::Init(uint8_t parent, uint8_t port, bool lowspeed) {
uint8_t buf[sizeof(USB_DEVICE_DESCRIPTOR)];
uint8_t rcode;
UsbDevice *p = NULL;
EpInfo *oldep_ptr = NULL;
uint16_t PID;
uint16_t VID;
uint8_t buf[sizeof (USB_DEVICE_DESCRIPTOR)];
uint8_t rcode;
UsbDevice *p = NULL;
EpInfo *oldep_ptr = NULL;
uint16_t PID;
uint16_t VID;
// get memory address of USB device address pool
AddressPool &addrPool = pUsb->GetAddressPool();
// get memory address of USB device address pool
AddressPool &addrPool = pUsb->GetAddressPool();
#ifdef EXTRADEBUG
Notify(PSTR("\r\nXBOXRECV Init"), 0x80);
Notify(PSTR("\r\nXBOXRECV Init"), 0x80);
#endif
// check if address has already been assigned to an instance
if (bAddress) {
// check if address has already been assigned to an instance
if (bAddress) {
#ifdef DEBUG
Notify(PSTR("\r\nAddress in use"), 0x80);
Notify(PSTR("\r\nAddress in use"), 0x80);
#endif
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
p = addrPool.GetUsbDevicePtr(0);
// Get pointer to pseudo device with address 0 assigned
p = addrPool.GetUsbDevicePtr(0);
if (!p) {
if (!p) {
#ifdef DEBUG
Notify(PSTR("\r\nAddress not found"), 0x80);
Notify(PSTR("\r\nAddress not found"), 0x80);
#endif
return USB_ERROR_ADDRESS_NOT_FOUND_IN_POOL;
}
return USB_ERROR_ADDRESS_NOT_FOUND_IN_POOL;
}
if (!p->epinfo) {
if (!p->epinfo) {
#ifdef DEBUG
Notify(PSTR("\r\nepinfo is null"), 0x80);
Notify(PSTR("\r\nepinfo is null"), 0x80);
#endif
return USB_ERROR_EPINFO_IS_NULL;
}
return USB_ERROR_EPINFO_IS_NULL;
}
// Save old pointer to EP_RECORD of address 0
oldep_ptr = p->epinfo;
// Save old pointer to EP_RECORD of address 0
oldep_ptr = p->epinfo;
// Temporary assign new pointer to epInfo to p->epinfo in order to avoid toggle inconsistence
p->epinfo = epInfo;
// Temporary assign new pointer to epInfo to p->epinfo in order to avoid toggle inconsistence
p->epinfo = epInfo;
p->lowspeed = lowspeed;
p->lowspeed = lowspeed;
// Get device descriptor
rcode = pUsb->getDevDescr(0, 0, sizeof(USB_DEVICE_DESCRIPTOR), (uint8_t*)buf);// Get device descriptor - addr, ep, nbytes, data
// Restore p->epinfo
p->epinfo = oldep_ptr;
// Get device descriptor
rcode = pUsb->getDevDescr(0, 0, sizeof (USB_DEVICE_DESCRIPTOR), (uint8_t*)buf); // Get device descriptor - addr, ep, nbytes, data
// Restore p->epinfo
p->epinfo = oldep_ptr;
if(rcode)
goto FailGetDevDescr;
if (rcode)
goto FailGetDevDescr;
VID = ((USB_DEVICE_DESCRIPTOR*)buf)->idVendor;
PID = ((USB_DEVICE_DESCRIPTOR*)buf)->idProduct;
VID = ((USB_DEVICE_DESCRIPTOR*)buf)->idVendor;
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
goto FailUnknownDevice;
else if(PID != XBOX_WIRELESS_RECEIVER_PID && PID != XBOX_WIRELESS_RECEIVER_THIRD_PARTY_PID) {
if (VID != XBOX_VID && VID != MADCATZ_VID) // We just check if it's a xbox receiver using the Vendor ID
goto FailUnknownDevice;
else if (PID != XBOX_WIRELESS_RECEIVER_PID && PID != XBOX_WIRELESS_RECEIVER_THIRD_PARTY_PID) {
#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
goto FailUnknownDevice;
}
goto FailUnknownDevice;
}
// Allocate new address according to device class
bAddress = addrPool.AllocAddress(parent, false, port);
// Allocate new address according to device class
bAddress = addrPool.AllocAddress(parent, false, port);
if (!bAddress)
return USB_ERROR_OUT_OF_ADDRESS_SPACE_IN_POOL;
if (!bAddress)
return USB_ERROR_OUT_OF_ADDRESS_SPACE_IN_POOL;
// Extract Max Packet Size from device descriptor
epInfo[0].maxPktSize = (uint8_t)((USB_DEVICE_DESCRIPTOR*)buf)->bMaxPacketSize0;
// Extract Max Packet Size from device descriptor
epInfo[0].maxPktSize = (uint8_t)((USB_DEVICE_DESCRIPTOR*)buf)->bMaxPacketSize0;
// Assign new address to the device
rcode = pUsb->setAddr( 0, 0, bAddress );
if (rcode) {
// Assign new address to the device
rcode = pUsb->setAddr(0, 0, bAddress);
if (rcode) {
p->lowspeed = false;
addrPool.FreeAddress(bAddress);
bAddress = 0;
#ifdef DEBUG
Notify(PSTR("\r\nsetAddr: "), 0x80);
#endif
PrintHex<uint8_t > (rcode, 0x80);
return rcode;
}
#ifdef EXTRADEBUG
Notify(PSTR("\r\nAddr: "), 0x80);
PrintHex<uint8_t > (bAddress, 0x80);
#endif
p->lowspeed = false;
addrPool.FreeAddress(bAddress);
bAddress = 0;
#ifdef DEBUG
Notify(PSTR("\r\nsetAddr: "), 0x80);
#endif
PrintHex<uint8_t>(rcode, 0x80);
return rcode;
}
#ifdef EXTRADEBUG
Notify(PSTR("\r\nAddr: "), 0x80);
PrintHex<uint8_t>(bAddress, 0x80);
#endif
p->lowspeed = false;
//get pointer to assigned address record
p = addrPool.GetUsbDevicePtr(bAddress);
if (!p)
return USB_ERROR_ADDRESS_NOT_FOUND_IN_POOL;
//get pointer to assigned address record
p = addrPool.GetUsbDevicePtr(bAddress);
if (!p)
return USB_ERROR_ADDRESS_NOT_FOUND_IN_POOL;
p->lowspeed = lowspeed;
p->lowspeed = lowspeed;
// Assign epInfo to epinfo pointer - only EP0 is known
rcode = pUsb->setEpInfoEntry(bAddress, 1, epInfo);
if (rcode)
goto FailSetDevTblEntry;
// Assign epInfo to epinfo pointer - only EP0 is known
rcode = pUsb->setEpInfoEntry(bAddress, 1, epInfo);
if (rcode)
goto FailSetDevTblEntry;
/* The application will work in reduced host mode, so we can save program and data
memory space. After verifying the VID we will use known values for the
configuration values for device, interface, endpoints and HID for the XBOX360 Wireless receiver */
/* The application will work in reduced host mode, so we can save program and data
memory space. After verifying the VID we will use known values for the
configuration values for device, interface, endpoints and HID for the XBOX360 Wireless receiver */
/* Initialize data structures for endpoints of device */
epInfo[ XBOX_INPUT_PIPE_1 ].epAddr = 0x01; // XBOX 360 report endpoint - poll interval 1ms
epInfo[ XBOX_INPUT_PIPE_1 ].epAttribs = EP_INTERRUPT;
epInfo[ XBOX_INPUT_PIPE_1 ].bmNakPower = USB_NAK_NOWAIT; // Only poll once for interrupt endpoints
epInfo[ XBOX_INPUT_PIPE_1 ].maxPktSize = EP_MAXPKTSIZE;
epInfo[ XBOX_INPUT_PIPE_1 ].bmSndToggle = bmSNDTOG0;
epInfo[ XBOX_INPUT_PIPE_1 ].bmRcvToggle = bmRCVTOG0;
epInfo[ XBOX_OUTPUT_PIPE_1 ].epAddr = 0x01; // XBOX 360 output endpoint - poll interval 8ms
epInfo[ XBOX_OUTPUT_PIPE_1 ].epAttribs = EP_INTERRUPT;
epInfo[ XBOX_OUTPUT_PIPE_1 ].bmNakPower = USB_NAK_NOWAIT; // Only poll once for interrupt endpoints
epInfo[ XBOX_OUTPUT_PIPE_1 ].maxPktSize = EP_MAXPKTSIZE;
epInfo[ XBOX_OUTPUT_PIPE_1 ].bmSndToggle = bmSNDTOG0;
epInfo[ XBOX_OUTPUT_PIPE_1 ].bmRcvToggle = bmRCVTOG0;
/* Initialize data structures for endpoints of device */
epInfo[ XBOX_INPUT_PIPE_1 ].epAddr = 0x01; // XBOX 360 report endpoint - poll interval 1ms
epInfo[ XBOX_INPUT_PIPE_1 ].epAttribs = EP_INTERRUPT;
epInfo[ XBOX_INPUT_PIPE_1 ].bmNakPower = USB_NAK_NOWAIT; // Only poll once for interrupt endpoints
epInfo[ XBOX_INPUT_PIPE_1 ].maxPktSize = EP_MAXPKTSIZE;
epInfo[ XBOX_INPUT_PIPE_1 ].bmSndToggle = bmSNDTOG0;
epInfo[ XBOX_INPUT_PIPE_1 ].bmRcvToggle = bmRCVTOG0;
epInfo[ XBOX_OUTPUT_PIPE_1 ].epAddr = 0x01; // XBOX 360 output endpoint - poll interval 8ms
epInfo[ XBOX_OUTPUT_PIPE_1 ].epAttribs = EP_INTERRUPT;
epInfo[ XBOX_OUTPUT_PIPE_1 ].bmNakPower = USB_NAK_NOWAIT; // Only poll once for interrupt endpoints
epInfo[ XBOX_OUTPUT_PIPE_1 ].maxPktSize = EP_MAXPKTSIZE;
epInfo[ XBOX_OUTPUT_PIPE_1 ].bmSndToggle = bmSNDTOG0;
epInfo[ XBOX_OUTPUT_PIPE_1 ].bmRcvToggle = bmRCVTOG0;
epInfo[ XBOX_INPUT_PIPE_2 ].epAddr = 0x03; // XBOX 360 report endpoint - poll interval 1ms
epInfo[ XBOX_INPUT_PIPE_2 ].epAttribs = EP_INTERRUPT;
epInfo[ XBOX_INPUT_PIPE_2 ].bmNakPower = USB_NAK_NOWAIT; // Only poll once for interrupt endpoints
epInfo[ XBOX_INPUT_PIPE_2 ].maxPktSize = EP_MAXPKTSIZE;
epInfo[ XBOX_INPUT_PIPE_2 ].bmSndToggle = bmSNDTOG0;
epInfo[ XBOX_INPUT_PIPE_2 ].bmRcvToggle = bmRCVTOG0;
epInfo[ XBOX_OUTPUT_PIPE_2 ].epAddr = 0x03; // XBOX 360 output endpoint - poll interval 8ms
epInfo[ XBOX_OUTPUT_PIPE_2 ].epAttribs = EP_INTERRUPT;
epInfo[ XBOX_OUTPUT_PIPE_2 ].bmNakPower = USB_NAK_NOWAIT; // Only poll once for interrupt endpoints
epInfo[ XBOX_OUTPUT_PIPE_2 ].maxPktSize = EP_MAXPKTSIZE;
epInfo[ XBOX_OUTPUT_PIPE_2 ].bmSndToggle = bmSNDTOG0;
epInfo[ XBOX_OUTPUT_PIPE_2 ].bmRcvToggle = bmRCVTOG0;
epInfo[ XBOX_INPUT_PIPE_2 ].epAddr = 0x03; // XBOX 360 report endpoint - poll interval 1ms
epInfo[ XBOX_INPUT_PIPE_2 ].epAttribs = EP_INTERRUPT;
epInfo[ XBOX_INPUT_PIPE_2 ].bmNakPower = USB_NAK_NOWAIT; // Only poll once for interrupt endpoints
epInfo[ XBOX_INPUT_PIPE_2 ].maxPktSize = EP_MAXPKTSIZE;
epInfo[ XBOX_INPUT_PIPE_2 ].bmSndToggle = bmSNDTOG0;
epInfo[ XBOX_INPUT_PIPE_2 ].bmRcvToggle = bmRCVTOG0;
epInfo[ XBOX_OUTPUT_PIPE_2 ].epAddr = 0x03; // XBOX 360 output endpoint - poll interval 8ms
epInfo[ XBOX_OUTPUT_PIPE_2 ].epAttribs = EP_INTERRUPT;
epInfo[ XBOX_OUTPUT_PIPE_2 ].bmNakPower = USB_NAK_NOWAIT; // Only poll once for interrupt endpoints
epInfo[ XBOX_OUTPUT_PIPE_2 ].maxPktSize = EP_MAXPKTSIZE;
epInfo[ XBOX_OUTPUT_PIPE_2 ].bmSndToggle = bmSNDTOG0;
epInfo[ XBOX_OUTPUT_PIPE_2 ].bmRcvToggle = bmRCVTOG0;
epInfo[ XBOX_INPUT_PIPE_3 ].epAddr = 0x05; // XBOX 360 report endpoint - poll interval 1ms
epInfo[ XBOX_INPUT_PIPE_3 ].epAttribs = EP_INTERRUPT;
epInfo[ XBOX_INPUT_PIPE_3 ].bmNakPower = USB_NAK_NOWAIT; // Only poll once for interrupt endpoints
epInfo[ XBOX_INPUT_PIPE_3 ].maxPktSize = EP_MAXPKTSIZE;
epInfo[ XBOX_INPUT_PIPE_3 ].bmSndToggle = bmSNDTOG0;
epInfo[ XBOX_INPUT_PIPE_3 ].bmRcvToggle = bmRCVTOG0;
epInfo[ XBOX_OUTPUT_PIPE_3 ].epAddr = 0x05; // XBOX 360 output endpoint - poll interval 8ms
epInfo[ XBOX_OUTPUT_PIPE_3 ].epAttribs = EP_INTERRUPT;
epInfo[ XBOX_OUTPUT_PIPE_3 ].bmNakPower = USB_NAK_NOWAIT; // Only poll once for interrupt endpoints
epInfo[ XBOX_OUTPUT_PIPE_3 ].maxPktSize = EP_MAXPKTSIZE;
epInfo[ XBOX_OUTPUT_PIPE_3 ].bmSndToggle = bmSNDTOG0;
epInfo[ XBOX_OUTPUT_PIPE_3 ].bmRcvToggle = bmRCVTOG0;
epInfo[ XBOX_INPUT_PIPE_3 ].epAddr = 0x05; // XBOX 360 report endpoint - poll interval 1ms
epInfo[ XBOX_INPUT_PIPE_3 ].epAttribs = EP_INTERRUPT;
epInfo[ XBOX_INPUT_PIPE_3 ].bmNakPower = USB_NAK_NOWAIT; // Only poll once for interrupt endpoints
epInfo[ XBOX_INPUT_PIPE_3 ].maxPktSize = EP_MAXPKTSIZE;
epInfo[ XBOX_INPUT_PIPE_3 ].bmSndToggle = bmSNDTOG0;
epInfo[ XBOX_INPUT_PIPE_3 ].bmRcvToggle = bmRCVTOG0;
epInfo[ XBOX_OUTPUT_PIPE_3 ].epAddr = 0x05; // XBOX 360 output endpoint - poll interval 8ms
epInfo[ XBOX_OUTPUT_PIPE_3 ].epAttribs = EP_INTERRUPT;
epInfo[ XBOX_OUTPUT_PIPE_3 ].bmNakPower = USB_NAK_NOWAIT; // Only poll once for interrupt endpoints
epInfo[ XBOX_OUTPUT_PIPE_3 ].maxPktSize = EP_MAXPKTSIZE;
epInfo[ XBOX_OUTPUT_PIPE_3 ].bmSndToggle = bmSNDTOG0;
epInfo[ XBOX_OUTPUT_PIPE_3 ].bmRcvToggle = bmRCVTOG0;
epInfo[ XBOX_INPUT_PIPE_4 ].epAddr = 0x07; // XBOX 360 report endpoint - poll interval 1ms
epInfo[ XBOX_INPUT_PIPE_4 ].epAttribs = EP_INTERRUPT;
epInfo[ XBOX_INPUT_PIPE_4 ].bmNakPower = USB_NAK_NOWAIT; // Only poll once for interrupt endpoints
epInfo[ XBOX_INPUT_PIPE_4 ].maxPktSize = EP_MAXPKTSIZE;
epInfo[ XBOX_INPUT_PIPE_4 ].bmSndToggle = bmSNDTOG0;
epInfo[ XBOX_INPUT_PIPE_4 ].bmRcvToggle = bmRCVTOG0;
epInfo[ XBOX_OUTPUT_PIPE_4 ].epAddr = 0x07; // XBOX 360 output endpoint - poll interval 8ms
epInfo[ XBOX_OUTPUT_PIPE_4 ].epAttribs = EP_INTERRUPT;
epInfo[ XBOX_OUTPUT_PIPE_4 ].bmNakPower = USB_NAK_NOWAIT; // Only poll once for interrupt endpoints
epInfo[ XBOX_OUTPUT_PIPE_4 ].maxPktSize = EP_MAXPKTSIZE;
epInfo[ XBOX_OUTPUT_PIPE_4 ].bmSndToggle = bmSNDTOG0;
epInfo[ XBOX_OUTPUT_PIPE_4 ].bmRcvToggle = bmRCVTOG0;
epInfo[ XBOX_INPUT_PIPE_4 ].epAddr = 0x07; // XBOX 360 report endpoint - poll interval 1ms
epInfo[ XBOX_INPUT_PIPE_4 ].epAttribs = EP_INTERRUPT;
epInfo[ XBOX_INPUT_PIPE_4 ].bmNakPower = USB_NAK_NOWAIT; // Only poll once for interrupt endpoints
epInfo[ XBOX_INPUT_PIPE_4 ].maxPktSize = EP_MAXPKTSIZE;
epInfo[ XBOX_INPUT_PIPE_4 ].bmSndToggle = bmSNDTOG0;
epInfo[ XBOX_INPUT_PIPE_4 ].bmRcvToggle = bmRCVTOG0;
epInfo[ XBOX_OUTPUT_PIPE_4 ].epAddr = 0x07; // XBOX 360 output endpoint - poll interval 8ms
epInfo[ XBOX_OUTPUT_PIPE_4 ].epAttribs = EP_INTERRUPT;
epInfo[ XBOX_OUTPUT_PIPE_4 ].bmNakPower = USB_NAK_NOWAIT; // Only poll once for interrupt endpoints
epInfo[ XBOX_OUTPUT_PIPE_4 ].maxPktSize = EP_MAXPKTSIZE;
epInfo[ XBOX_OUTPUT_PIPE_4 ].bmSndToggle = bmSNDTOG0;
epInfo[ XBOX_OUTPUT_PIPE_4 ].bmRcvToggle = bmRCVTOG0;
rcode = pUsb->setEpInfoEntry(bAddress, 9, epInfo);
if( rcode )
goto FailSetDevTblEntry;
rcode = pUsb->setEpInfoEntry(bAddress, 9, epInfo);
if (rcode)
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);
if( rcode )
goto FailSetConf;
rcode = pUsb->setConf(bAddress, epInfo[ XBOX_CONTROL_PIPE ].epAddr, 1);
if (rcode)
goto FailSetConf;
#ifdef DEBUG
Notify(PSTR("\r\nXbox Wireless Receiver Connected\r\n"), 0x80);
Notify(PSTR("\r\nXbox Wireless Receiver Connected\r\n"), 0x80);
#endif
XboxReceiverConnected = true;
bPollEnable = true;
return 0; // successful configuration
XboxReceiverConnected = true;
bPollEnable = true;
return 0; // successful configuration
/* diagnostic messages */
/* diagnostic messages */
FailGetDevDescr:
#ifdef DEBUG
Notify(PSTR("\r\ngetDevDescr:"), 0x80);
Notify(PSTR("\r\ngetDevDescr:"), 0x80);
#endif
goto Fail;
goto Fail;
FailSetDevTblEntry:
#ifdef DEBUG
Notify(PSTR("\r\nsetDevTblEn:"), 0x80);
Notify(PSTR("\r\nsetDevTblEn:"), 0x80);
#endif
goto Fail;
goto Fail;
FailSetConf:
#ifdef DEBUG
Notify(PSTR("\r\nsetConf:"), 0x80);
Notify(PSTR("\r\nsetConf:"), 0x80);
#endif
goto Fail;
goto Fail;
FailUnknownDevice:
#ifdef DEBUG
Notify(PSTR("\r\nUnknown Device Connected - VID: "), 0x80);
PrintHex<uint16_t>(VID, 0x80);
Notify(PSTR(" PID: "), 0x80);
PrintHex<uint16_t>(PID, 0x80);
Notify(PSTR("\r\nUnknown Device Connected - VID: "), 0x80);
PrintHex<uint16_t > (VID, 0x80);
Notify(PSTR(" PID: "), 0x80);
PrintHex<uint16_t > (PID, 0x80);
#endif
rcode = USB_DEV_CONFIG_ERROR_DEVICE_NOT_SUPPORTED;
goto Fail;
rcode = USB_DEV_CONFIG_ERROR_DEVICE_NOT_SUPPORTED;
goto Fail;
Fail:
#ifdef DEBUG
Notify(PSTR("\r\nXbox 360 Init Failed, error code: "), 0x80);
Serial.print(rcode,HEX);
Notify(PSTR("\r\nXbox 360 Init Failed, error code: "), 0x80);
Serial.print(rcode, HEX);
#endif
Release();
return rcode;
Release();
return rcode;
}
/* Performs a cleanup after failed Init() attempt */
uint8_t XBOXRECV::Release() {
XboxReceiverConnected = false;
for(uint8_t i=0;i<4;i++)
Xbox360Connected[i] = 0x00;
pUsb->GetAddressPool().FreeAddress(bAddress);
bAddress = 0;
bPollEnable = false;
return 0;
XboxReceiverConnected = false;
for (uint8_t i = 0; i < 4; i++)
Xbox360Connected[i] = 0x00;
pUsb->GetAddressPool().FreeAddress(bAddress);
bAddress = 0;
bPollEnable = false;
return 0;
}
uint8_t XBOXRECV::Poll() {
if (!bPollEnable)
return 0;
if(!timer || ((millis() - timer) > 3000)) { // Run checkStatus every 3 seconds
timer = millis();
checkStatus();
}
uint8_t inputPipe;
uint16_t bufferSize;
for(uint8_t i=0;i<4;i++) {
switch (i) {
case 0: inputPipe = XBOX_INPUT_PIPE_1; break;
case 1: inputPipe = XBOX_INPUT_PIPE_2; break;
case 2: inputPipe = XBOX_INPUT_PIPE_3; break;
case 3: inputPipe = XBOX_INPUT_PIPE_4; break;
if (!bPollEnable)
return 0;
if (!timer || ((millis() - timer) > 3000)) { // Run checkStatus every 3 seconds
timer = millis();
checkStatus();
}
bufferSize = EP_MAXPKTSIZE; // This is the maximum number of bytes we want to receive
pUsb->inTransfer(bAddress, epInfo[ inputPipe ].epAddr, &bufferSize, readBuf);
if(bufferSize > 0) { // The number of received bytes
uint8_t inputPipe;
uint16_t bufferSize;
for (uint8_t i = 0; i < 4; i++) {
switch (i) {
case 0: inputPipe = XBOX_INPUT_PIPE_1;
break;
case 1: inputPipe = XBOX_INPUT_PIPE_2;
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
pUsb->inTransfer(bAddress, epInfo[ inputPipe ].epAddr, &bufferSize, readBuf);
if (bufferSize > 0) { // The number of received bytes
#ifdef EXTRADEBUG
Notify(PSTR("Bytes Received: "), 0x80);
Serial.print(bufferSize);
Notify(PSTR("\r\n"), 0x80);
Notify(PSTR("Bytes Received: "), 0x80);
Serial.print(bufferSize);
Notify(PSTR("\r\n"), 0x80);
#endif
readReport(i);
readReport(i);
#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
}
}
}
return 0;
return 0;
}
void XBOXRECV::readReport(uint8_t controller) {
if (readBuf == NULL)
return;
// This report is send when a controller is connected and disconnected
if(readBuf[0] == 0x08 && readBuf[1] != Xbox360Connected[controller]) {
Xbox360Connected[controller] = readBuf[1];
if (readBuf == NULL)
return;
// This report is send when a controller is connected and disconnected
if (readBuf[0] == 0x08 && readBuf[1] != Xbox360Connected[controller]) {
Xbox360Connected[controller] = readBuf[1];
#ifdef DEBUG
Notify(PSTR("Controller "), 0x80);
Serial.print(controller);
Notify(PSTR("Controller "), 0x80);
Serial.print(controller);
#endif
if(Xbox360Connected[controller]) {
if (Xbox360Connected[controller]) {
#ifdef DEBUG
char* str = 0;
switch(readBuf[1]) {
case 0x80: str = PSTR(" as controller\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(str, 0x80);
char* str = 0;
switch (readBuf[1]) {
case 0x80: str = PSTR(" as controller\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(str, 0x80);
#endif
LED led;
switch (controller) {
case 0: led = LED1; break;
case 1: led = LED2; break;
case 2: led = LED3; break;
case 3: led = LED4; break;
}
setLedOn(controller,led);
LED led;
switch (controller) {
case 0: led = LED1;
break;
case 1: led = LED2;
break;
case 2: led = LED3;
break;
case 3: led = LED4;
break;
}
setLedOn(controller, led);
}
#ifdef DEBUG
else
Notify(PSTR(": disconnected\r\n"), 0x80);
#endif
return;
}
#ifdef DEBUG
else
Notify(PSTR(": disconnected\r\n"), 0x80);
#endif
return;
}
// Controller status report
if(readBuf[1] == 0x00 && readBuf[3] & 0x13 && readBuf[4] >= 0x22) {
controllerStatus[controller] = ((uint16_t)readBuf[3] << 8) | readBuf[4];
return;
}
if(readBuf[1] != 0x01) // Check if it's the correct report - the receiver also sends different status reports
return;
// Controller status report
if (readBuf[1] == 0x00 && readBuf[3] & 0x13 && readBuf[4] >= 0x22) {
controllerStatus[controller] = ((uint16_t)readBuf[3] << 8) | readBuf[4];
return;
}
if (readBuf[1] != 0x01) // Check if it's the correct report - the receiver also sends different status reports
return;
// A controller must be connected if it's sending data
if(!Xbox360Connected[controller])
Xbox360Connected[controller] |= 0x80;
// A controller must be connected if it's sending data
if (!Xbox360Connected[controller])
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));
hatValue[controller][LeftHatX] = (int16_t)(((uint16_t)readBuf[11] << 8) | readBuf[10]);
hatValue[controller][LeftHatY] = (int16_t)(((uint16_t)readBuf[13] << 8) | readBuf[12]);
hatValue[controller][RightHatX] = (int16_t)(((uint16_t)readBuf[15] << 8) | readBuf[14]);
hatValue[controller][RightHatY] = (int16_t)(((uint16_t)readBuf[17] << 8) | readBuf[16]);
hatValue[controller][LeftHatX] = (int16_t)(((uint16_t)readBuf[11] << 8) | readBuf[10]);
hatValue[controller][LeftHatY] = (int16_t)(((uint16_t)readBuf[13] << 8) | readBuf[12]);
hatValue[controller][RightHatX] = (int16_t)(((uint16_t)readBuf[15] << 8) | readBuf[14]);
hatValue[controller][RightHatY] = (int16_t)(((uint16_t)readBuf[17] << 8) | readBuf[16]);
//Notify(PSTR("\r\nButtonState: "), 0x80);
//PrintHex<uint32_t>(ButtonState[controller], 0x80);
//Notify(PSTR("\r\nButtonState: "), 0x80);
//PrintHex<uint32_t>(ButtonState[controller], 0x80);
if(ButtonState[controller] != OldButtonState[controller]) {
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
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;
if((uint8_t)(OldButtonState[controller] >> 8) == 0 && (uint8_t)(ButtonState[controller] >> 8) != 0)
L2Clicked[controller] = true;
OldButtonState[controller] = ButtonState[controller];
}
if (ButtonState[controller] != OldButtonState[controller]) {
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
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;
if ((uint8_t)(OldButtonState[controller] >> 8) == 0 && (uint8_t)(ButtonState[controller] >> 8) != 0)
L2Clicked[controller] = true;
OldButtonState[controller] = ButtonState[controller];
}
}
void XBOXRECV::printReport(uint8_t controller, uint8_t nBytes) { //Uncomment "#define PRINTREPORT" to print the report send by the Xbox 360 Controller
#ifdef PRINTREPORT
if (readBuf == NULL)
return;
Notify(PSTR("Controller "), 0x80);
Serial.print(controller);
Notify(PSTR(": "), 0x80);
for(uint8_t i = 0; i < nBytes;i++) {
PrintHex<uint8_t>(readBuf[i], 0x80);
Serial.print(" ");
}
Serial.println();
if (readBuf == NULL)
return;
Notify(PSTR("Controller "), 0x80);
Serial.print(controller);
Notify(PSTR(": "), 0x80);
for (uint8_t i = 0; i < nBytes; i++) {
PrintHex<uint8_t > (readBuf[i], 0x80);
Serial.print(" ");
}
Serial.println();
#endif
}
uint8_t XBOXRECV::getButtonPress(uint8_t controller, Button b) {
if(b == L2) // These are analog buttons
return (uint8_t)(ButtonState[controller] >> 8);
else if(b == R2)
return (uint8_t)ButtonState[controller];
return (ButtonState[controller] & ((uint32_t)pgm_read_word(&XBOXBUTTONS[(uint8_t)b]) << 16));
if (b == L2) // These are analog buttons
return (uint8_t)(ButtonState[controller] >> 8);
else if (b == R2)
return (uint8_t)ButtonState[controller];
return (ButtonState[controller] & ((uint32_t)pgm_read_word(&XBOXBUTTONS[(uint8_t)b]) << 16));
}
bool XBOXRECV::getButtonClick(uint8_t controller, Button b) {
if(b == L2) {
if(L2Clicked[controller]) {
L2Clicked[controller] = false;
return true;
if (b == L2) {
if (L2Clicked[controller]) {
L2Clicked[controller] = false;
return true;
}
return false;
} else if (b == R2) {
if (R2Clicked[controller]) {
R2Clicked[controller] = false;
return true;
}
return false;
}
return false;
}
else if(b == R2) {
if(R2Clicked[controller]) {
R2Clicked[controller] = false;
return true;
}
return false;
}
uint16_t button = pgm_read_word(&XBOXBUTTONS[(uint8_t)b]);
bool click = (ButtonClickState[controller] & button);
ButtonClickState[controller] &= ~button; // clear "click" event
return click;
uint16_t button = pgm_read_word(&XBOXBUTTONS[(uint8_t)b]);
bool click = (ButtonClickState[controller] & button);
ButtonClickState[controller] &= ~button; // clear "click" event
return click;
}
int16_t XBOXRECV::getAnalogHat(uint8_t controller, AnalogHat a) {
return hatValue[controller][a];
return hatValue[controller][a];
}
bool XBOXRECV::buttonChanged(uint8_t controller) {
bool state = buttonStateChanged[controller];
buttonStateChanged[controller] = false;
return state;
bool state = buttonStateChanged[controller];
buttonStateChanged[controller] = false;
return state;
}
/*
ControllerStatus Breakdown
ControllerStatus[controller] & 0x0001 // 0
@ -429,81 +445,90 @@ ControllerStatus Breakdown
ControllerStatus[controller] & 0x2000 // 0
ControllerStatus[controller] & 0x4000 // 0
ControllerStatus[controller] & 0x8000 // 0
*/
*/
uint8_t XBOXRECV::getBatteryLevel(uint8_t controller) {
uint8_t batteryLevel = ((controllerStatus[controller] & 0x00C0) >> 6) * 33;
if(batteryLevel == 99)
batteryLevel = 100;
return batteryLevel;
uint8_t batteryLevel = ((controllerStatus[controller] & 0x00C0) >> 6) * 33;
if (batteryLevel == 99)
batteryLevel = 100;
return batteryLevel;
}
void XBOXRECV::XboxCommand(uint8_t controller, uint8_t* data, uint16_t nbytes) {
uint8_t rcode;
uint8_t outputPipe;
switch (controller) {
case 0: outputPipe = XBOX_OUTPUT_PIPE_1; break;
case 1: outputPipe = XBOX_OUTPUT_PIPE_2; 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);
uint8_t rcode;
uint8_t outputPipe;
switch (controller) {
case 0: outputPipe = XBOX_OUTPUT_PIPE_1;
break;
case 1: outputPipe = XBOX_OUTPUT_PIPE_2;
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);
#ifdef EXTRADEBUG
if(rcode)
Notify(PSTR("Error sending Xbox message\r\n"), 0x80);
if (rcode)
Notify(PSTR("Error sending Xbox message\r\n"), 0x80);
#endif
}
void XBOXRECV::setLedRaw(uint8_t controller, uint8_t value) {
writeBuf[0] = 0x00;
writeBuf[1] = 0x00;
writeBuf[2] = 0x08;
writeBuf[3] = value | 0x40;
XboxCommand(controller, writeBuf, 4);
void XBOXRECV::setLedRaw(uint8_t controller, uint8_t value) {
writeBuf[0] = 0x00;
writeBuf[1] = 0x00;
writeBuf[2] = 0x08;
writeBuf[3] = value | 0x40;
XboxCommand(controller, writeBuf, 4);
}
void XBOXRECV::setLedOn(uint8_t controller, LED led) {
if(led != ALL) // All LEDs can't be on a the same time
setLedRaw(controller,(pgm_read_byte(&XBOXLEDS[(uint8_t)led]))+4);
if (led != ALL) // All LEDs can't be on a the same time
setLedRaw(controller, (pgm_read_byte(&XBOXLEDS[(uint8_t)led])) + 4);
}
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
setLedRaw(controller,(uint8_t)ledMode);
setLedRaw(controller, (uint8_t)ledMode);
}
/* PC runs this at interval of approx 2 seconds
Thanks to BusHound from Perisoft.net for the Windows USB Analysis output
Found by timstamp.co.uk
*/
*/
void XBOXRECV::checkStatus() {
if(!bPollEnable)
return;
// Get controller info
writeBuf[0] = 0x08;
writeBuf[1] = 0x00;
writeBuf[2] = 0x0f;
writeBuf[3] = 0xc0;
for(uint8_t i=0; i<4; i++) {
XboxCommand(i, writeBuf, 4);
}
// Get battery status
writeBuf[0] = 0x00;
writeBuf[1] = 0x00;
writeBuf[2] = 0x00;
writeBuf[3] = 0x40;
for(uint8_t i=0; i<4; i++) {
if(Xbox360Connected[i])
XboxCommand(i, writeBuf, 4);
}
if (!bPollEnable)
return;
// Get controller info
writeBuf[0] = 0x08;
writeBuf[1] = 0x00;
writeBuf[2] = 0x0f;
writeBuf[3] = 0xc0;
for (uint8_t i = 0; i < 4; i++) {
XboxCommand(i, writeBuf, 4);
}
// Get battery status
writeBuf[0] = 0x00;
writeBuf[1] = 0x00;
writeBuf[2] = 0x00;
writeBuf[3] = 0x40;
for (uint8_t i = 0; i < 4; i++) {
if (Xbox360Connected[i])
XboxCommand(i, writeBuf, 4);
}
}
void XBOXRECV::setRumbleOn(uint8_t controller, uint8_t lValue, uint8_t rValue) {
writeBuf[0] = 0x00;
writeBuf[1] = 0x01;
writeBuf[2] = 0x0f;
writeBuf[3] = 0xc0;
writeBuf[4] = 0x00;
writeBuf[5] = lValue; // big weight
writeBuf[6] = rValue; // small weight
writeBuf[0] = 0x00;
writeBuf[1] = 0x01;
writeBuf[2] = 0x0f;
writeBuf[3] = 0xc0;
writeBuf[4] = 0x00;
writeBuf[5] = lValue; // big weight
writeBuf[6] = rValue; // small weight
XboxCommand(controller, writeBuf, 7);
XboxCommand(controller, writeBuf, 7);
}

View file

@ -62,167 +62,183 @@
*/
class XBOXRECV : public USBDeviceConfig {
public:
/**
* Constructor for the XBOXRECV class.
* @param pUsb Pointer to USB class instance.
*/
XBOXRECV(USB *pUsb);
/**
* Constructor for the XBOXRECV class.
* @param pUsb Pointer to USB class instance.
*/
XBOXRECV(USB *pUsb);
/** @name USBDeviceConfig implementation */
/**
* Initialize the Xbox wireless receiver.
* @param parent Hub number.
* @param port Port number on the hub.
* @param lowspeed Speed of the device.
* @return 0 on success.
*/
virtual uint8_t Init(uint8_t parent, uint8_t port, bool lowspeed);
/**
* Release the USB device.
* @return 0 on success.
*/
virtual uint8_t Release();
/**
* Poll the USB Input endpoins and run the state machines.
* @return 0 on success.
*/
virtual uint8_t Poll();
/**
* Get the device address.
* @return The device address.
*/
virtual uint8_t GetAddress() { return bAddress; };
/**
* Used to check if the controller has been initialized.
* @return True if it's ready.
*/
virtual bool isReady() { return bPollEnable; };
/**@}*/
/** @name USBDeviceConfig implementation */
/**
* Initialize the Xbox wireless receiver.
* @param parent Hub number.
* @param port Port number on the hub.
* @param lowspeed Speed of the device.
* @return 0 on success.
*/
virtual uint8_t Init(uint8_t parent, uint8_t port, bool lowspeed);
/**
* Release the USB device.
* @return 0 on success.
*/
virtual uint8_t Release();
/**
* Poll the USB Input endpoins and run the state machines.
* @return 0 on success.
*/
virtual uint8_t Poll();
/** @name Xbox Controller functions */
/**
* getButtonPress(uint8_t controller, Button b) will return true as long as the button is held down.
*
* While getButtonClick(uint8_t controller, Button b) will only return it once.
*
* So you instance if you need to increase a variable once you would use getButtonClick(uint8_t controller, Button b),
* but if you need to drive a robot forward you would use getButtonPress(uint8_t controller, Button b).
* @param controller The controller to read from.
* @param b ::Button to read.
* @return getButtonClick(uint8_t controller, Button b) will return a bool, but getButtonPress(uint8_t controller, Button b)
* will return a byte if reading ::L2 or ::R2.
*/
uint8_t getButtonPress(uint8_t controller, Button b);
bool getButtonClick(uint8_t controller, Button b);
/**@}*/
/**
* Get the device address.
* @return The device address.
*/
virtual uint8_t GetAddress() {
return bAddress;
};
/** @name Xbox Controller functions */
/**
* Return the analog value from the joysticks on the controller.
* @param controller The controller to read from.
* @param a Either ::LeftHatX, ::LeftHatY, ::RightHatX or ::RightHatY.
* @return Returns a signed 16-bit integer.
*/
int16_t getAnalogHat(uint8_t controller, AnalogHat a);
/**
* Turn rumble off and all the LEDs on the specific controller.
* @param controller The controller to write to.
*/
void setAllOff(uint8_t controller) { setRumbleOn(controller,0,0); setLedOff(controller); };
/**
* Turn rumble off the specific controller.
* @param controller The controller to write to.
*/
void setRumbleOff(uint8_t controller) { setRumbleOn(controller,0,0); };
/**
* Turn rumble on.
* @param controller The controller to write to.
* @param lValue Left motor (big weight) inside the controller.
* @param rValue Right motor (small weight) inside the controller.
*/
void setRumbleOn(uint8_t controller, uint8_t lValue, uint8_t rValue);
/**
* Set LED value. Without using the ::LED or ::LEDMode enum.
* @param controller The controller to write to.
* @param value See:
* setLedOff(uint8_t controller), setLedOn(uint8_t controller, LED l),
* setLedBlink(uint8_t controller, LED l), and setLedMode(uint8_t controller, LEDMode lm).
*/
void setLedRaw(uint8_t controller, uint8_t value);
/**
* Turn all LEDs off the specific controller.
* @param controller The controller to write to.
*/
void setLedOff(uint8_t controller) { setLedRaw(controller,0); };
/**
* Turn on a LED by using the ::LED enum.
* @param controller The controller to write to.
* @param l ::LED1, ::LED2, ::LED3 and ::LED4 is supported by the Xbox controller.
*/
void setLedOn(uint8_t controller, LED l);
/**
* Turn on a LED by using the ::LED enum.
* @param controller The controller to write to.
* @param l ::ALL, ::LED1, ::LED2, ::LED3 and ::LED4 is supported by the Xbox controller.
*/
void setLedBlink(uint8_t controller, LED l);
/**
* Used to set special LED modes supported by the Xbox controller.
* @param controller The controller to write to.
* @param lm See ::LEDMode.
*/
void setLedMode(uint8_t controller, LEDMode lm);
/**
* Used to get the battery level from the controller.
* @param controller The controller to read from.
* @return Returns the battery level in percentage in 33% steps.
*/
uint8_t getBatteryLevel(uint8_t controller);
/**
* Used to check if a button has changed.
* @param controller The controller to read from.
* @return True if a button has changed.
*/
bool buttonChanged(uint8_t controller);
/**@}*/
/**
* Used to check if the controller has been initialized.
* @return True if it's ready.
*/
virtual bool isReady() {
return bPollEnable;
};
/**@}*/
/** True if a wireless receiver is connected. */
bool XboxReceiverConnected;
/** Variable used to indicate if the XBOX 360 controller is successfully connected. */
uint8_t Xbox360Connected[4];
/** @name Xbox Controller functions */
/**
* getButtonPress(uint8_t controller, Button b) will return true as long as the button is held down.
*
* While getButtonClick(uint8_t controller, Button b) will only return it once.
*
* So you instance if you need to increase a variable once you would use getButtonClick(uint8_t controller, Button b),
* but if you need to drive a robot forward you would use getButtonPress(uint8_t controller, Button b).
* @param controller The controller to read from.
* @param b ::Button to read.
* @return getButtonClick(uint8_t controller, Button b) will return a bool, but getButtonPress(uint8_t controller, Button b)
* will return a byte if reading ::L2 or ::R2.
*/
uint8_t getButtonPress(uint8_t controller, Button b);
bool getButtonClick(uint8_t controller, Button b);
/**@}*/
/** @name Xbox Controller functions */
/**
* Return the analog value from the joysticks on the controller.
* @param controller The controller to read from.
* @param a Either ::LeftHatX, ::LeftHatY, ::RightHatX or ::RightHatY.
* @return Returns a signed 16-bit integer.
*/
int16_t getAnalogHat(uint8_t controller, AnalogHat a);
/**
* Turn rumble off and all the LEDs on the specific controller.
* @param controller The controller to write to.
*/
void setAllOff(uint8_t controller) {
setRumbleOn(controller, 0, 0);
setLedOff(controller);
};
/**
* Turn rumble off the specific controller.
* @param controller The controller to write to.
*/
void setRumbleOff(uint8_t controller) {
setRumbleOn(controller, 0, 0);
};
/**
* Turn rumble on.
* @param controller The controller to write to.
* @param lValue Left motor (big weight) inside the controller.
* @param rValue Right motor (small weight) inside the controller.
*/
void setRumbleOn(uint8_t controller, uint8_t lValue, uint8_t rValue);
/**
* Set LED value. Without using the ::LED or ::LEDMode enum.
* @param controller The controller to write to.
* @param value See:
* setLedOff(uint8_t controller), setLedOn(uint8_t controller, LED l),
* setLedBlink(uint8_t controller, LED l), and setLedMode(uint8_t controller, LEDMode lm).
*/
void setLedRaw(uint8_t controller, uint8_t value);
/**
* Turn all LEDs off the specific controller.
* @param controller The controller to write to.
*/
void setLedOff(uint8_t controller) {
setLedRaw(controller, 0);
};
/**
* Turn on a LED by using the ::LED enum.
* @param controller The controller to write to.
* @param l ::LED1, ::LED2, ::LED3 and ::LED4 is supported by the Xbox controller.
*/
void setLedOn(uint8_t controller, LED l);
/**
* Turn on a LED by using the ::LED enum.
* @param controller The controller to write to.
* @param l ::ALL, ::LED1, ::LED2, ::LED3 and ::LED4 is supported by the Xbox controller.
*/
void setLedBlink(uint8_t controller, LED l);
/**
* Used to set special LED modes supported by the Xbox controller.
* @param controller The controller to write to.
* @param lm See ::LEDMode.
*/
void setLedMode(uint8_t controller, LEDMode lm);
/**
* Used to get the battery level from the controller.
* @param controller The controller to read from.
* @return Returns the battery level in percentage in 33% steps.
*/
uint8_t getBatteryLevel(uint8_t controller);
/**
* Used to check if a button has changed.
* @param controller The controller to read from.
* @return True if a button has changed.
*/
bool buttonChanged(uint8_t controller);
/**@}*/
/** True if a wireless receiver is connected. */
bool XboxReceiverConnected;
/** Variable used to indicate if the XBOX 360 controller is successfully connected. */
uint8_t Xbox360Connected[4];
protected:
/** Pointer to USB class instance. */
USB *pUsb;
/** Device address. */
uint8_t bAddress;
/** Endpoint info structure. */
EpInfo epInfo[XBOX_MAX_ENDPOINTS];
/** Pointer to USB class instance. */
USB *pUsb;
/** Device address. */
uint8_t bAddress;
/** Endpoint info structure. */
EpInfo epInfo[XBOX_MAX_ENDPOINTS];
private:
bool bPollEnable;
bool bPollEnable;
/* Variables to store the buttons */
uint32_t ButtonState[4];
uint32_t OldButtonState[4];
uint16_t ButtonClickState[4];
int16_t hatValue[4][4];
uint16_t controllerStatus[4];
bool buttonStateChanged[4]; // True if a button has changed
/* Variables to store the buttons */
uint32_t ButtonState[4];
uint32_t OldButtonState[4];
uint16_t ButtonClickState[4];
int16_t hatValue[4][4];
uint16_t controllerStatus[4];
bool buttonStateChanged[4]; // True if a button has changed
bool L2Clicked[4]; // These buttons are analog, so we use we use these bools to check if they where clicked or not
bool R2Clicked[4];
bool L2Clicked[4]; // These buttons are analog, so we use we use these bools to check if they where clicked or not
bool R2Clicked[4];
unsigned long timer; // Timing for checkStatus() signals
unsigned long timer; // Timing for checkStatus() signals
uint8_t readBuf[EP_MAXPKTSIZE]; // General purpose buffer for input data
uint8_t writeBuf[EP_MAXPKTSIZE]; // General purpose buffer for output data
uint8_t readBuf[EP_MAXPKTSIZE]; // General purpose buffer for input data
uint8_t writeBuf[EP_MAXPKTSIZE]; // General purpose buffer for output data
void readReport(uint8_t controller); // read incoming data
void printReport(uint8_t controller, uint8_t nBytes); // print incoming date - Uncomment for debugging
void readReport(uint8_t controller); // read incoming data
void printReport(uint8_t controller, uint8_t nBytes); // print incoming date - Uncomment for debugging
/* Private commands */
void XboxCommand(uint8_t controller, uint8_t* data, uint16_t nbytes);
void checkStatus();
/* Private commands */
void XboxCommand(uint8_t controller, uint8_t* data, uint16_t nbytes);
void checkStatus();
};
#endif

View file

@ -20,323 +20,329 @@
//#define EXTRADEBUG // Uncomment to get even more debugging data
//#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
bAddress(0), // device address - mandatory
bPollEnable(false) { // don't start polling before dongle is connected
for(uint8_t i=0; i<XBOX_MAX_ENDPOINTS; i++) {
epInfo[i].epAddr = 0;
epInfo[i].maxPktSize = (i) ? 0 : 8;
epInfo[i].epAttribs = 0;
epInfo[i].bmNakPower = (i) ? USB_NAK_NOWAIT : USB_NAK_MAX_POWER;
}
for (uint8_t i = 0; i < XBOX_MAX_ENDPOINTS; i++) {
epInfo[i].epAddr = 0;
epInfo[i].maxPktSize = (i) ? 0 : 8;
epInfo[i].epAttribs = 0;
epInfo[i].bmNakPower = (i) ? USB_NAK_NOWAIT : USB_NAK_MAX_POWER;
}
if (pUsb) // register in USB subsystem
pUsb->RegisterDeviceClass(this); //set devConfig[] entry
if (pUsb) // register in USB subsystem
pUsb->RegisterDeviceClass(this); //set devConfig[] entry
}
uint8_t XBOXUSB::Init(uint8_t parent, uint8_t port, bool lowspeed) {
uint8_t buf[sizeof(USB_DEVICE_DESCRIPTOR)];
uint8_t rcode;
UsbDevice *p = NULL;
EpInfo *oldep_ptr = NULL;
uint16_t PID;
uint16_t VID;
uint8_t buf[sizeof (USB_DEVICE_DESCRIPTOR)];
uint8_t rcode;
UsbDevice *p = NULL;
EpInfo *oldep_ptr = NULL;
uint16_t PID;
uint16_t VID;
// get memory address of USB device address pool
AddressPool &addrPool = pUsb->GetAddressPool();
// get memory address of USB device address pool
AddressPool &addrPool = pUsb->GetAddressPool();
#ifdef EXTRADEBUG
Notify(PSTR("\r\nXBOXUSB Init"), 0x80);
Notify(PSTR("\r\nXBOXUSB Init"), 0x80);
#endif
// check if address has already been assigned to an instance
if (bAddress) {
// check if address has already been assigned to an instance
if (bAddress) {
#ifdef DEBUG
Notify(PSTR("\r\nAddress in use"), 0x80);
Notify(PSTR("\r\nAddress in use"), 0x80);
#endif
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
p = addrPool.GetUsbDevicePtr(0);
// Get pointer to pseudo device with address 0 assigned
p = addrPool.GetUsbDevicePtr(0);
if (!p) {
if (!p) {
#ifdef DEBUG
Notify(PSTR("\r\nAddress not found"), 0x80);
Notify(PSTR("\r\nAddress not found"), 0x80);
#endif
return USB_ERROR_ADDRESS_NOT_FOUND_IN_POOL;
}
return USB_ERROR_ADDRESS_NOT_FOUND_IN_POOL;
}
if (!p->epinfo) {
if (!p->epinfo) {
#ifdef DEBUG
Notify(PSTR("\r\nepinfo is null"), 0x80);
Notify(PSTR("\r\nepinfo is null"), 0x80);
#endif
return USB_ERROR_EPINFO_IS_NULL;
}
return USB_ERROR_EPINFO_IS_NULL;
}
// Save old pointer to EP_RECORD of address 0
oldep_ptr = p->epinfo;
// Save old pointer to EP_RECORD of address 0
oldep_ptr = p->epinfo;
// Temporary assign new pointer to epInfo to p->epinfo in order to avoid toggle inconsistence
p->epinfo = epInfo;
// Temporary assign new pointer to epInfo to p->epinfo in order to avoid toggle inconsistence
p->epinfo = epInfo;
p->lowspeed = lowspeed;
p->lowspeed = lowspeed;
// Get device descriptor
rcode = pUsb->getDevDescr(0, 0, sizeof(USB_DEVICE_DESCRIPTOR), (uint8_t*)buf);// Get device descriptor - addr, ep, nbytes, data
// Restore p->epinfo
p->epinfo = oldep_ptr;
// Get device descriptor
rcode = pUsb->getDevDescr(0, 0, sizeof (USB_DEVICE_DESCRIPTOR), (uint8_t*)buf); // Get device descriptor - addr, ep, nbytes, data
// Restore p->epinfo
p->epinfo = oldep_ptr;
if(rcode)
goto FailGetDevDescr;
if (rcode)
goto FailGetDevDescr;
VID = ((USB_DEVICE_DESCRIPTOR*)buf)->idVendor;
PID = ((USB_DEVICE_DESCRIPTOR*)buf)->idProduct;
VID = ((USB_DEVICE_DESCRIPTOR*)buf)->idVendor;
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
goto FailUnknownDevice;
if(PID == XBOX_WIRELESS_PID) {
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;
if (PID == XBOX_WIRELESS_PID) {
#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
goto FailUnknownDevice;
}
else if(PID == XBOX_WIRELESS_RECEIVER_PID || PID == XBOX_WIRELESS_RECEIVER_THIRD_PARTY_PID) {
goto FailUnknownDevice;
} else if (PID == XBOX_WIRELESS_RECEIVER_PID || PID == XBOX_WIRELESS_RECEIVER_THIRD_PARTY_PID) {
#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
goto FailUnknownDevice;
}
goto FailUnknownDevice;
}
// Allocate new address according to device class
bAddress = addrPool.AllocAddress(parent, false, port);
// Allocate new address according to device class
bAddress = addrPool.AllocAddress(parent, false, port);
if (!bAddress)
return USB_ERROR_OUT_OF_ADDRESS_SPACE_IN_POOL;
if (!bAddress)
return USB_ERROR_OUT_OF_ADDRESS_SPACE_IN_POOL;
// Extract Max Packet Size from device descriptor
epInfo[0].maxPktSize = (uint8_t)((USB_DEVICE_DESCRIPTOR*)buf)->bMaxPacketSize0;
// Extract Max Packet Size from device descriptor
epInfo[0].maxPktSize = (uint8_t)((USB_DEVICE_DESCRIPTOR*)buf)->bMaxPacketSize0;
// Assign new address to the device
rcode = pUsb->setAddr( 0, 0, bAddress );
if (rcode) {
// Assign new address to the device
rcode = pUsb->setAddr(0, 0, bAddress);
if (rcode) {
p->lowspeed = false;
addrPool.FreeAddress(bAddress);
bAddress = 0;
#ifdef DEBUG
Notify(PSTR("\r\nsetAddr: "), 0x80);
#endif
PrintHex<uint8_t > (rcode, 0x80);
return rcode;
}
#ifdef EXTRADEBUG
Notify(PSTR("\r\nAddr: "), 0x80);
PrintHex<uint8_t > (bAddress, 0x80);
#endif
p->lowspeed = false;
addrPool.FreeAddress(bAddress);
bAddress = 0;
#ifdef DEBUG
Notify(PSTR("\r\nsetAddr: "), 0x80);
#endif
PrintHex<uint8_t>(rcode, 0x80);
return rcode;
}
#ifdef EXTRADEBUG
Notify(PSTR("\r\nAddr: "), 0x80);
PrintHex<uint8_t>(bAddress, 0x80);
#endif
p->lowspeed = false;
//get pointer to assigned address record
p = addrPool.GetUsbDevicePtr(bAddress);
if (!p)
return USB_ERROR_ADDRESS_NOT_FOUND_IN_POOL;
//get pointer to assigned address record
p = addrPool.GetUsbDevicePtr(bAddress);
if (!p)
return USB_ERROR_ADDRESS_NOT_FOUND_IN_POOL;
p->lowspeed = lowspeed;
p->lowspeed = lowspeed;
// Assign epInfo to epinfo pointer - only EP0 is known
rcode = pUsb->setEpInfoEntry(bAddress, 1, epInfo);
if (rcode)
goto FailSetDevTblEntry;
// Assign epInfo to epinfo pointer - only EP0 is known
rcode = pUsb->setEpInfoEntry(bAddress, 1, epInfo);
if (rcode)
goto FailSetDevTblEntry;
/* The application will work in reduced host mode, so we can save program and data
memory space. After verifying the VID we will use known values for the
configuration values for device, interface, endpoints and HID for the XBOX360 Controllers */
/* The application will work in reduced host mode, so we can save program and data
memory space. After verifying the VID we will use known values for the
configuration values for device, interface, endpoints and HID for the XBOX360 Controllers */
/* Initialize data structures for endpoints of device */
epInfo[ XBOX_INPUT_PIPE ].epAddr = 0x01; // XBOX 360 report endpoint
epInfo[ XBOX_INPUT_PIPE ].epAttribs = EP_INTERRUPT;
epInfo[ XBOX_INPUT_PIPE ].bmNakPower = USB_NAK_NOWAIT; // Only poll once for interrupt endpoints
epInfo[ XBOX_INPUT_PIPE ].maxPktSize = EP_MAXPKTSIZE;
epInfo[ XBOX_INPUT_PIPE ].bmSndToggle = bmSNDTOG0;
epInfo[ XBOX_INPUT_PIPE ].bmRcvToggle = bmRCVTOG0;
epInfo[ XBOX_OUTPUT_PIPE ].epAddr = 0x02; // XBOX 360 output endpoint
epInfo[ XBOX_OUTPUT_PIPE ].epAttribs = EP_INTERRUPT;
epInfo[ XBOX_OUTPUT_PIPE ].bmNakPower = USB_NAK_NOWAIT; // Only poll once for interrupt endpoints
epInfo[ XBOX_OUTPUT_PIPE ].maxPktSize = EP_MAXPKTSIZE;
epInfo[ XBOX_OUTPUT_PIPE ].bmSndToggle = bmSNDTOG0;
epInfo[ XBOX_OUTPUT_PIPE ].bmRcvToggle = bmRCVTOG0;
/* Initialize data structures for endpoints of device */
epInfo[ XBOX_INPUT_PIPE ].epAddr = 0x01; // XBOX 360 report endpoint
epInfo[ XBOX_INPUT_PIPE ].epAttribs = EP_INTERRUPT;
epInfo[ XBOX_INPUT_PIPE ].bmNakPower = USB_NAK_NOWAIT; // Only poll once for interrupt endpoints
epInfo[ XBOX_INPUT_PIPE ].maxPktSize = EP_MAXPKTSIZE;
epInfo[ XBOX_INPUT_PIPE ].bmSndToggle = bmSNDTOG0;
epInfo[ XBOX_INPUT_PIPE ].bmRcvToggle = bmRCVTOG0;
epInfo[ XBOX_OUTPUT_PIPE ].epAddr = 0x02; // XBOX 360 output endpoint
epInfo[ XBOX_OUTPUT_PIPE ].epAttribs = EP_INTERRUPT;
epInfo[ XBOX_OUTPUT_PIPE ].bmNakPower = USB_NAK_NOWAIT; // Only poll once for interrupt endpoints
epInfo[ XBOX_OUTPUT_PIPE ].maxPktSize = EP_MAXPKTSIZE;
epInfo[ XBOX_OUTPUT_PIPE ].bmSndToggle = bmSNDTOG0;
epInfo[ XBOX_OUTPUT_PIPE ].bmRcvToggle = bmRCVTOG0;
rcode = pUsb->setEpInfoEntry(bAddress, 3, epInfo);
if( rcode )
goto FailSetDevTblEntry;
rcode = pUsb->setEpInfoEntry(bAddress, 3, epInfo);
if (rcode)
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);
if( rcode )
goto FailSetConf;
rcode = pUsb->setConf(bAddress, epInfo[ XBOX_CONTROL_PIPE ].epAddr, 1);
if (rcode)
goto FailSetConf;
#ifdef DEBUG
Notify(PSTR("\r\nXbox 360 Controller Connected\r\n"), 0x80);
Notify(PSTR("\r\nXbox 360 Controller Connected\r\n"), 0x80);
#endif
setLedOn(LED1);
Xbox360Connected = true;
bPollEnable = true;
return 0; // successful configuration
setLedOn(LED1);
Xbox360Connected = true;
bPollEnable = true;
return 0; // successful configuration
/* diagnostic messages */
/* diagnostic messages */
FailGetDevDescr:
#ifdef DEBUG
Notify(PSTR("\r\ngetDevDescr:"), 0x80);
Notify(PSTR("\r\ngetDevDescr:"), 0x80);
#endif
goto Fail;
goto Fail;
FailSetDevTblEntry:
#ifdef DEBUG
Notify(PSTR("\r\nsetDevTblEn:"), 0x80);
Notify(PSTR("\r\nsetDevTblEn:"), 0x80);
#endif
goto Fail;
goto Fail;
FailSetConf:
#ifdef DEBUG
Notify(PSTR("\r\nsetConf:"), 0x80);
Notify(PSTR("\r\nsetConf:"), 0x80);
#endif
goto Fail;
goto Fail;
FailUnknownDevice:
#ifdef DEBUG
Notify(PSTR("\r\nUnknown Device Connected - VID: "), 0x80);
PrintHex<uint16_t>(VID, 0x80);
Notify(PSTR(" PID: "), 0x80);
PrintHex<uint16_t>(PID, 0x80);
Notify(PSTR("\r\nUnknown Device Connected - VID: "), 0x80);
PrintHex<uint16_t > (VID, 0x80);
Notify(PSTR(" PID: "), 0x80);
PrintHex<uint16_t > (PID, 0x80);
#endif
rcode = USB_DEV_CONFIG_ERROR_DEVICE_NOT_SUPPORTED;
goto Fail;
rcode = USB_DEV_CONFIG_ERROR_DEVICE_NOT_SUPPORTED;
goto Fail;
Fail:
#ifdef DEBUG
Notify(PSTR("\r\nXbox 360 Init Failed, error code: "), 0x80);
Serial.print(rcode,HEX);
Notify(PSTR("\r\nXbox 360 Init Failed, error code: "), 0x80);
Serial.print(rcode, HEX);
#endif
Release();
return rcode;
Release();
return rcode;
}
/* Performs a cleanup after failed Init() attempt */
uint8_t XBOXUSB::Release() {
Xbox360Connected = false;
pUsb->GetAddressPool().FreeAddress(bAddress);
bAddress = 0;
bPollEnable = false;
return 0;
Xbox360Connected = false;
pUsb->GetAddressPool().FreeAddress(bAddress);
bAddress = 0;
bPollEnable = false;
return 0;
}
uint8_t XBOXUSB::Poll() {
if (!bPollEnable)
return 0;
uint16_t BUFFER_SIZE = EP_MAXPKTSIZE;
pUsb->inTransfer(bAddress, epInfo[ XBOX_INPUT_PIPE ].epAddr, &BUFFER_SIZE, readBuf); // input on endpoint 1
readReport();
if (!bPollEnable)
return 0;
uint16_t BUFFER_SIZE = EP_MAXPKTSIZE;
pUsb->inTransfer(bAddress, epInfo[ XBOX_INPUT_PIPE ].epAddr, &BUFFER_SIZE, readBuf); // input on endpoint 1
readReport();
#ifdef PRINTREPORT
printReport(); // Uncomment "#define PRINTREPORT" to print the report send by the Xbox 360 Controller
printReport(); // Uncomment "#define PRINTREPORT" to print the report send by the Xbox 360 Controller
#endif
return 0;
return 0;
}
void XBOXUSB::readReport() {
if (readBuf == NULL)
return;
if(readBuf[0] != 0x00 || readBuf[1] != 0x14) { // Check if it's the correct report - the controller also sends different status reports
return;
}
if (readBuf == NULL)
return;
if (readBuf[0] != 0x00 || readBuf[1] != 0x14) { // Check if it's the correct report - the controller also sends different status reports
return;
}
ButtonState = (uint32_t)(readBuf[5] | ((uint16_t)readBuf[4] << 8) | ((uint32_t)readBuf[3] << 16) | ((uint32_t)readBuf[2] << 24));
ButtonState = (uint32_t)(readBuf[5] | ((uint16_t)readBuf[4] << 8) | ((uint32_t)readBuf[3] << 16) | ((uint32_t)readBuf[2] << 24));
hatValue[LeftHatX] = (int16_t)(((uint16_t)readBuf[7] << 8) | readBuf[6]);
hatValue[LeftHatY] = (int16_t)(((uint16_t)readBuf[9] << 8) | readBuf[8]);
hatValue[RightHatX] = (int16_t)(((uint16_t)readBuf[11] << 8) | readBuf[10]);
hatValue[RightHatY] = (int16_t)(((uint16_t)readBuf[13] << 8) | readBuf[12]);
hatValue[LeftHatX] = (int16_t)(((uint16_t)readBuf[7] << 8) | readBuf[6]);
hatValue[LeftHatY] = (int16_t)(((uint16_t)readBuf[9] << 8) | readBuf[8]);
hatValue[RightHatX] = (int16_t)(((uint16_t)readBuf[11] << 8) | readBuf[10]);
hatValue[RightHatY] = (int16_t)(((uint16_t)readBuf[13] << 8) | readBuf[12]);
//Notify(PSTR("\r\nButtonState"), 0x80);
//PrintHex<uint32_t>(ButtonState, 0x80);
//Notify(PSTR("\r\nButtonState"), 0x80);
//PrintHex<uint32_t>(ButtonState, 0x80);
if(ButtonState != OldButtonState) {
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
R2Clicked = true;
if((uint8_t)(OldButtonState >> 8) == 0 && (uint8_t)(ButtonState >> 8) != 0)
L2Clicked = true;
OldButtonState = ButtonState;
}
if (ButtonState != OldButtonState) {
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
R2Clicked = true;
if ((uint8_t)(OldButtonState >> 8) == 0 && (uint8_t)(ButtonState >> 8) != 0)
L2Clicked = true;
OldButtonState = ButtonState;
}
}
void XBOXUSB::printReport() { //Uncomment "#define PRINTREPORT" to print the report send by the Xbox 360 Controller
#ifdef PRINTREPORT
if (readBuf == NULL)
return;
for(uint8_t i = 0; i < XBOX_REPORT_BUFFER_SIZE;i++) {
PrintHex<uint8_t>(readBuf[i], 0x80);
Serial.print(" ");
}
Serial.println();
if (readBuf == NULL)
return;
for (uint8_t i = 0; i < XBOX_REPORT_BUFFER_SIZE; i++) {
PrintHex<uint8_t > (readBuf[i], 0x80);
Serial.print(" ");
}
Serial.println();
#endif
}
uint8_t XBOXUSB::getButtonPress(Button b) {
if(b == L2) // These are analog buttons
return (uint8_t)(ButtonState >> 8);
else if(b == R2)
return (uint8_t)ButtonState;
return (ButtonState & ((uint32_t)pgm_read_word(&XBOXBUTTONS[(uint8_t)b]) << 16));
if (b == L2) // These are analog buttons
return (uint8_t)(ButtonState >> 8);
else if (b == R2)
return (uint8_t)ButtonState;
return (ButtonState & ((uint32_t)pgm_read_word(&XBOXBUTTONS[(uint8_t)b]) << 16));
}
bool XBOXUSB::getButtonClick(Button b) {
if(b == L2) {
if(L2Clicked) {
L2Clicked = false;
return true;
if (b == L2) {
if (L2Clicked) {
L2Clicked = false;
return true;
}
return false;
} else if (b == R2) {
if (R2Clicked) {
R2Clicked = false;
return true;
}
return false;
}
return false;
}
else if(b == R2) {
if(R2Clicked) {
R2Clicked = false;
return true;
}
return false;
}
uint16_t button = pgm_read_word(&XBOXBUTTONS[(uint8_t)b]);
bool click = (ButtonClickState & button);
ButtonClickState &= ~button; // clear "click" event
return click;
uint16_t button = pgm_read_word(&XBOXBUTTONS[(uint8_t)b]);
bool click = (ButtonClickState & button);
ButtonClickState &= ~button; // clear "click" event
return click;
}
int16_t XBOXUSB::getAnalogHat(AnalogHat a) {
return hatValue[a];
return hatValue[a];
}
/* Xbox Controller commands */
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)
pUsb->ctrlReq(bAddress,epInfo[XBOX_CONTROL_PIPE].epAddr, bmREQ_HID_OUT, HID_REQUEST_SET_REPORT, 0x00, 0x02, 0x00, nbytes, nbytes, data, NULL);
//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);
}
void XBOXUSB::setLedRaw(uint8_t value) {
writeBuf[0] = 0x01;
writeBuf[1] = 0x03;
writeBuf[2] = value;
writeBuf[0] = 0x01;
writeBuf[1] = 0x03;
writeBuf[2] = value;
XboxCommand(writeBuf, 3);
XboxCommand(writeBuf, 3);
}
void XBOXUSB::setLedOn(LED led) {
if(led != ALL) // All LEDs can't be on a the same time
setLedRaw((pgm_read_byte(&XBOXLEDS[(uint8_t)led]))+4);
if (led != ALL) // All LEDs can't be on a the same time
setLedRaw((pgm_read_byte(&XBOXLEDS[(uint8_t)led])) + 4);
}
void XBOXUSB::setLedBlink(LED 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
setLedRaw((uint8_t)ledMode);
}
void XBOXUSB::setRumbleOn(uint8_t lValue, uint8_t rValue) {
writeBuf[0] = 0x00;
writeBuf[1] = 0x08;
writeBuf[2] = 0x00;
writeBuf[3] = lValue; // big weight
writeBuf[4] = rValue; // small weight
writeBuf[5] = 0x00;
writeBuf[6] = 0x00;
writeBuf[7] = 0x00;
XboxCommand(writeBuf, 8);
void XBOXUSB::setLedBlink(LED 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
setLedRaw((uint8_t)ledMode);
}
void XBOXUSB::setRumbleOn(uint8_t lValue, uint8_t rValue) {
writeBuf[0] = 0x00;
writeBuf[1] = 0x08;
writeBuf[2] = 0x00;
writeBuf[3] = lValue; // big weight
writeBuf[4] = rValue; // small weight
writeBuf[5] = 0x00;
writeBuf[6] = 0x00;
writeBuf[7] = 0x00;
XboxCommand(writeBuf, 8);
}

247
XBOXUSB.h
View file

@ -58,135 +58,150 @@
/** This class implements support for a Xbox wired controller via USB. */
class XBOXUSB : public USBDeviceConfig {
public:
/**
* Constructor for the XBOXUSB class.
* @param pUsb Pointer to USB class instance.
*/
XBOXUSB(USB *pUsb);
/**
* Constructor for the XBOXUSB class.
* @param pUsb Pointer to USB class instance.
*/
XBOXUSB(USB *pUsb);
/** @name USBDeviceConfig implementation */
/**
* Initialize the Xbox Controller.
* @param parent Hub number.
* @param port Port number on the hub.
* @param lowspeed Speed of the device.
* @return 0 on success.
*/
virtual uint8_t Init(uint8_t parent, uint8_t port, bool lowspeed);
/**
* Release the USB device.
* @return 0 on success.
*/
virtual uint8_t Release();
/**
* Poll the USB Input endpoins and run the state machines.
* @return 0 on success.
*/
virtual uint8_t Poll();
/**
* Get the device address.
* @return The device address.
*/
virtual uint8_t GetAddress() { return bAddress; };
/**
* Used to check if the controller has been initialized.
* @return True if it's ready.
*/
virtual bool isReady() { return bPollEnable; };
/**@}*/
/** @name USBDeviceConfig implementation */
/**
* Initialize the Xbox Controller.
* @param parent Hub number.
* @param port Port number on the hub.
* @param lowspeed Speed of the device.
* @return 0 on success.
*/
virtual uint8_t Init(uint8_t parent, uint8_t port, bool lowspeed);
/**
* Release the USB device.
* @return 0 on success.
*/
virtual uint8_t Release();
/**
* Poll the USB Input endpoins and run the state machines.
* @return 0 on success.
*/
virtual uint8_t Poll();
/** @name Xbox Controller functions */
/**
* getButtonPress(Button b) will return true as long as the button is held down.
*
* While getButtonClick(Button b) will only return it once.
*
* So you instance if you need to increase a variable once you would use getButtonClick(Button b),
* but if you need to drive a robot forward you would use getButtonPress(Button b).
* @param b ::Button to read.
* @return getButtonClick(Button b) will return a bool, but getButtonPress(Button b)
* will return a byte if reading ::L2 or ::R2.
*/
uint8_t getButtonPress(Button b);
bool getButtonClick(Button b);
/**@}*/
/**
* Get the device address.
* @return The device address.
*/
virtual uint8_t GetAddress() {
return bAddress;
};
/** @name Xbox Controller functions */
/**
* Return the analog value from the joysticks on the controller.
* @param a Either ::LeftHatX, ::LeftHatY, ::RightHatX or ::RightHatY.
* @return Returns a signed 16-bit integer.
*/
int16_t getAnalogHat(AnalogHat a);
/**
* Used to check if the controller has been initialized.
* @return True if it's ready.
*/
virtual bool isReady() {
return bPollEnable;
};
/**@}*/
/** Turn rumble off and all the LEDs on the controller. */
void setAllOff() { setRumbleOn(0,0); setLedRaw(0); };
/** Turn rumble off the controller. */
void setRumbleOff() { setRumbleOn(0,0); };
/**
* Turn rumble on.
* @param lValue Left motor (big weight) inside the controller.
* @param rValue Right motor (small weight) inside the controller.
*/
void setRumbleOn(uint8_t lValue, uint8_t rValue);
/**
* Set LED value. Without using the ::LED or ::LEDMode enum.
* @param value See:
* setLedOff(), setLedOn(LED l),
* setLedBlink(LED l), and setLedMode(LEDMode lm).
*/
void setLedRaw(uint8_t value);
/** Turn all LEDs off the controller. */
void setLedOff() { setLedRaw(0); };
/**
* Turn on a LED by using the ::LED enum.
* @param l ::LED1, ::LED2, ::LED3 and ::LED4 is supported by the Xbox controller.
*/
void setLedOn(LED l);
/**
* Turn on a LED by using the ::LED enum.
* @param l ::ALL, ::LED1, ::LED2, ::LED3 and ::LED4 is supported by the Xbox controller.
*/
void setLedBlink(LED l);
/**
* Used to set special LED modes supported by the Xbox controller.
* @param controller The controller to write to.
* @param lm See ::LEDMode.
*/
void setLedMode(LEDMode lm);
/**@}*/
/** @name Xbox Controller functions */
/**
* getButtonPress(Button b) will return true as long as the button is held down.
*
* While getButtonClick(Button b) will only return it once.
*
* So you instance if you need to increase a variable once you would use getButtonClick(Button b),
* but if you need to drive a robot forward you would use getButtonPress(Button b).
* @param b ::Button to read.
* @return getButtonClick(Button b) will return a bool, but getButtonPress(Button b)
* will return a byte if reading ::L2 or ::R2.
*/
uint8_t getButtonPress(Button b);
bool getButtonClick(Button b);
/**@}*/
/** True if a Xbox 360 controller is connected. */
bool Xbox360Connected;
/** @name Xbox Controller functions */
/**
* Return the analog value from the joysticks on the controller.
* @param a Either ::LeftHatX, ::LeftHatY, ::RightHatX or ::RightHatY.
* @return Returns a signed 16-bit integer.
*/
int16_t getAnalogHat(AnalogHat a);
/** Turn rumble off and all the LEDs on the controller. */
void setAllOff() {
setRumbleOn(0, 0);
setLedRaw(0);
};
/** Turn rumble off the controller. */
void setRumbleOff() {
setRumbleOn(0, 0);
};
/**
* Turn rumble on.
* @param lValue Left motor (big weight) inside the controller.
* @param rValue Right motor (small weight) inside the controller.
*/
void setRumbleOn(uint8_t lValue, uint8_t rValue);
/**
* Set LED value. Without using the ::LED or ::LEDMode enum.
* @param value See:
* setLedOff(), setLedOn(LED l),
* setLedBlink(LED l), and setLedMode(LEDMode lm).
*/
void setLedRaw(uint8_t value);
/** Turn all LEDs off the controller. */
void setLedOff() {
setLedRaw(0);
};
/**
* Turn on a LED by using the ::LED enum.
* @param l ::LED1, ::LED2, ::LED3 and ::LED4 is supported by the Xbox controller.
*/
void setLedOn(LED l);
/**
* Turn on a LED by using the ::LED enum.
* @param l ::ALL, ::LED1, ::LED2, ::LED3 and ::LED4 is supported by the Xbox controller.
*/
void setLedBlink(LED l);
/**
* Used to set special LED modes supported by the Xbox controller.
* @param controller The controller to write to.
* @param lm See ::LEDMode.
*/
void setLedMode(LEDMode lm);
/**@}*/
/** True if a Xbox 360 controller is connected. */
bool Xbox360Connected;
protected:
/** Pointer to USB class instance. */
USB *pUsb;
/** Device address. */
uint8_t bAddress;
/** Endpoint info structure. */
EpInfo epInfo[XBOX_MAX_ENDPOINTS];
/** Pointer to USB class instance. */
USB *pUsb;
/** Device address. */
uint8_t bAddress;
/** Endpoint info structure. */
EpInfo epInfo[XBOX_MAX_ENDPOINTS];
private:
bool bPollEnable;
bool bPollEnable;
/* Variables to store the buttons */
uint32_t ButtonState;
uint32_t OldButtonState;
uint16_t ButtonClickState;
int16_t hatValue[4];
uint16_t controllerStatus;
/* Variables to store the buttons */
uint32_t ButtonState;
uint32_t OldButtonState;
uint16_t ButtonClickState;
int16_t hatValue[4];
uint16_t controllerStatus;
bool L2Clicked; // These buttons are analog, so we use we use these bools to check if they where clicked or not
bool R2Clicked;
bool L2Clicked; // These buttons are analog, so we use we use these bools to check if they where clicked or not
bool R2Clicked;
uint8_t readBuf[EP_MAXPKTSIZE]; // General purpose buffer for input data
uint8_t writeBuf[EP_MAXPKTSIZE]; // General purpose buffer for output data
uint8_t readBuf[EP_MAXPKTSIZE]; // General purpose buffer for input data
uint8_t writeBuf[EP_MAXPKTSIZE]; // General purpose buffer for output data
void readReport(); // read incoming data
void printReport(); // print incoming date - Uncomment for debugging
void readReport(); // read incoming data
void printReport(); // print incoming date - Uncomment for debugging
/* Private commands */
void XboxCommand(uint8_t* data, uint16_t nbytes);
/* Private commands */
void XboxCommand(uint8_t* data, uint16_t nbytes);
};
#endif

View file

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

15
adk.cpp
View file

@ -41,8 +41,7 @@ pUsb(p), //pointer to USB class instance - mandatory
bAddress(0), //device address - mandatory
bConfNum(0), //configuration number
bNumEP(1), //if config descriptor needs to be parsed
ready(false)
{
ready(false) {
// initialize endpoint data structures
for (uint8_t i = 0; i < ADK_MAX_ENDPOINTS; i++) {
epInfo[i].epAddr = 0;
@ -101,7 +100,7 @@ uint8_t ADK::Init(uint8_t parent, uint8_t port, bool lowspeed) {
p->lowspeed = lowspeed;
// 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
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);
// 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
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
if (((USB_DEVICE_DESCRIPTOR*) buf)->idVendor == ADK_VID &&
(((USB_DEVICE_DESCRIPTOR*) buf)->idProduct == ADK_PID || ((USB_DEVICE_DESCRIPTOR*) buf)->idProduct == ADB_PID)) {
if (((USB_DEVICE_DESCRIPTOR*)buf)->idVendor == ADK_VID &&
(((USB_DEVICE_DESCRIPTOR*)buf)->idProduct == ADK_PID || ((USB_DEVICE_DESCRIPTOR*)buf)->idProduct == ADB_PID)) {
USBTRACE("\r\nAcc.mode device detected");
/* 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);
@ -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
epInfo[index].epAddr = (pep->bEndpointAddress & 0x0F);
epInfo[index].maxPktSize = (uint8_t) pep->wMaxPacketSize;
epInfo[index].maxPktSize = (uint8_t)pep->wMaxPacketSize;
bNumEP++;

6
adk.h
View file

@ -133,17 +133,17 @@ public:
/* returns 2 bytes in *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 */
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 */
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_

View file

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

View file

@ -79,7 +79,7 @@ uint8_t ACM::Init(uint8_t parent, uint8_t port, bool lowspeed) {
p->lowspeed = lowspeed;
// Get device descriptor
rcode = pUsb->getDevDescr(0, 0, constBufSize, (uint8_t*) buf);
rcode = pUsb->getDevDescr(0, 0, constBufSize, (uint8_t*)buf);
// Restore p->epinfo
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;
// 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
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;
num_of_conf = ((USB_DEVICE_DESCRIPTOR*) buf)->bNumConfigurations;
num_of_conf = ((USB_DEVICE_DESCRIPTOR*)buf)->bNumConfigurations;
// Assign epInfo to epinfo pointer
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
epInfo[index].epAddr = (pep->bEndpointAddress & 0x0F);
epInfo[index].maxPktSize = (uint8_t) pep->wMaxPacketSize;
epInfo[index].maxPktSize = (uint8_t)pep->wMaxPacketSize;
epInfo[index].epAttribs = 0;
bNumEP++;
@ -304,11 +304,11 @@ uint8_t ACM::ClearCommFeature(uint16_t fid) {
}
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) {
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) {

View file

@ -78,7 +78,7 @@ uint8_t FTDI::Init(uint8_t parent, uint8_t port, bool lowspeed) {
p->lowspeed = lowspeed;
// 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
p->epinfo = oldep_ptr;
@ -86,11 +86,11 @@ uint8_t FTDI::Init(uint8_t parent, uint8_t port, bool lowspeed) {
if (rcode)
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;
// Save type of FTDI chip
wFTDIType = ((USB_DEVICE_DESCRIPTOR*) buf)->bcdDevice;
wFTDIType = ((USB_DEVICE_DESCRIPTOR*)buf)->bcdDevice;
// Allocate new address according to device class
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;
// 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
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;
num_of_conf = ((USB_DEVICE_DESCRIPTOR*) buf)->bNumConfigurations;
num_of_conf = ((USB_DEVICE_DESCRIPTOR*)buf)->bNumConfigurations;
// Assign epInfo to epinfo pointer
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
epInfo[index].epAddr = (pep->bEndpointAddress & 0x0F);
epInfo[index].maxPktSize = (uint8_t) pep->wMaxPacketSize;
epInfo[index].maxPktSize = (uint8_t)pep->wMaxPacketSize;
epInfo[index].epAttribs = 0;
bNumEP++;

View file

@ -57,7 +57,7 @@ uint8_t PL2303::Init(uint8_t parent, uint8_t port, bool lowspeed) {
p->lowspeed = lowspeed;
// 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
p->epinfo = oldep_ptr;
@ -65,11 +65,11 @@ uint8_t PL2303::Init(uint8_t parent, uint8_t port, bool lowspeed) {
if (rcode)
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;
// Save type of PL chip
wPLType = ((USB_DEVICE_DESCRIPTOR*) buf)->bcdDevice;
wPLType = ((USB_DEVICE_DESCRIPTOR*)buf)->bcdDevice;
// Allocate new address according to device class
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;
// 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
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;
num_of_conf = ((USB_DEVICE_DESCRIPTOR*) buf)->bNumConfigurations;
num_of_conf = ((USB_DEVICE_DESCRIPTOR*)buf)->bNumConfigurations;
// Assign epInfo to epinfo pointer
rcode = pUsb->setEpInfoEntry(bAddress, 1, epInfo);

View file

@ -85,8 +85,8 @@ void ConfigDescParser<CLASS_ID, SUBCLASS_ID, PROTOCOL_ID, MASK>::Parse(const uin
uint16_t cntdn = (uint16_t) len;
uint8_t *p = (uint8_t*) pbuf;
while (cntdn)
if (!ParseDescriptor(&p, &cntdn))
while(cntdn)
if(!ParseDescriptor(&p, &cntdn))
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 */
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) {
switch (stateParseDescr) {
switch(stateParseDescr) {
case 0:
theBuffer.valueSize = 2;
valParser.Initialize(&theBuffer);
stateParseDescr = 1;
case 1:
if (!valParser.Parse(pp, pcntdn))
if(!valParser.Parse(pp, pcntdn))
return false;
dscrLen = *((uint8_t*) theBuffer.pValue);
dscrType = *((uint8_t*) theBuffer.pValue + 1);
@ -114,14 +114,14 @@ bool ConfigDescParser<CLASS_ID, SUBCLASS_ID, PROTOCOL_ID, MASK>::ParseDescriptor
theBuffer.pValue = varBuffer + 2;
stateParseDescr = 3;
case 3:
switch (dscrType) {
switch(dscrType) {
case USB_DESCRIPTOR_INTERFACE:
isGoodInterface = false;
case USB_DESCRIPTOR_CONFIGURATION:
theBuffer.valueSize = sizeof (USB_CONFIGURATION_DESCRIPTOR) - 2;
theBuffer.valueSize = sizeof(USB_CONFIGURATION_DESCRIPTOR) - 2;
break;
case USB_DESCRIPTOR_ENDPOINT:
theBuffer.valueSize = sizeof (USB_ENDPOINT_DESCRIPTOR) - 2;
theBuffer.valueSize = sizeof(USB_ENDPOINT_DESCRIPTOR) - 2;
break;
case HID_DESCRIPTOR_HID:
theBuffer.valueSize = dscrLen - 2;
@ -130,20 +130,20 @@ bool ConfigDescParser<CLASS_ID, SUBCLASS_ID, PROTOCOL_ID, MASK>::ParseDescriptor
valParser.Initialize(&theBuffer);
stateParseDescr = 4;
case 4:
switch (dscrType) {
switch(dscrType) {
case USB_DESCRIPTOR_CONFIGURATION:
if (!valParser.Parse(pp, pcntdn))
if(!valParser.Parse(pp, pcntdn))
return false;
confValue = ((USB_CONFIGURATION_DESCRIPTOR*) varBuffer)->bConfigurationValue;
break;
case USB_DESCRIPTOR_INTERFACE:
if (!valParser.Parse(pp, pcntdn))
if(!valParser.Parse(pp, pcntdn))
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;
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;
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;
isGoodInterface = true;
@ -152,10 +152,10 @@ bool ConfigDescParser<CLASS_ID, SUBCLASS_ID, PROTOCOL_ID, MASK>::ParseDescriptor
protoValue = ((USB_INTERFACE_DESCRIPTOR*) varBuffer)->bInterfaceProtocol;
break;
case USB_DESCRIPTOR_ENDPOINT:
if (!valParser.Parse(pp, pcntdn))
if(!valParser.Parse(pp, pcntdn))
return false;
if (isGoodInterface)
if (theXtractor)
if(isGoodInterface)
if(theXtractor)
theXtractor->EndpointXtract(confValue, ifaceNumber, ifaceAltSet, protoValue, (USB_ENDPOINT_DESCRIPTOR*) varBuffer);
break;
//case HID_DESCRIPTOR_HID:
@ -164,7 +164,7 @@ bool ConfigDescParser<CLASS_ID, SUBCLASS_ID, PROTOCOL_ID, MASK>::ParseDescriptor
// PrintHidDescriptor((const USB_HID_DESCRIPTOR*)varBuffer);
// break;
default:
if (!theSkipper.Skip(pp, pcntdn, dscrLen - 2))
if(!theSkipper.Skip(pp, pcntdn, dscrLen - 2))
return false;
}
theBuffer.pValue = varBuffer;
@ -197,7 +197,7 @@ void ConfigDescParser<CLASS_ID, SUBCLASS_ID, PROTOCOL_ID, MASK>::PrintHidDescrip
//Notify(PSTR("\r\nwDescriptorLength:\t"));
//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);
Notify(PSTR("\r\nbDescrType:\t\t"), 0x80);

View file

@ -21,96 +21,98 @@
/*
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
*/
*/
/** Enum used to turn on the LEDs on the different controllers. */
enum LED {
LED1 = 0,
LED2 = 1,
LED3 = 2,
LED4 = 3,
LED1 = 0,
LED2 = 1,
LED3 = 2,
LED4 = 3,
LED5 = 4,
LED6 = 5,
LED7 = 6,
LED8 = 7,
LED9 = 8,
LED10 = 9,
/** Used to blink all LEDs on the Xbox controller */
ALL = 4,
LED5 = 4,
LED6 = 5,
LED7 = 6,
LED8 = 7,
LED9 = 8,
LED10 = 9,
/** Used to blink all LEDs on the Xbox controller */
ALL = 4,
};
/** This enum is used to read all the different buttons on the different controllers */
enum Button {
/**@{*/
/** These buttons are available on all the the controllers */
UP = 0,
RIGHT = 1,
DOWN = 2,
LEFT = 3,
/**@}*/
/**@{*/
/** These buttons are available on all the the controllers */
UP = 0,
RIGHT = 1,
DOWN = 2,
LEFT = 3,
/**@}*/
/**@{*/
/** Wii buttons */
PLUS = 5,
TWO = 6,
ONE = 7,
MINUS = 8,
HOME = 9,
Z = 10,
C = 11,
B = 12,
A = 13,
/**@}*/
/**@{*/
/** Wii buttons */
PLUS = 5,
TWO = 6,
ONE = 7,
MINUS = 8,
HOME = 9,
Z = 10,
C = 11,
B = 12,
A = 13,
/**@}*/
/**@{*/
/** These are only available on the Wii U Pro Controller */
L = 16,
R = 17,
ZL = 18,
ZR = 19,
/**@}*/
/**@{*/
/** These are only available on the Wii U Pro Controller */
L = 16,
R = 17,
ZL = 18,
ZR = 19,
/**@}*/
/**@{*/
/** PS3 controllers buttons */
SELECT = 4,
START = 5,
L3 = 6,
R3 = 7,
/**@{*/
/** PS3 controllers buttons */
SELECT = 4,
START = 5,
L3 = 6,
R3 = 7,
L2 = 8,
R2 = 9,
L1 = 10,
R1 = 11,
TRIANGLE = 12,
CIRCLE = 13,
CROSS = 14,
SQUARE = 15,
L2 = 8,
R2 = 9,
L1 = 10,
R1 = 11,
TRIANGLE = 12,
CIRCLE = 13,
CROSS = 14,
SQUARE = 15,
PS = 16,
PS = 16,
MOVE = 17, // Covers 12 bits - we only need to read the top 8
T = 18, // Covers 12 bits - we only need to read the top 8
/**@}*/
MOVE = 17, // Covers 12 bits - we only need to read the top 8
T = 18, // Covers 12 bits - we only need to read the top 8
/**@}*/
/**@{*/
/** Xbox buttons */
BACK = 4,
X = 14,
Y = 15,
XBOX = 16,
SYNC = 17,
/**@}*/
/**@{*/
/** Xbox buttons */
BACK = 4,
X = 14,
Y = 15,
XBOX = 16,
SYNC = 17,
/**@}*/
};
/** Joysticks on the PS3 and Xbox controllers. */
enum AnalogHat {
/** Left joystick x-axis */
LeftHatX = 0,
/** Left joystick y-axis */
LeftHatY = 1,
/** Right joystick x-axis */
RightHatX = 2,
/** Right joystick y-axis */
RightHatY = 3,
/** Left joystick x-axis */
LeftHatX = 0,
/** Left joystick y-axis */
LeftHatY = 1,
/** Right joystick x-axis */
RightHatX = 2,
/** Right joystick y-axis */
RightHatY = 3,
};
#endif

View file

@ -41,15 +41,15 @@ public:
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) {
for (LEN_TYPE j = 0; j < len; j++, byteCount++, byteTotal++) {
if (!byteCount) {
for(LEN_TYPE j = 0; j < len; j++, byteCount++, byteTotal++) {
if(!byteCount) {
SerialPrintHex<OFFSET_TYPE > (byteTotal);
Serial.print(": ");
}
SerialPrintHex<uint8_t > (pbuf[j]);
Serial.print(" ");
if (byteCount == 15) {
if(byteCount == 15) {
Serial.println("");
byteCount = 0xFF;
}

View file

@ -7,7 +7,7 @@ uint8_t HID::GetReportDescr(uint8_t ep, USBReadParser *parser) {
uint8_t buf[constBufLen];
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;

View file

@ -17,7 +17,7 @@ e-mail : support@circuitsathome.com
#include "hidboot.h"
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)
OnLeftButtonDown(pmi);
@ -112,20 +112,20 @@ uint8_t KeyboardReportParser::OemToAscii(uint8_t mod, uint8_t key) {
// Lower case letters
else
return (key - 4 + 'a');
} // Numbers
}// Numbers
else if (key > 0x1d && key < 0x27) {
if (shift)
return ((uint8_t) pgm_read_byte(&numKeys[key - 0x1e]));
return ((uint8_t)pgm_read_byte(&numKeys[key - 0x1e]));
else
return (key - 0x1e + '1');
} // Keypad Numbers
}// Keypad Numbers
else if (key > 0x58 && key < 0x62) {
if (kbdLockingKeys.kbdLeds.bmNumLock == 1)
return (key - 0x59 + '1');
} 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)
return (uint8_t) pgm_read_byte(&padKeys[key - 0x54]);
return (uint8_t)pgm_read_byte(&padKeys[key - 0x54]);
else {
switch (key) {
case KEY_SPACE: return (0x20);

View file

@ -60,7 +60,7 @@ class MouseReportParser : public HIDReportParser {
union {
MOUSEINFO mouseInfo;
uint8_t bInfo[sizeof (MOUSEINFO)];
uint8_t bInfo[sizeof(MOUSEINFO)];
} prevState;
public:
@ -140,7 +140,7 @@ protected:
union {
KBDINFO kbdInfo;
uint8_t bInfo[sizeof (KBDINFO)];
uint8_t bInfo[sizeof(KBDINFO)];
} prevState;
union {
@ -221,13 +221,13 @@ bPollEnable(false),
pRptParser(NULL) {
Initialize();
if (pUsb)
if(pUsb)
pUsb->RegisterDeviceClass(this);
}
template <const uint8_t BOOT_PROTOCOL>
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].maxPktSize = (i) ? 0 : 8;
epInfo[i].epAttribs = 0;
@ -240,7 +240,7 @@ void HIDBoot<BOOT_PROTOCOL>::Initialize() {
template <const uint8_t BOOT_PROTOCOL>
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 rcode;
@ -256,16 +256,16 @@ uint8_t HIDBoot<BOOT_PROTOCOL>::Init(uint8_t parent, uint8_t port, bool lowspeed
USBTRACE("BM Init\r\n");
if (bAddress)
if(bAddress)
return USB_ERROR_CLASS_INSTANCE_ALREADY_IN_USE;
// Get pointer to pseudo device with address 0 assigned
p = addrPool.GetUsbDevicePtr(0);
if (!p)
if(!p)
return USB_ERROR_ADDRESS_NOT_FOUND_IN_POOL;
if (!p->epinfo) {
if(!p->epinfo) {
USBTRACE("epinfo\r\n");
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
rcode = pUsb->getDevDescr(0, 0, 8, (uint8_t*) buf);
if (!rcode)
if(!rcode)
len = (buf[0] > constBufSize) ? constBufSize : buf[0];
if (rcode) {
if(rcode) {
// Restore p->epinfo
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
bAddress = addrPool.AllocAddress(parent, false, port);
if (!bAddress)
if(!bAddress)
return USB_ERROR_OUT_OF_ADDRESS_SPACE_IN_POOL;
// 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
rcode = pUsb->setAddr(0, 0, bAddress);
if (rcode) {
if(rcode) {
p->lowspeed = false;
addrPool.FreeAddress(bAddress);
bAddress = 0;
@ -320,15 +320,15 @@ uint8_t HIDBoot<BOOT_PROTOCOL>::Init(uint8_t parent, uint8_t port, bool lowspeed
p = addrPool.GetUsbDevicePtr(bAddress);
if (!p)
if(!p)
return USB_ERROR_ADDRESS_NOT_FOUND_IN_POOL;
p->lowspeed = lowspeed;
if (len)
if(len)
rcode = pUsb->getDevDescr(bAddress, 0, len, (uint8_t*) buf);
if (rcode)
if(rcode)
goto FailGetDevDescr;
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
rcode = pUsb->setEpInfoEntry(bAddress, 1, epInfo);
if (rcode)
if(rcode)
goto FailSetDevTblEntry;
//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<
USB_CLASS_HID,
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);
if (bNumEP > 1)
if(bNumEP > 1)
break;
} // for
if (bNumEP < 2)
if(bNumEP < 2)
return USB_DEV_CONFIG_ERROR_DEVICE_NOT_SUPPORTED;
//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
rcode = pUsb->setConf(bAddress, 0, bConfNum);
if (rcode)
if(rcode)
goto FailSetConfDescr;
//USBTRACE2("\r\nIf:", bIfaceNum);
rcode = SetProtocol(bIfaceNum, HID_BOOT_PROTOCOL);
if (rcode)
if(rcode)
goto FailSetProtocol;
if (BOOT_PROTOCOL == 1) {
if(BOOT_PROTOCOL == 1) {
rcode = SetIdle(bIfaceNum, 0, 0);
if (rcode)
if(rcode)
goto FailSetIdle;
}
USBTRACE("BM configured\r\n");
@ -424,7 +424,7 @@ Fail:
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) {
// If the first configuration satisfies, the others are not concidered.
if (bNumEP > 1 && conf != bConfNum)
if(bNumEP > 1 && conf != bConfNum)
return;
bConfNum = conf;
@ -432,7 +432,7 @@ void HIDBoot<BOOT_PROTOCOL>::EndpointXtract(uint8_t conf, uint8_t iface, uint8_t
uint8_t index;
if ((pep->bmAttributes & 0x03) == 3 && (pep->bEndpointAddress & 0x80) == 0x80) {
if((pep->bmAttributes & 0x03) == 3 && (pep->bEndpointAddress & 0x80) == 0x80) {
index = epInterruptInIndex;
// Fill in the endpoint info structure
@ -461,10 +461,10 @@ template <const uint8_t BOOT_PROTOCOL>
uint8_t HIDBoot<BOOT_PROTOCOL>::Poll() {
uint8_t rcode = 0;
if (!bPollEnable)
if(!bPollEnable)
return 0;
if (qNextPollTime <= millis()) {
if(qNextPollTime <= millis()) {
qNextPollTime = millis() + 10;
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);
if (rcode) {
if (rcode != hrNAK)
if(rcode) {
if(rcode != hrNAK)
USBTRACE2("Poll:", rcode);
return rcode;
}
@ -484,7 +484,7 @@ uint8_t HIDBoot<BOOT_PROTOCOL>::Poll() {
//if (read)
// Serial.println("");
if (pRptParser)
if(pRptParser)
pRptParser->Parse((HID*)this, 0, (uint8_t) read, buf);
}
return rcode;

View file

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

View file

@ -119,7 +119,7 @@ protected:
MultiValueBuffer theBuffer;
MultiByteValueParser valParser;
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 itemSize; // Item size

View file

@ -112,7 +112,7 @@ uint8_t HIDUniversal::Init(uint8_t parent, uint8_t port, bool lowspeed) {
p->lowspeed = lowspeed;
// Get device descriptor
rcode = pUsb->getDevDescr(0, 0, 8, (uint8_t*) buf);
rcode = pUsb->getDevDescr(0, 0, 8, (uint8_t*)buf);
if (!rcode)
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;
// 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
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;
if (len)
rcode = pUsb->getDevDescr(bAddress, 0, len, (uint8_t*) buf);
rcode = pUsb->getDevDescr(bAddress, 0, len, (uint8_t*)buf);
if (rcode)
goto FailGetDevDescr;
num_of_conf = ((USB_DEVICE_DESCRIPTOR*) buf)->bNumConfigurations;
num_of_conf = ((USB_DEVICE_DESCRIPTOR*)buf)->bNumConfigurations;
// Assign epInfo to epinfo pointer
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) {
// Fill in the endpoint info structure
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].bmNakPower = USB_NAK_NOWAIT;
@ -339,7 +339,7 @@ uint8_t HIDUniversal::Poll() {
for (uint8_t i = 0; i < bNumIface; i++) {
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);
@ -371,7 +371,7 @@ uint8_t HIDUniversal::Poll() {
HIDReportParser *prs = GetReportParser(((bHasReportId) ? *buf : 0));
if (prs)
prs->Parse(this, bHasReportId, (uint8_t) read, buf);
prs->Parse(this, bHasReportId, (uint8_t)read, buf);
}
}
return rcode;

View file

@ -82,7 +82,7 @@ uint8_t BulkOnly::Init(uint8_t parent, uint8_t port, bool lowspeed) {
p->lowspeed = lowspeed;
// Get device descriptor
rcode = pUsb->getDevDescr(0, 0, constBufSize, (uint8_t*) buf);
rcode = pUsb->getDevDescr(0, 0, constBufSize, (uint8_t*)buf);
// Restore p->epinfo
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;
// 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
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;
num_of_conf = ((USB_DEVICE_DESCRIPTOR*) buf)->bNumConfigurations;
num_of_conf = ((USB_DEVICE_DESCRIPTOR*)buf)->bNumConfigurations;
// Assign epInfo to epinfo pointer
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);
Notify(PSTR("\r\n\r\n"), 0x80);
// 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) {
rcode = 255;
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
epInfo[index].epAddr = (pep->bEndpointAddress & 0x0F);
epInfo[index].maxPktSize = (uint8_t) pep->wMaxPacketSize;
epInfo[index].maxPktSize = (uint8_t)pep->wMaxPacketSize;
epInfo[index].epAttribs = 0;
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.dCBWTag = ++dCBWTag;
cbw.dCBWDataTransferLength = ((uint32_t) bsize * blocks);
cbw.dCBWDataTransferLength = ((uint32_t)bsize * blocks);
cbw.bmCBWFlags = MASS_CMD_DIR_IN,
cbw.bmCBWLUN = lun;
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.dCBWTag = ++dCBWTag;
cbw.dCBWDataTransferLength = ((uint32_t) bsize * blocks);
cbw.dCBWDataTransferLength = ((uint32_t)bsize * blocks);
cbw.bmCBWFlags = MASS_CMD_DIR_IN,
cbw.bmCBWLUN = lun;
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.dCBWTag = ++dCBWTag;
cbw.dCBWDataTransferLength = ((uint32_t) bsize * blocks);
cbw.dCBWDataTransferLength = ((uint32_t)bsize * blocks);
cbw.bmCBWFlags = MASS_CMD_DIR_OUT,
cbw.bmCBWLUN = lun;
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[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) {
@ -714,7 +714,7 @@ uint8_t BulkOnly::Transaction(CommandBlockWrapper *pcbw, uint16_t buf_size, void
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) {
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 err = 0;
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) {
ErrorMessage<uint8_t > (PSTR("RDR"), err);
return MASS_ERR_GENERAL_USB_ERROR;
}
} else
ret = pUsb->inTransfer(bAddress, epInfo[epDataInIndex].epAddr, &read, (uint8_t*) buf);
ret = pUsb->inTransfer(bAddress, epInfo[epDataInIndex].epAddr, &read, (uint8_t*)buf);
} 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);
@ -798,7 +798,7 @@ uint8_t BulkOnly::HandleSCSIError(uint8_t status) {
switch (status) {
case 0: return MASS_ERR_SUCCESS;
//case 4: return MASS_ERR_UNIT_BUSY;
//case 4: return MASS_ERR_UNIT_BUSY;
case 2:
ErrorMessage<uint8_t > (PSTR("Phase"), status);
ResetRecovery();

View file

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

View file

@ -43,7 +43,7 @@ bool PTPListParser::Parse(uint8_t **pp, uint16_t *pcntdn, PTP_ARRAY_EL_FUNC pf,
return false;
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;
nStage = 2;

View file

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

View file

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

View file

@ -108,7 +108,7 @@ typedef struct {
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 bNumConfigurations; // Number of possible configurations.
}__attribute__((packed)) USB_DEVICE_DESCRIPTOR;
} __attribute__((packed)) USB_DEVICE_DESCRIPTOR;
/* Configuration descriptor structure */
typedef struct {
@ -120,7 +120,7 @@ typedef struct {
uint8_t iConfiguration; // Index of String Descriptor describing the configuration.
uint8_t bmAttributes; // Configuration characteristics.
uint8_t bMaxPower; // Maximum power consumed by this configuration.
}__attribute__((packed)) USB_CONFIGURATION_DESCRIPTOR;
} __attribute__((packed)) USB_CONFIGURATION_DESCRIPTOR;
/* Interface descriptor structure */
typedef struct {
@ -133,7 +133,7 @@ typedef struct {
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 iInterface; // Index of String Descriptor describing the interface.
}__attribute__((packed)) USB_INTERFACE_DESCRIPTOR;
} __attribute__((packed)) USB_INTERFACE_DESCRIPTOR;
/* Endpoint descriptor structure */
typedef struct {
@ -143,7 +143,7 @@ typedef struct {
uint8_t bmAttributes; // Endpoint transfer type.
uint16_t wMaxPacketSize; // Maximum packet size.
uint8_t bInterval; // Polling interval in frames.
}__attribute__((packed)) USB_ENDPOINT_DESCRIPTOR;
} __attribute__((packed)) USB_ENDPOINT_DESCRIPTOR;
/* HID descriptor */
typedef struct {
@ -154,11 +154,11 @@ typedef struct {
uint8_t bNumDescriptors; // Number of additional class specific descriptors
uint8_t bDescrType; // Type of class descriptor
uint16_t wDescriptorLength; // Total size of the Report descriptor
}__attribute__((packed)) USB_HID_DESCRIPTOR;
} __attribute__((packed)) USB_HID_DESCRIPTOR;
typedef struct {
uint8_t bDescrType; // Type of class 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_

View file

@ -96,9 +96,9 @@ template< typename SS, typename INTR >
void MAX3421e< SS, INTR >::regWr(uint8_t reg, uint8_t data) {
SS::Clear();
SPDR = (reg | 0x02);
while (!(SPSR & (1 << SPIF)));
while(!(SPSR & (1 << SPIF)));
SPDR = data;
while (!(SPSR & (1 << SPIF)));
while(!(SPSR & (1 << SPIF)));
SS::Set();
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) {
SS::Clear();
SPDR = (reg | 0x02); //set WR bit and send register number
while (nbytes--) {
while (!(SPSR & (1 << SPIF))); //check if previous byte was sent
while(nbytes--) {
while(!(SPSR & (1 << SPIF))); //check if previous byte was sent
SPDR = (*data_p); // send next data byte
data_p++; // advance data pointer
}
while (!(SPSR & (1 << SPIF)));
while(!(SPSR & (1 << SPIF)));
SS::Set();
return ( data_p);
return( data_p);
}
/* GPIO write */
/*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) {
SS::Clear();
SPDR = reg;
while (!(SPSR & (1 << SPIF)));
while(!(SPSR & (1 << SPIF)));
SPDR = 0; //send empty byte
while (!(SPSR & (1 << SPIF)));
while(!(SPSR & (1 << SPIF)));
SS::Set();
return ( SPDR);
return( SPDR);
}
/* 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) {
SS::Clear();
SPDR = reg;
while (!(SPSR & (1 << SPIF))); //wait
while (nbytes) {
while(!(SPSR & (1 << SPIF))); //wait
while(nbytes) {
SPDR = 0; //send empty byte
nbytes--;
while (!(SPSR & (1 << SPIF)));
while(!(SPSR & (1 << SPIF)));
*data_p = SPDR;
data_p++;
}
SS::Set();
return ( data_p);
return( data_p);
}
/* GPIO read. See gpioWr for explanation */
@ -168,7 +168,7 @@ uint8_t MAX3421e< SS, INTR >::gpioRd() {
gpin = regRd(rIOPINS2); //pins 4-7
gpin &= 0xf0; //clean lower nibble
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
@ -178,12 +178,12 @@ uint16_t MAX3421e< SS, INTR >::reset() {
uint16_t i = 0;
regWr(rUSBCTL, bmCHIPRES);
regWr(rUSBCTL, 0x00);
while (++i) {
if ((regRd(rUSBIRQ) & bmOSCOKIRQ)) {
while(++i) {
if((regRd(rUSBIRQ) & bmOSCOKIRQ)) {
break;
}
}
return ( i);
return( i);
}
///* initialize MAX3421E. Set Host mode, pullups, and stuff. Returns 0 if success, -1 if not */
//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 */
template< typename SS, typename INTR >
int8_t MAX3421e< SS, INTR >::Init() {
if (reset() == 0) { //OSCOKIRQ hasn't asserted in time
return ( -1);
if(reset() == 0) { //OSCOKIRQ hasn't asserted in time
return( -1);
}
regWr(rMODE, bmDPPULLDN | bmDMPULLDN | bmHOST); // set pull-downs, Host
@ -209,13 +209,13 @@ int8_t MAX3421e< SS, INTR >::Init() {
/* check if device is connected */
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
regWr(rHIRQ, bmCONDETIRQ); //clear connection detect interrupt
regWr(rCPUCTL, 0x01); //enable interrupt pin
return ( 0);
return( 0);
}
/* 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;
bus_sample = regRd(rHRSL); //Get J,K status
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):
if ((regRd(rMODE) & bmLOWSPEED) == 0) {
if((regRd(rMODE) & bmLOWSPEED) == 0) {
regWr(rMODE, MODE_FS_HOST); //start full-speed host
vbusState = FSHOST;
} else {
@ -235,7 +235,7 @@ void MAX3421e< SS, INTR >::busprobe() {
}
break;
case( bmKSTATUS):
if ((regRd(rMODE) & bmLOWSPEED) == 0) {
if((regRd(rMODE) & bmLOWSPEED) == 0) {
regWr(rMODE, MODE_LS_HOST); //start low-speed host
vbusState = LSHOST;
} else {
@ -262,7 +262,7 @@ uint8_t MAX3421e< SS, INTR >::Task(void) {
//Serial.println( vbusState, HEX );
pinvalue = INTR::IsSet(); //Read();
//pinvalue = digitalRead( MAX_INT );
if (pinvalue == 0) {
if(pinvalue == 0) {
rcode = IntHandler();
}
// pinvalue = digitalRead( MAX_GPX );
@ -270,7 +270,7 @@ uint8_t MAX3421e< SS, INTR >::Task(void) {
// GpxHandler();
// }
// usbSM(); //USB state machine
return ( rcode);
return( rcode);
}
template< typename SS, typename INTR >
@ -281,13 +281,13 @@ uint8_t MAX3421e< SS, INTR >::IntHandler() {
//if( HIRQ & bmFRAMEIRQ ) { //->1ms SOF interrupt handler
// HIRQ_sendback |= bmFRAMEIRQ;
//}//end FRAMEIRQ handling
if (HIRQ & bmCONDETIRQ) {
if(HIRQ & bmCONDETIRQ) {
busprobe();
HIRQ_sendback |= bmCONDETIRQ;
}
/* End HIRQ interrupts handling, clear serviced IRQs */
regWr(rHIRQ, HIRQ_sendback);
return ( HIRQ_sendback);
return( HIRQ_sendback);
}
//template< typename SS, typename INTR >
//uint8_t MAX3421e< SS, INTR >::GpxHandler()

View file

@ -74,7 +74,7 @@ uint8_t USBHub::Init(uint8_t parent, uint8_t port, bool lowspeed) {
p->lowspeed = lowspeed;
// Get device descriptor
rcode = pUsb->getDevDescr(0, 0, 8, (uint8_t*) buf);
rcode = pUsb->getDevDescr(0, 0, 8, (uint8_t*)buf);
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
// 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;
// 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)
return USB_ERROR_OUT_OF_ADDRESS_SPACE_IN_POOL;
// 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
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;
if (len)
rcode = pUsb->getDevDescr(bAddress, 0, len, (uint8_t*) buf);
rcode = pUsb->getDevDescr(bAddress, 0, len, (uint8_t*)buf);
if (rcode)
goto FailGetDevDescr;
@ -139,7 +139,7 @@ uint8_t USBHub::Init(uint8_t parent, uint8_t port, bool lowspeed) {
goto FailGetHubDescr;
// Save number of ports for future use
bNbrPorts = ((HubDescriptor*) buf)->bNbrPorts;
bNbrPorts = ((HubDescriptor*)buf)->bNbrPorts;
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);
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);
}
if (rcode)

View file

@ -155,11 +155,11 @@ struct HubDescriptor {
uint16_t TTThinkTime : 2;
uint16_t PortIndicatorsSupported : 1;
uint16_t Reserved : 8;
}__attribute__((packed));
} __attribute__((packed));
uint8_t bPwrOn2PwrGood;
uint8_t bHubContrCurrent;
}__attribute__((packed));
} __attribute__((packed));
struct HubEvent {
@ -168,11 +168,11 @@ struct HubEvent {
struct {
uint16_t bmStatus; // port status bits
uint16_t bmChange; // port status change bits
}__attribute__((packed));
} __attribute__((packed));
uint32_t bmEvent;
uint8_t evtBuff[4];
};
}__attribute__((packed));
} __attribute__((packed));
class USBHub : USBDeviceConfig {
static bool bResetInitiated; // True when reset is triggered
@ -216,42 +216,42 @@ public:
// Clear Hub Feature
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
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
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
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
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
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
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
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);

View file

@ -22,43 +22,43 @@
/** Enum used to set special LED modes supported by the Xbox controller. */
enum LEDMode {
ROTATING = 0x0A,
FASTBLINK = 0x0B,
SLOWBLINK = 0x0C,
ALTERNATING = 0x0D,
ROTATING = 0x0A,
FASTBLINK = 0x0B,
SLOWBLINK = 0x0C,
ALTERNATING = 0x0D,
};
/** Used to set the LEDs on the controllers */
const uint8_t XBOXLEDS[] PROGMEM = {
0x02, // LED1
0x03, // LED2
0x04, // LED3
0x05, // LED4
0x01 // ALL - Used to blink all LEDs
};
0x02, // LED1
0x03, // LED2
0x04, // LED3
0x05, // LED4
0x01 // ALL - Used to blink all LEDs
};
/** Buttons on the controllers */
const uint16_t XBOXBUTTONS[] PROGMEM = {
0x0100, // UP
0x0800, // RIGHT
0x0200, // DOWN
0x0400, // LEFT
0x0100, // UP
0x0800, // RIGHT
0x0200, // DOWN
0x0400, // LEFT
0x2000, // BACK
0x1000, // START
0x4000, // L3
0x8000, // R3
0x2000, // BACK
0x1000, // START
0x4000, // L3
0x8000, // R3
0,0, // Skip L2 and R2 as these are analog buttons
0x0001, // L1
0x0002, // R1
0, 0, // Skip L2 and R2 as these are analog buttons
0x0001, // L1
0x0002, // R1
0x0020, // B
0x0010, // A
0x0040, // X
0x0080, // Y
0x0020, // B
0x0010, // A
0x0040, // X
0x0080, // Y
0x0004, // XBOX
0x0008 // SYNC
0x0004, // XBOX
0x0008 // SYNC
};
#endif