Browse Source

Merge pull request #28 from KurtE/WIP2-Bluetooth

Wip2 bluetooth
main
Paul Stoffregen 5 years ago
parent
commit
b495655501
No account linked to committer's email address
46 changed files with 17736 additions and 258 deletions
  1. +290
    -35
      USBHost_t36.h
  2. +1519
    -0
      bluetooth.cpp
  3. +134
    -0
      digitizer.cpp
  4. +4
    -4
      ehci.cpp
  5. +586
    -0
      examples/Bluetooth/JoystickBT/JoystickBT.ino
  6. +1
    -0
      examples/Bluetooth/JoystickBT/defs.h
  7. +146
    -0
      examples/Bluetooth/JoystickBT/helperPS.ino
  8. +568
    -0
      examples/Bluetooth/KeyboardBT/KeyboardBT.ino
  9. +1
    -0
      examples/Bluetooth/KeyboardBT/defs.h
  10. +577
    -0
      examples/Bluetooth/MouseBT/MouseBT.ino
  11. +1
    -0
      examples/Bluetooth/MouseBT/defs.h
  12. +1776
    -0
      examples/Bluetooth/Pacman-Teensy-BT/Pacman-Teensy-BT.ino
  13. +997
    -0
      examples/Bluetooth/Pacman-Teensy-BT/PacmanTiles.h
  14. +77
    -0
      examples/Bluetooth/Pacman-Teensy-BT/README.md
  15. +2933
    -0
      examples/Bluetooth/Pacman-Teensy-BT/crntsc.h
  16. +2403
    -0
      examples/Bluetooth/Pacman-Teensy-BT/crpal.h
  17. +3082
    -0
      examples/Bluetooth/Pacman-Teensy-BT/font8x8.cpp
  18. BIN
      examples/Bluetooth/Pacman-Teensy-BT/icons/apple.png
  19. BIN
      examples/Bluetooth/Pacman-Teensy-BT/icons/bell.png
  20. BIN
      examples/Bluetooth/Pacman-Teensy-BT/icons/cherry.png
  21. BIN
      examples/Bluetooth/Pacman-Teensy-BT/icons/galaxian.png
  22. BIN
      examples/Bluetooth/Pacman-Teensy-BT/icons/grape.png
  23. BIN
      examples/Bluetooth/Pacman-Teensy-BT/icons/key.png
  24. BIN
      examples/Bluetooth/Pacman-Teensy-BT/icons/peach.png
  25. BIN
      examples/Bluetooth/Pacman-Teensy-BT/icons/strawberry.png
  26. +604
    -0
      examples/Digitizer/Digitizer.ino
  27. +1
    -0
      examples/Digitizer/defs.h
  28. +2
    -2
      examples/Serial/Joystick/Joystick.ino
  29. +209
    -0
      examples/Serial/Joystick/Joystick/Joystick.ino
  30. +65
    -0
      examples/Serial/Joystick/Joystick/ps4Helpers.ino
  31. +0
    -0
      examples/Serial/MIDI/InputFunctions/InputFunctions.ino
  32. +0
    -0
      examples/Serial/MIDI/Interface_16x16/Interface_16x16.ino
  33. +6
    -4
      examples/Serial/Mouse/Mouse.ino
  34. +0
    -0
      examples/Serial/Mouse/defs.h
  35. +0
    -0
      examples/Test/SerialTest/SerialTest.ino
  36. +0
    -0
      examples/Test/SerialTest/defs.h
  37. +0
    -0
      examples/Test/Test/Test.ino
  38. +970
    -0
      examples/USBHost_viewer/USBHost_viewer.ino
  39. +1
    -0
      examples/USBHost_viewer/defs.h
  40. +7
    -5
      hid.cpp
  41. +475
    -46
      joystick.cpp
  42. +84
    -7
      keyboard.cpp
  43. +2
    -0
      keywords.txt
  44. +62
    -2
      mouse.cpp
  45. +145
    -145
      print.cpp
  46. +8
    -8
      rawhid.cpp

+ 290
- 35
USBHost_t36.h View File

@@ -27,7 +27,7 @@
#include <stdint.h>

#if !defined(__MK66FX1M0__) && !defined(__IMXRT1052__) && !defined(__IMXRT1062__)
#error "USBHost_t36 only works with Teensy 3.6. Please select it in Tools > Boards"
#error "USBHost_t36 only works with Teensy 3.6 or Teensy 4.x. Please select it in Tools > Boards"
#endif
#include "utility/imxrt_usbhs.h"

@@ -58,6 +58,13 @@


//#define USBHOST_PRINT_DEBUG
//#define USBHDBGSerial Serial1


#ifndef USBHDBGSerial
#define USBHDBGSerial Serial
#endif


/************************************************/
/* Data Types */
@@ -314,35 +321,35 @@ protected:
static void print_config_descriptor(const uint8_t *p, uint32_t maxlen);
static void print_string_descriptor(const char *name, const uint8_t *p);
static void print_hexbytes(const void *ptr, uint32_t len);
static void print_(const char *s) { Serial.print(s); }
static void print_(int n) { Serial.print(n); }
static void print_(unsigned int n) { Serial.print(n); }
static void print_(long n) { Serial.print(n); }
static void print_(unsigned long n) { Serial.print(n); }
static void println_(const char *s) { Serial.println(s); }
static void println_(int n) { Serial.println(n); }
static void println_(unsigned int n) { Serial.println(n); }
static void println_(long n) { Serial.println(n); }
static void println_(unsigned long n) { Serial.println(n); }
static void println_() { Serial.println(); }
static void print_(uint32_t n, uint8_t b) { Serial.print(n, b); }
static void println_(uint32_t n, uint8_t b) { Serial.println(n, b); }
static void print_(const char *s) { USBHDBGSerial.print(s); }
static void print_(int n) { USBHDBGSerial.print(n); }
static void print_(unsigned int n) { USBHDBGSerial.print(n); }
static void print_(long n) { USBHDBGSerial.print(n); }
static void print_(unsigned long n) { USBHDBGSerial.print(n); }
static void println_(const char *s) { USBHDBGSerial.println(s); }
static void println_(int n) { USBHDBGSerial.println(n); }
static void println_(unsigned int n) { USBHDBGSerial.println(n); }
static void println_(long n) { USBHDBGSerial.println(n); }
static void println_(unsigned long n) { USBHDBGSerial.println(n); }
static void println_() { USBHDBGSerial.println(); }
static void print_(uint32_t n, uint8_t b) { USBHDBGSerial.print(n, b); }
static void println_(uint32_t n, uint8_t b) { USBHDBGSerial.println(n, b); }
static void print_(const char *s, int n, uint8_t b = DEC) {
Serial.print(s); Serial.print(n, b); }
USBHDBGSerial.print(s); USBHDBGSerial.print(n, b); }
static void print_(const char *s, unsigned int n, uint8_t b = DEC) {
Serial.print(s); Serial.print(n, b); }
USBHDBGSerial.print(s); USBHDBGSerial.print(n, b); }
static void print_(const char *s, long n, uint8_t b = DEC) {
Serial.print(s); Serial.print(n, b); }
USBHDBGSerial.print(s); USBHDBGSerial.print(n, b); }
static void print_(const char *s, unsigned long n, uint8_t b = DEC) {
Serial.print(s); Serial.print(n, b); }
USBHDBGSerial.print(s); USBHDBGSerial.print(n, b); }
static void println_(const char *s, int n, uint8_t b = DEC) {
Serial.print(s); Serial.println(n, b); }
USBHDBGSerial.print(s); USBHDBGSerial.println(n, b); }
static void println_(const char *s, unsigned int n, uint8_t b = DEC) {
Serial.print(s); Serial.println(n, b); }
USBHDBGSerial.print(s); USBHDBGSerial.println(n, b); }
static void println_(const char *s, long n, uint8_t b = DEC) {
Serial.print(s); Serial.println(n, b); }
USBHDBGSerial.print(s); USBHDBGSerial.println(n, b); }
static void println_(const char *s, unsigned long n, uint8_t b = DEC) {
Serial.print(s); Serial.println(n, b); }
USBHDBGSerial.print(s); USBHDBGSerial.println(n, b); }
friend class USBDriverTimer; // for access to print & println
#else
static void print_(const Transfer_t *transfer) {}
@@ -517,12 +524,47 @@ private:
virtual void hid_input_end();
virtual void disconnect_collection(Device_t *dev);
void add_to_list();
USBHIDInput *next;
USBHIDInput *next = NULL;
friend class USBHIDParser;
protected:
Device_t *mydevice = NULL;
};


// Device drivers may inherit from this base class, if they wish to receive
// HID input like data from Bluetooth HID device.
class BluetoothController;

class BTHIDInput {
public:
operator bool() { return (btdevice != nullptr); }
uint16_t idVendor() { return (btdevice != nullptr) ? btdevice->idVendor : 0; }
uint16_t idProduct() { return (btdevice != nullptr) ? btdevice->idProduct : 0; }
const uint8_t *manufacturer()
{ return ((btdevice == nullptr) || (btdevice->strbuf == nullptr)) ? nullptr : &btdevice->strbuf->buffer[btdevice->strbuf->iStrings[strbuf_t::STR_ID_MAN]]; }
const uint8_t *product()
{ return remote_name_; }
const uint8_t *serialNumber()
{ return ((btdevice == nullptr) || (btdevice->strbuf == nullptr)) ? nullptr : &btdevice->strbuf->buffer[btdevice->strbuf->iStrings[strbuf_t::STR_ID_SERIAL]]; }
private:
virtual bool claim_bluetooth(BluetoothController *driver, uint32_t bluetooth_class, uint8_t *remoteName) {return false;}
virtual bool process_bluetooth_HID_data(const uint8_t *data, uint16_t length) {return false;}
virtual void release_bluetooth() {};
virtual bool remoteNameComplete(const uint8_t *remoteName) {return true;}
virtual void connectionComplete(void) {};
void add_to_list();
BTHIDInput *next = NULL;
friend class BluetoothController;
protected:
enum {SP_NEED_CONNECT=0x1, SP_DONT_NEED_CONNECT=0x02, SP_PS3_IDS=0x4};
enum {REMOTE_NAME_SIZE=32};
uint8_t special_process_required = 0;
Device_t *btdevice = NULL;
uint8_t remote_name_[REMOTE_NAME_SIZE] = {0};

};


/************************************************/
/* USB Device Drivers */
/************************************************/
@@ -652,7 +694,7 @@ private:
uint16_t in_size;
uint16_t out_size;
setup_t setup;
uint8_t descriptor[512];
uint8_t descriptor[800];
uint8_t report[64];
uint16_t descsize;
bool use_report_id;
@@ -667,7 +709,7 @@ private:

//--------------------------------------------------------------------------

class KeyboardController : public USBDriver , public USBHIDInput {
class KeyboardController : public USBDriver , public USBHIDInput, public BTHIDInput {
public:
typedef union {
struct {
@@ -691,8 +733,7 @@ public:
const uint8_t *product();
const uint8_t *serialNumber();

// Some methods are in both public classes so we need to figure out which one to use
operator bool() { return (device != nullptr); }
operator bool() { return ((device != nullptr) || (btdevice != nullptr)); }
// Main boot keyboard functions.
uint16_t getKey() { return keyCode; }
uint8_t getModifiers() { return modifiers; }
@@ -724,6 +765,13 @@ protected:
void new_data(const Transfer_t *transfer);
void init();

// Bluetooth data
virtual bool claim_bluetooth(BluetoothController *driver, uint32_t bluetooth_class, uint8_t *remoteName);
virtual bool process_bluetooth_HID_data(const uint8_t *data, uint16_t length);
virtual bool remoteNameComplete(const uint8_t *remoteName);
virtual void release_bluetooth();


protected: // HID functions for extra keyboard data.
virtual hidclaim_t claim_collection(USBHIDParser *driver, Device_t *dev, uint32_t topusage);
virtual void hid_input_begin(uint32_t topusage, uint32_t type, int lgmin, int lgmax);
@@ -764,9 +812,9 @@ private:
};


class MouseController : public USBHIDInput {
class MouseController : public USBHIDInput, public BTHIDInput {
public:
MouseController(USBHost &host) { USBHIDParser::driver_ready_for_hid_collection(this); }
MouseController(USBHost &host) { init(); }
bool available() { return mouseEvent; }
void mouseDataClear();
uint8_t getButtons() { return buttons; }
@@ -780,7 +828,17 @@ protected:
virtual void hid_input_data(uint32_t usage, int32_t value);
virtual void hid_input_end();
virtual void disconnect_collection(Device_t *dev);

// Bluetooth data
virtual bool claim_bluetooth(BluetoothController *driver, uint32_t bluetooth_class, uint8_t *remoteName);
virtual bool process_bluetooth_HID_data(const uint8_t *data, uint16_t length);
virtual void release_bluetooth();


private:
void init();
BluetoothController *btdriver_ = nullptr;

uint8_t collections_claimed = 0;
volatile bool mouseEvent = false;
volatile bool hid_input_begin_ = false;
@@ -793,7 +851,44 @@ private:

//--------------------------------------------------------------------------

class JoystickController : public USBDriver, public USBHIDInput {
class DigitizerController : public USBHIDInput, public BTHIDInput {
public:
DigitizerController(USBHost &host) { init(); }
bool available() { return digitizerEvent; }
void digitizerDataClear();
uint8_t getButtons() { return buttons; }
int getMouseX() { return mouseX; }
int getMouseY() { return mouseY; }
int getWheel() { return wheel; }
int getWheelH() { return wheelH; }
int getAxis(uint32_t index) { return (index < (sizeof(digiAxes)/sizeof(digiAxes[0]))) ? digiAxes[index] : 0; }

protected:
virtual hidclaim_t claim_collection(USBHIDParser *driver, Device_t *dev, uint32_t topusage);
virtual void hid_input_begin(uint32_t topusage, uint32_t type, int lgmin, int lgmax);
virtual void hid_input_data(uint32_t usage, int32_t value);
virtual void hid_input_end();
virtual void disconnect_collection(Device_t *dev);


private:
void init();

uint8_t collections_claimed = 0;
volatile bool digitizerEvent = false;
volatile bool hid_input_begin_ = false;
uint8_t buttons = 0;
int mouseX = 0;
int mouseY = 0;
int wheel = 0;
int wheelH = 0;
int digiAxes[16];
};


//--------------------------------------------------------------------------

class JoystickController : public USBDriver, public USBHIDInput, public BTHIDInput {
public:
JoystickController(USBHost &host) { init(); }

@@ -803,7 +898,7 @@ public:
const uint8_t *manufacturer();
const uint8_t *product();
const uint8_t *serialNumber();
operator bool() { return (((device != nullptr) || (mydevice != nullptr)) && connected_); } // override as in both USBDriver and in USBHIDInput
operator bool() { return (((device != nullptr) || (mydevice != nullptr || (btdevice != nullptr))) && connected_); } // override as in both USBDriver and in USBHIDInput

bool available() { return joystickEvent; }
void joystickDataClear();
@@ -816,11 +911,18 @@ public:

// set functions functionality depends on underlying joystick.
bool setRumble(uint8_t lValue, uint8_t rValue, uint8_t timeout=0xff);
// setLEDs on PS4(RGB), PS3 simple LED setting (only uses lr)
bool setLEDs(uint8_t lr, uint8_t lg=0, uint8_t lb=0); // sets Leds,
// setLEDs on PS4(RGB), PS3 simple LED setting (only uses lb)
bool setLEDs(uint8_t lr, uint8_t lg, uint8_t lb); // sets Leds,
bool inline setLEDs(uint32_t leds) {return setLEDs((leds >> 16) & 0xff, (leds >> 8) & 0xff, leds & 0xff);} // sets Leds - passing one arg for all leds
enum { STANDARD_AXIS_COUNT = 10, ADDITIONAL_AXIS_COUNT = 54, TOTAL_AXIS_COUNT = (STANDARD_AXIS_COUNT+ADDITIONAL_AXIS_COUNT) };
typedef enum { UNKNOWN=0, PS3, PS4, XBOXONE, XBOX360} joytype_t;
joytype_t joystickType = UNKNOWN;
typedef enum { UNKNOWN=0, PS3, PS4, XBOXONE, XBOX360, PS3_MOTION, SpaceNav} joytype_t;
joytype_t joystickType() {return joystickType_;}

// PS3 pair function. hack, requires that it be connect4ed by USB and we have the address of the Bluetooth dongle...
bool PS3Pair(uint8_t* bdaddr);

protected:
// From USBDriver
virtual bool claim(Device_t *device, int type, const uint8_t *descriptors, uint32_t len);
@@ -834,14 +936,27 @@ protected:
virtual void hid_input_end();
virtual void disconnect_collection(Device_t *dev);
virtual bool hid_process_out_data(const Transfer_t *transfer);

// Bluetooth data
virtual bool claim_bluetooth(BluetoothController *driver, uint32_t bluetooth_class, uint8_t *remoteName);
virtual bool process_bluetooth_HID_data(const uint8_t *data, uint16_t length);
virtual void release_bluetooth();
virtual bool remoteNameComplete(const uint8_t *remoteName);
virtual void connectionComplete(void);

joytype_t joystickType_ = UNKNOWN;
private:

// Class specific
void init();
USBHIDParser *driver_ = nullptr;
BluetoothController *btdriver_ = nullptr;

joytype_t mapVIDPIDtoJoystickType(uint16_t idVendor, uint16_t idProduct, bool exclude_hid_devices);
bool transmitPS4UserFeedbackMsg();
bool transmitPS3UserFeedbackMsg();
bool transmitPS3MotionUserFeedbackMsg();
bool mapNameToJoystickType(const uint8_t *remoteName);

bool anychange = false;
volatile bool joystickEvent = false;
@@ -1596,4 +1711,144 @@ private:

};

//--------------------------------------------------------------------------

class BluetoothController: public USBDriver {
public:
BluetoothController(USBHost &host, bool pair = false, const char *pin = "0000") : do_pair_device_(pair), pair_pincode_(pin), delayTimer_(this)
{ init(); }

enum {MAX_ENDPOINTS=4, NUM_SERVICES=4, }; // Max number of Bluetooth services - if you need more than 4 simply increase this number
enum {BT_CLASS_DEVICE= 0x0804}; // Toy - Robot
static void driver_ready_for_bluetooth(BTHIDInput *driver);

const uint8_t* myBDAddr(void) {return my_bdaddr_;}

// BUGBUG version to allow some of the controlled objects to call?
enum {CONTROL_SCID=-1, INTERRUPT_SCID=-2};
void sendL2CapCommand(uint8_t* data, uint8_t nbytes, int channel = (int)0x0001);

protected:
virtual bool claim(Device_t *device, int type, const uint8_t *descriptors, uint32_t len);
virtual void control(const Transfer_t *transfer);
virtual void disconnect();
virtual void timer_event(USBDriverTimer *whichTimer);

BTHIDInput * find_driver(uint32_t device_type, uint8_t *remoteName=nullptr);

// Hack to allow PS3 to maybe change values
uint16_t connection_rxid_ = 0;
uint16_t control_dcid_ = 0x70;
uint16_t interrupt_dcid_ = 0x71;
uint16_t interrupt_scid_;
uint16_t control_scid_;


private:
friend class BTHIDInput;
static void rx_callback(const Transfer_t *transfer);
static void rx2_callback(const Transfer_t *transfer);
static void tx_callback(const Transfer_t *transfer);
void rx_data(const Transfer_t *transfer);
void rx2_data(const Transfer_t *transfer);
void tx_data(const Transfer_t *transfer);

void init();

// HCI support functions...
void sendHCICommand(uint16_t hciCommand, uint16_t cParams, const uint8_t* data);
//void sendHCIReadLocalSupportedFeatures();
void inline sendHCI_INQUIRY();
void inline sendHCIInquiryCancel();
void inline sendHCICreateConnection();
void inline sendHCIAuthenticationRequested();
void inline sendHCIAcceptConnectionRequest();
void inline sendHCILinkKeyNegativeReply();
void inline sendHCIPinCodeReply();
void inline sendResetHCI();
void inline sendHDCWriteClassOfDev();
void inline sendHCIReadBDAddr();
void inline sendHCIReadLocalVersionInfo();
void inline sendHCIWriteScanEnable(uint8_t scan_op);
void inline sendHCIHCIWriteInquiryMode(uint8_t inquiry_mode);
void inline sendHCISetEventMask();

void inline sendHCIRemoteNameRequest();
void inline sendHCIRemoteVersionInfoRequest();
void handle_hci_command_complete();
void handle_hci_command_status();
void handle_hci_inquiry_result(bool fRSSI=false);
void handle_hci_extended_inquiry_result();
void handle_hci_inquiry_complete();
void handle_hci_incoming_connect();
void handle_hci_connection_complete();
void handle_hci_disconnect_complete();
void handle_hci_authentication_complete();
void handle_hci_remote_name_complete();
void handle_hci_remote_version_information_complete();
void handle_hci_pin_code_request();
void handle_hci_link_key_notification();
void handle_hci_link_key_request();
void queue_next_hci_command();

void sendl2cap_ConnectionResponse(uint16_t handle, uint8_t rxid, uint16_t dcid, uint16_t scid, uint8_t result);
void sendl2cap_ConnectionRequest(uint16_t handle, uint8_t rxid, uint16_t scid, uint16_t psm);
void sendl2cap_ConfigRequest(uint16_t handle, uint8_t rxid, uint16_t dcid);
void sendl2cap_ConfigResponse(uint16_t handle, uint8_t rxid, uint16_t scid);
void sendL2CapCommand(uint16_t handle, uint8_t* data, uint8_t nbytes, uint8_t channelLow = 0x01, uint8_t channelHigh = 0x00);

void process_l2cap_connection_request(uint8_t *data);
void process_l2cap_connection_response(uint8_t *data);
void process_l2cap_config_request(uint8_t *data);
void process_l2cap_config_response(uint8_t *data);
void process_l2cap_command_reject(uint8_t *data);
void process_l2cap_disconnect_request(uint8_t *data);

void setHIDProtocol(uint8_t protocol);
void handleHIDTHDRData(uint8_t *buffer); // Pass the whole buffer...
static BTHIDInput *available_bthid_drivers_list;


setup_t setup;
Pipe_t mypipes[4] __attribute__ ((aligned(32)));
Transfer_t mytransfers[7] __attribute__ ((aligned(32)));
strbuf_t mystring_bufs[2]; // 2 string buffers - one for our device - one for remote device...
uint16_t pending_control_ = 0;
uint16_t pending_control_tx_ = 0;
uint16_t rx_size_ = 0;
uint16_t rx2_size_ = 0;
uint16_t tx_size_ = 0;
Pipe_t *rxpipe_;
Pipe_t *rx2pipe_;
Pipe_t *txpipe_;
uint8_t rxbuf_[256]; // used to receive data from RX, which may come with several packets...
uint8_t rx_packet_data_remaining=0; // how much data remaining
uint8_t rx2buf_[64]; // receive buffer from Bulk end point
uint8_t txbuf_[256]; // buffer to use to send commands to bluetooth
uint8_t hciVersion; // what version of HCI do we have?

bool do_pair_device_; // Should we do a pair for a new device?
const char *pair_pincode_; // What pin code to use for the pairing
USBDriverTimer delayTimer_;
uint8_t my_bdaddr_[6]; // The bluetooth dongles Bluetooth address.
uint8_t features[8]; // remember our local features.
BTHIDInput * device_driver_ = nullptr;;
uint8_t device_bdaddr_[6];// remember devices address
uint8_t device_ps_repetion_mode_ ; // mode
uint8_t device_clock_offset_[2];
uint32_t device_class_; // class of device.
uint16_t device_connection_handle_; // handle to connection
uint8_t remote_ver_;
uint16_t remote_man_;
uint8_t remote_subv_;
uint8_t connection_complete_ = false; //

typedef struct {
uint16_t idVendor;
uint16_t idProduct;
} product_vendor_mapping_t;
static product_vendor_mapping_t pid_vid_mapping[];

};

#endif

+ 1519
- 0
bluetooth.cpp
File diff suppressed because it is too large
View File


+ 134
- 0
digitizer.cpp View File

@@ -0,0 +1,134 @@
/* USB EHCI Host for Teensy 3.6
* Copyright 2017 Paul Stoffregen (paul@pjrc.com)
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/

#include <Arduino.h>
#include "USBHost_t36.h" // Read this header first for key info


void DigitizerController::init()
{
USBHIDParser::driver_ready_for_hid_collection(this);
}


hidclaim_t DigitizerController::claim_collection(USBHIDParser *driver, Device_t *dev, uint32_t topusage)
{
// only claim Desktop/Mouse
if (topusage != 0xff0d0001) return CLAIM_NO;
// only claim from one physical device
if (mydevice != NULL && dev != mydevice) return CLAIM_NO;
mydevice = dev;
collections_claimed++;
return CLAIM_REPORT;
}

void DigitizerController::disconnect_collection(Device_t *dev)
{
if (--collections_claimed == 0) {
mydevice = NULL;
}
}

void DigitizerController::hid_input_begin(uint32_t topusage, uint32_t type, int lgmin, int lgmax)
{
// TODO: check if absolute coordinates
hid_input_begin_ = true;
}

void DigitizerController::hid_input_data(uint32_t usage, int32_t value)
{
USBHDBGSerial.printf("Digitizer: usage=%X, value=%d\n", usage, value);
uint32_t usage_page = usage >> 16;
usage &= 0xFFFF;
USBHDBGSerial.printf("Digitizer: &usage=%X, usage_page=%x\n", usage, usage_page);
// This is Mikes version...
if (usage_page == 0xff00 && usage >= 100 && usage <= 0x108) {
switch (usage) {
case 0x102:
mouseX = value;
break;
case 0x103:
mouseY = value;
break;
case 0x32: // Apple uses this for horizontal scroll
wheelH = value;
break;
case 0x38:
wheel = value;
break;
}
digiAxes[usage & 0xf] = value;
}
if (usage_page == 0xff0D) {
if (usage >= 0 && usage < 0x138) { //at least to start
switch (usage) {
case 0x130:
mouseX = value;
break;
case 0x131:
mouseY = value;
break;
case 0x132: // Apple uses this for horizontal scroll
wheelH = value;
break;
case 0x138:
wheel = value;
break;
case 0x30: digiAxes[0] = value; break;
case 0x32: digiAxes[1] = value; break;
case 0x36: digiAxes[2] = value; break;
case 0x42: digiAxes[3] = value; break;
case 0x44: digiAxes[4] = value; break;
case 0x5A: digiAxes[5] = value; break;
case 0x5B: digiAxes[6] = value; break;
case 0x5C: digiAxes[7] = value; break;
case 0x77: digiAxes[8] = value; break;
}
//digiAxes[usage & 0xf] = value;
} else if (usage >= 0x910 && usage <= 0x91f) {
if (value == 0) {
buttons &= ~(1 << (usage - 0x910));
} else {
buttons |= (1 << (usage - 0x910));
}
}
}
}

void DigitizerController::hid_input_end()
{
if (hid_input_begin_) {
digitizerEvent = true;
hid_input_begin_ = false;
}
}

void DigitizerController::digitizerDataClear() {
digitizerEvent = false;
buttons = 0;
mouseX = 0;
mouseY = 0;
wheel = 0;
wheelH = 0;
}

+ 4
- 4
ehci.cpp View File

@@ -468,8 +468,8 @@ void USBDriverTimer::start(uint32_t microseconds)
return;
}
uint32_t remain = USBHS_GPTIMER1CTL & 0xFFFFFF;
//Serial.print("remain = ");
//Serial.println(remain);
//USBHDBGSerial.print("remain = ");
//USBHDBGSerial.println(remain);
if (microseconds < remain) {
// this timer event is before any on the schedule
__disable_irq();
@@ -755,8 +755,8 @@ bool USBHost::queue_Data_Transfer(Pipe_t *pipe, void *buffer, uint32_t len, USBD
if (transfer == data) break;
transfer = next;
}
return false;
}
return false;
}
data->qtd.next = (uint32_t)next;
data = next;
}

+ 586
- 0
examples/Bluetooth/JoystickBT/JoystickBT.ino View File

@@ -0,0 +1,586 @@

// Simple test of USB Host Mouse/Keyboard
//
// This example is in the public domain

#include "USBHost_t36.h"
//#include "debug_tt.h"

USBHost myusb;
USBHub hub1(myusb);
USBHub hub2(myusb);
USBHIDParser hid1(myusb);
USBHIDParser hid2(myusb);
USBHIDParser hid3(myusb);
USBHIDParser hid4(myusb);
USBHIDParser hid5(myusb);
JoystickController joystick1(myusb);
//BluetoothController bluet(myusb, true, "0000"); // Version does pairing to device
BluetoothController bluet(myusb); // version assumes it already was paired
int user_axis[64];
uint32_t buttons_prev = 0;
uint32_t buttons;
RawHIDController rawhid1(myusb);
RawHIDController rawhid2(myusb, 0xffc90004);

USBDriver *drivers[] = {&hub1, &hub2, &joystick1, &bluet, &hid1, &hid2, &hid3, &hid4, &hid5};

#define CNT_DEVICES (sizeof(drivers)/sizeof(drivers[0]))
const char * driver_names[CNT_DEVICES] = {"Hub1", "Hub2", "JOY1D", "Bluet", "HID1" , "HID2", "HID3", "HID4", "HID5"};

bool driver_active[CNT_DEVICES] = {false, false, false, false};

// Lets also look at HID Input devices
USBHIDInput *hiddrivers[] = {&joystick1, &rawhid1, &rawhid2};

#define CNT_HIDDEVICES (sizeof(hiddrivers)/sizeof(hiddrivers[0]))
const char * hid_driver_names[CNT_DEVICES] = {"Joystick1", "RawHid1", "RawHid2"};

bool hid_driver_active[CNT_DEVICES] = {false, false, false};

BTHIDInput *bthiddrivers[] = {&joystick1};
#define CNT_BTHIDDEVICES (sizeof(bthiddrivers)/sizeof(bthiddrivers[0]))
const char * bthid_driver_names[CNT_HIDDEVICES] = {"joystick"};
bool bthid_driver_active[CNT_HIDDEVICES] = {false};


bool show_changed_only = false;
bool show_raw_data = false;
bool show_changed_data = false;

uint8_t joystick_left_trigger_value = 0;
uint8_t joystick_right_trigger_value = 0;
uint64_t joystick_full_notify_mask = (uint64_t) - 1;

int psAxis[64];
bool first_joystick_message = true;
uint8_t last_bdaddr[6] = {0, 0, 0, 0, 0, 0};

// ps3 motion on USB does not do much, but see if we can pair it and maybe change
// color of bulb...
uint32_t PS3_MOTION_timer = 0;
uint8_t PS3_MOTION_tried_to_pair_state = 0;
#define PS3_MOTION_PERIOD 2500 // not sure yet what would be good period for this..

//=============================================================================
// Setup
//=============================================================================
void setup()
{

Serial1.begin(2000000);
while (!Serial) ; // wait for Arduino Serial Monitor

Serial.println("\n\nUSB Host Testing");
Serial.println(sizeof(USBHub), DEC);
myusb.begin();

delay(2000);

rawhid1.attachReceive(OnReceiveHidData);
rawhid2.attachReceive(OnReceiveHidData);
}

//=============================================================================
// Loop
//=============================================================================
void loop()
{
myusb.Task();

if (Serial.available()) {
int ch = Serial.read(); // get the first char.
while (Serial.read() != -1) ;
if ((ch == 'b') || (ch == 'B')) {
Serial.println("Only notify on Basic Axis changes");
joystick1.axisChangeNotifyMask(0x3ff);
} else if ((ch == 'f') || (ch == 'F')) {
Serial.println("Only notify on Full Axis changes");
joystick1.axisChangeNotifyMask(joystick_full_notify_mask);

} else {
if (show_changed_only) {
show_changed_only = false;
Serial.println("\n*** Show All fields mode ***");
} else {
show_changed_only = true;
Serial.println("\n*** Show only changed fields mode ***");
}
}
}
// check to see if the device list has changed:
UpdateActiveDeviceInfo();
processPS3MotionTimer();

if (joystick1.available()) {
if (first_joystick_message) {
Serial.printf("*** First Joystick message %x:%x ***\n",
joystick1.idVendor(), joystick1.idProduct());
first_joystick_message = false;

const uint8_t *psz = joystick1.manufacturer();
if (psz && *psz) Serial.printf(" manufacturer: %s\n", psz);
psz = joystick1.product();
if (psz && *psz) Serial.printf(" product: %s\n", psz);
psz = joystick1.serialNumber();
if (psz && *psz) Serial.printf(" Serial: %s\n", psz);

// lets try to reduce number of fields that update
joystick1.axisChangeNotifyMask(0xFFFFFl);
}

for (uint8_t i = 0; i < 64; i++) {
psAxis[i] = joystick1.getAxis(i);
}
switch (joystick1.joystickType()) {
case JoystickController::UNKNOWN:
case JoystickController::PS4:
displayPS4Data();
break;
case JoystickController::PS3:
displayPS3Data();
break;
case JoystickController::PS3_MOTION:
displayPS3MotionData();
break;
case JoystickController::XBOXONE:
case JoystickController::XBOX360:
displayXBoxData();
break;
default:
displayRawData();
break;
}
//for (uint8_t i = 0; i < 24; i++) {
// Serial.printf(" %d:%d", i, psAxis[i]);
//}
//Serial.println();

delay(100);
joystick1.joystickDataClear();
}

// See if we have some RAW data
if (rawhid1) {
int ch;
uint8_t buffer[64];
uint8_t count_chars = 0;
memset(buffer, 0, sizeof(buffer));
if (Serial.available()) {
while (((ch = Serial.read()) != -1) && (count_chars < sizeof(buffer))) {
buffer[count_chars++] = ch;
}
rawhid1.sendPacket(buffer);
}
}
}

//=============================================================================
// UpdateActiveDeviceInfo
//=============================================================================
void UpdateActiveDeviceInfo() {
for (uint8_t i = 0; i < CNT_DEVICES; i++) {
if (*drivers[i] != driver_active[i]) {
if (driver_active[i]) {
Serial.printf("*** Device %s - disconnected ***\n", driver_names[i]);
driver_active[i] = false;
} else {
Serial.printf("*** Device %s %x:%x - connected ***\n", driver_names[i], drivers[i]->idVendor(), drivers[i]->idProduct());
driver_active[i] = true;

const uint8_t *psz = drivers[i]->manufacturer();
if (psz && *psz) Serial.printf(" manufacturer: %s\n", psz);
psz = drivers[i]->product();
if (psz && *psz) Serial.printf(" product: %s\n", psz);
psz = drivers[i]->serialNumber();
if (psz && *psz) Serial.printf(" Serial: %s\n", psz);

if (drivers[i] == &bluet) {
const uint8_t *bdaddr = bluet.myBDAddr();
// remember it...
Serial.printf(" BDADDR: %x:%x:%x:%x:%x:%x\n", bdaddr[0], bdaddr[1], bdaddr[2], bdaddr[3], bdaddr[4], bdaddr[5]);
for (uint8_t i = 0; i < 6; i++) last_bdaddr[i] = bdaddr[i];
}
}
}
}

for (uint8_t i = 0; i < CNT_HIDDEVICES; i++) {
if (*hiddrivers[i] != hid_driver_active[i]) {
if (hid_driver_active[i]) {
Serial.printf("*** HID Device %s - disconnected ***\n", hid_driver_names[i]);
hid_driver_active[i] = false;
} else {
Serial.printf("*** HID Device %s %x:%x - connected ***\n", hid_driver_names[i], hiddrivers[i]->idVendor(), hiddrivers[i]->idProduct());
hid_driver_active[i] = true;

const uint8_t *psz = hiddrivers[i]->manufacturer();
if (psz && *psz) Serial.printf(" manufacturer: %s\n", psz);
psz = hiddrivers[i]->product();
if (psz && *psz) Serial.printf(" product: %s\n", psz);
psz = hiddrivers[i]->serialNumber();
if (psz && *psz) Serial.printf(" Serial: %s\n", psz);

// See if this is our joystick object...
if (hiddrivers[i] == &joystick1) {
Serial.printf(" Joystick type: %d\n", joystick1.joystickType());
if (joystick1.joystickType() == JoystickController::PS3_MOTION) {
Serial.println(" PS3 Motion detected");
PS3_MOTION_timer = millis(); // set time for last event
PS3_MOTION_tried_to_pair_state = 0;
}
}

}
}
}
// Then Bluetooth devices
for (uint8_t i = 0; i < CNT_BTHIDDEVICES; i++) {
if (*bthiddrivers[i] != bthid_driver_active[i]) {
if (bthid_driver_active[i]) {
Serial.printf("*** BTHID Device %s - disconnected ***\n", hid_driver_names[i]);
bthid_driver_active[i] = false;
} else {
Serial.printf("*** BTHID Device %s %x:%x - connected ***\n", hid_driver_names[i], hiddrivers[i]->idVendor(), hiddrivers[i]->idProduct());
bthid_driver_active[i] = true;

const uint8_t *psz = bthiddrivers[i]->manufacturer();
if (psz && *psz) Serial.printf(" manufacturer: %s\n", psz);
psz = bthiddrivers[i]->product();
if (psz && *psz) Serial.printf(" product: %s\n", psz);
psz = bthiddrivers[i]->serialNumber();
if (psz && *psz) Serial.printf(" Serial: %s\n", psz);
}
}
}
}

//=============================================================================
// displayPS4Data
//=============================================================================
void displayPS4Data()
{
buttons = joystick1.getButtons();
Serial.printf("LX: %d, LY: %d, RX: %d, RY: %d \r\n", psAxis[0], psAxis[1], psAxis[2], psAxis[5]);
Serial.printf("L-Trig: %d, R-Trig: %d\r\n", psAxis[3], psAxis[4]);
Serial.printf("Buttons: %x\r\n", buttons);
Serial.printf("Battery Status: %d\n", ((psAxis[30] & ((1 << 4) - 1))*10));
printAngles();
Serial.println();

uint8_t ltv;
uint8_t rtv;

ltv = psAxis[3];
rtv = psAxis[4];

if ((ltv != joystick_left_trigger_value) || (rtv != joystick_right_trigger_value)) {
joystick_left_trigger_value = ltv;
joystick_right_trigger_value = rtv;
Serial.printf("Rumbling: %d, %d\r\n", ltv, rtv);
joystick1.setRumble(ltv, rtv);
}

if (buttons != buttons_prev) {
uint8_t lr = 0;
uint8_t lg = 0;
uint8_t lb = 0;
if(buttons == 0x10008){//Srq
lr = 0xff;
}
if(buttons == 0x40008){//Circ
lg = 0xff;
}
if(buttons == 0x80008){//Tri
lb = 0xff;
}
Serial.print(buttons,HEX); Serial.print(", ");
Serial.print(lr); Serial.print(", ");
Serial.print(lg); Serial.print(", ");
Serial.println(lb);
joystick1.setLEDs(lr, lg, lb);
buttons_prev = buttons;
}

}

//=============================================================================
// displayPS3Data
//=============================================================================
void displayPS3Data()

{
buttons = joystick1.getButtons();
//buttons = psAxis[2] | ((uint16_t)psAxis[3] << 8);

// Use L3 (Left joystick button) to toggle Show Raw or not...
if ((buttons & 0x02) && !(buttons_prev & 0x02)) show_raw_data = !show_raw_data;
if ((buttons & 0x04) && !(buttons_prev & 0x04)) show_changed_data = !show_changed_data;

// See about maybe pair...
if ((buttons & 0x10000) && !(buttons_prev & 0x10000) && (buttons & 0x0C01)) {
// PS button just pressed and select button pressed act like PS4 share like...
// Note: you can use either R1 or L1 with the PS button, to work with Sony Move Navigation...
Serial.print("\nPS3 Pairing Request");
if (!last_bdaddr[0] && !last_bdaddr[1] && !last_bdaddr[2] && !last_bdaddr[3] && !last_bdaddr[4] && !last_bdaddr[5]) {
Serial.println(" - failed - no Bluetooth adapter has been plugged in");
} else if (!hiddrivers[0]) { // Kludge see if we are connected as HID?
Serial.println(" - failed - PS3 device not plugged into USB");
} else {
Serial.printf(" - Attempt pair to: %x:%x:%x:%x:%x:%x\n", last_bdaddr[0], last_bdaddr[1], last_bdaddr[2], last_bdaddr[3], last_bdaddr[4], last_bdaddr[5]);

if (! joystick1.PS3Pair(last_bdaddr)) {
Serial.println(" Pairing call Failed");
} else {
Serial.println(" Pairing complete (I hope), make sure Bluetooth adapter is plugged in and try PS3 without USB");
}
}
}


if (show_raw_data) {
displayRawData();
} else {
Serial.printf("LX: %d, LY: %d, RX: %d, RY: %d \r\n", psAxis[0], psAxis[1], psAxis[2], psAxis[5]);
Serial.printf("L-Trig: %d, R-Trig: %d\r\n", psAxis[3], psAxis[4]);
Serial.printf("Buttons: %x\r\n", buttons);
}
uint8_t ltv;
uint8_t rtv;

ltv = psAxis[3];
rtv = psAxis[4];

if ((ltv != joystick_left_trigger_value) || (rtv != joystick_right_trigger_value)) {
joystick_left_trigger_value = ltv;
joystick_right_trigger_value = rtv;
Serial.printf("Rumbling: %d, %d\r\n", ltv, rtv);
joystick1.setRumble(ltv, rtv);
}

if (buttons != buttons_prev) {
uint8_t leds = 0;
if (buttons & 0x8000) leds = 1; //Srq
if (buttons & 0x2000) leds = 2; //Cir
if (buttons & 0x1000) leds = 3; //Tri
//Cross = 2
joystick1.setLEDs(leds);
buttons_prev = buttons;
}
}
//=============================================================================
// displayPS3MotionData
//=============================================================================
void displayPS3MotionData()

{
buttons = joystick1.getButtons();

// Hard to know what is best here. for now just copy raw data over...
// will do this for now... Format of thought to be data.
// data[1-3] Buttons (mentioned 4 as well but appears to be counter
// axis[0-1] data[5] Trigger, Previous trigger value
// 2-5 Unknown probably place holders for Axis like data for other PS3
// 6 - Time stamp
// 7 - Battery
// 8-19 - Accel: XL, XH, YL, YH, ZL, ZH, XL2, XH2, YL2, YH2, ZL2, ZH2
// 20-31 - Gyro: Xl,Xh,Yl,Yh,Zl,Zh,Xl2,Xh2,Yl2,Yh2,Zl2,Zh2
// 32 - Temp High
// 33 - Temp Low (4 bits) Maybe Magneto x High on other??

// Use Select button to choose raw or not
if ((buttons & 0x01) && !(buttons_prev & 0x01)) show_raw_data = !show_raw_data;
if ((buttons & 0x04) && !(buttons_prev & 0x04)) show_changed_data = !show_changed_data;

if (show_raw_data) {
displayRawData();
} else {
uint64_t changed_mask = joystick1.axisChangedMask();
Serial.printf("Changed: %08x Buttons: %x: Trig: %d\r\n", (uint32_t)changed_mask, buttons, psAxis[0]);
Serial.printf("Battery Status: %d\n", psAxis[7]);
printPS3MotionAngles();
Serial.println();
}

uint8_t ltv = psAxis[0];

if ((ltv != joystick_left_trigger_value) ) {
joystick_left_trigger_value = ltv;
Serial.printf("Rumbling: %d\r\n", ltv);
joystick1.setRumble(ltv, 0);
}

if (buttons != buttons_prev) {
uint8_t ledsR = (buttons & 0x8000)? 0xff : 0; //Srq
uint8_t ledsG = (buttons & 0x2000)? 0xff : 0; //Cir
uint8_t ledsB = (buttons & 0x1000)? 0xff : 0; //Tri
Serial.printf("Set Leds %x %x %x\r\n", ledsR, ledsG, ledsB );
joystick1.setLEDs(ledsR, ledsG, ledsB);
buttons_prev = buttons;
}
}

//=============================================================================
// displayXBoxData
//=============================================================================
void displayXBoxData()
{
buttons = joystick1.getButtons();

// Use L3 (Left joystick button) to toggle Show Raw or not...
if ((buttons & 0x4000) && !(buttons_prev & 0x4000)) show_raw_data = !show_raw_data;
if ((buttons & 0x8000) && !(buttons_prev & 0x8000)) show_changed_data = !show_changed_data;

if (show_raw_data) {
displayRawData();
} else {
Serial.printf("LX: %d, LY: %d, RX: %d, RY: %d \r\n", psAxis[0], psAxis[1], psAxis[2], psAxis[5]);
Serial.printf("L-Trig: %d, R-Trig: %d\r\n", psAxis[3], psAxis[4]);
Serial.printf("Buttons: %x\r\n", buttons);
}
uint8_t ltv;
uint8_t rtv;

ltv = psAxis[3];
rtv = psAxis[4];

if ((ltv != joystick_left_trigger_value) || (rtv != joystick_right_trigger_value)) {
joystick_left_trigger_value = ltv;
joystick_right_trigger_value = rtv;
Serial.printf("Rumbling: %d, %d\r\n", ltv, rtv);
joystick1.setRumble(ltv, rtv);
}

if (buttons != buttons_prev) {
uint8_t leds = 0;
if (buttons & 0x8000) leds = 1; //Srq
if (buttons & 0x2000) leds = 2; //Cir
if (buttons & 0x1000) leds = 3; //Tri
//Cross = 2
joystick1.setLEDs(leds);
buttons_prev = buttons;
}
}

//=============================================================================
// displayRawData
//=============================================================================
void displayRawData() {
uint64_t axis_mask = joystick1.axisMask();
uint64_t changed_mask = joystick1.axisChangedMask();

buttons = joystick1.getButtons();

if (!changed_mask && (buttons == buttons_prev)) return;

if (show_changed_data) {
if (!changed_mask) return;
changed_mask &= 0xfffffffffL; // try reducing which ones show...
Serial.printf("%0x - ", joystick1.getButtons());

for (uint16_t index = 0; changed_mask; index++) {
if (changed_mask & 1) {
Serial.printf("%d:%02x ", index, psAxis[index]);
}
changed_mask >>= 1;
}

} else {
axis_mask &= 0xffffff;
Serial.printf("%06x%06x: %06x - ", (uint32_t)(changed_mask >> 32), (uint32_t)(changed_mask & 0xffffffff), joystick1.getButtons());

for (uint16_t index = 0; axis_mask; index++) {
Serial.printf("%02x ", psAxis[index]);
axis_mask >>= 1;
}
}
Serial.println();
buttons_prev = buttons;

}


//=============================================================================
// OnReceiveHidData
//=============================================================================
bool OnReceiveHidData(uint32_t usage, const uint8_t *data, uint32_t len) {
// Called for maybe both HIDS for rawhid basic test. One is for the Teensy
// to output to Serial. while still having Raw Hid...
if (usage == 0xffc90004) {
// Lets trim off trailing null characters.
while ((len > 0) && (data[len - 1] == 0)) {
len--;
}
if (len) {
Serial.print("RawHid Serial: ");
Serial.write(data, len);
}
} else {
Serial.print("RawHID data: ");
Serial.println(usage, HEX);
while (len) {
uint8_t cb = (len > 16) ? 16 : len;
const uint8_t *p = data;
uint8_t i;
for (i = 0; i < cb; i++) {
Serial.printf("%02x ", *p++);
}
Serial.print(": ");
for (i = 0; i < cb; i++) {
Serial.write(((*data >= ' ') && (*data <= '~')) ? *data : '.');
data++;
}
len -= cb;
Serial.println();
}
}

return true;
}

//=============================================================================
// processPS3MotionTimer
//=============================================================================
static const uint32_t PS3_MOTION_colors[] = {0, 0xff, 0xff00, 0xff0000, 0xffff, 0xff00ff, 0xffff00, 0xffffff};

uint8_t PS3_MOTION_colors_index = 0;

void processPS3MotionTimer() {
// See if we have a PS3_MOTION connected and we have run for a certain amount of time

if (PS3_MOTION_timer && ((millis()-PS3_MOTION_timer) >= PS3_MOTION_PERIOD)) {
Serial.println("PS3 Motion Timer"); Serial.flush();
if (joystick1) {
PS3_MOTION_timer = millis(); // joystick not there any more...

// We will first try to set feedback color for the PS3, maybe alternate colors
if (++PS3_MOTION_colors_index >= sizeof(PS3_MOTION_colors)/sizeof(PS3_MOTION_colors[0])) PS3_MOTION_colors_index = 0;
joystick1.setLEDs(PS3_MOTION_colors[PS3_MOTION_colors_index]);

// Next see if we can try to pair.
if (PS3_MOTION_tried_to_pair_state == 0) {
Serial.println("PS3_MOTION Connected");
if (!last_bdaddr[0] && !last_bdaddr[1] && !last_bdaddr[2] && !last_bdaddr[3] && !last_bdaddr[4] && !last_bdaddr[5]) {
Serial.println(" - No Bluetooth adapter has been plugged in - so will not try to pair");
PS3_MOTION_tried_to_pair_state = 1;
}
}
if ((PS3_MOTION_tried_to_pair_state < 2) &&
(last_bdaddr[0] || last_bdaddr[1] || last_bdaddr[2] || last_bdaddr[3] || last_bdaddr[4] || last_bdaddr[5])) {
Serial.println(" - Bluetooth device detected, will try to pair");
// Lets try to pair
if (! joystick1.PS3Pair(last_bdaddr)) {
Serial.println(" - Pairing call Failed");
} else {
Serial.println(" - Pairing complete (I hope), make sure Bluetooth adapter is plugged in and try PS3 without USB");
}
PS3_MOTION_tried_to_pair_state = 2; // don't try again...
}
} else {
Serial.println("PS3 Motion Joystick no longer detected");
PS3_MOTION_timer = 0; // joystick not there any more...
}
}
}

+ 1
- 0
examples/Bluetooth/JoystickBT/defs.h View File

@@ -0,0 +1 @@


+ 146
- 0
examples/Bluetooth/JoystickBT/helperPS.ino View File

@@ -0,0 +1,146 @@
float pitch, roll;
float gx, gy, gz;
int16_t mx, my, mz;
uint16_t xc, yc;
uint8_t isTouch;
float ax, ay, az;
int16_t xc_old, yc_old;

/* Decode 12-bit signed value (assuming two's complement) */
#define TWELVE_BIT_SIGNED(x) (((x) & 0x800)?(-(((~(x)) & 0xFFF) + 1)):(x))

#define Model_ZCM1 1
//#define Model_ZCM2 0

void printAngles(){
//test function calls
float gx, gy, gz;
getAccel(ax, ay, az);
Serial.printf("Accel-g's: %f, %f, %f\n", ax, ay, az);
getGyro(gx, gy, gz);
Serial.printf("Gyro-deg/sec: %f, %f, %f\n", gx, gy, gz);

getAngles(pitch, roll);
Serial.printf("Pitch/Roll: %f, %f\n", pitch, roll);

getCoords(xc, yc, isTouch);
}

void getCoords(uint16_t &xc, uint16_t &yc, uint8_t &isTouch){

//uint8_t finger = 0; //only getting finger 1

// Trackpad touch 1: id, active, x, y
xc = ((psAxis[37] & 0x0f) << 8) | psAxis[36];
yc = psAxis[38] << 4 | ((psAxis[37] & 0xf0) >> 4),

isTouch = psAxis[35] >> 7;
if(xc != xc_old || yc != yc_old){
Serial.printf("Touch: %d, %d, %d, %d\n", psAxis[33], isTouch, xc, yc);
xc_old = xc;
yc_old = yc;
}
}

void getAccel( float &ax, float &ay, float &az){
int accelx = (int16_t)(psAxis[20]<<8) | psAxis[19];
int accelz = (int16_t)(psAxis[22]<<8) | psAxis[21];
int accely = (int16_t)(psAxis[24]<<8) | psAxis[23];

ax = (float) accelx/8192;
ay = (float) accely/8192;
az = (float) accelz/8192;
}

void getAngles(float &p, float &r){
getAccel( ax, ay, az);
p = (atan2f(ay, az) + PI) * RAD_TO_DEG;
r = (atan2f(ax, az) + PI) * RAD_TO_DEG;
}

void getGyro(float &gx, float &gy, float &gz){
int gyroy = (int16_t)(psAxis[14]<<8) | psAxis[13];
int gyroz = (int16_t)(psAxis[16]<<8) | psAxis[15];
int gyrox = (int16_t)(psAxis[18]<<8) | psAxis[17];

gx = (float) gyrox * RAD_TO_DEG/1024;
gy = (float) gyroy * RAD_TO_DEG/1024;
gz = (float) gyroz * RAD_TO_DEG/1024;
}


void printPS3MotionAngles(){
//test function calls
float gx, gy, gz;
getPS3MotionAccel(ax, ay, az);
Serial.printf("Accel-g's: %f, %f, %f\n", ax, ay, az);
getPS3MotionGyro(gx, gy, gz);
Serial.printf("Gyro-deg/sec: %f, %f, %f\n", gx, gy, gz);
getPS3MotionMag(mx, my, mz);
Serial.printf("Mag: %d, %d, %d\n", mx, my, mz);

getPS3MotionAngles(pitch, roll);
Serial.printf("Pitch/Roll: %f, %f\n", pitch, roll);
}


void getPS3MotionAccel( float &ax, float &ay, float &az){
int accelx = (psAxis[15]<<8 | psAxis[14]);
int accely = (psAxis[17]<<8 | psAxis[16]);
int accelz = (psAxis[19]<<8 | psAxis[18]);
#if defined(Model_ZCM1)
accelx = accelx-0x8000;
accely = accely-0x8000;
accelz = accelz-0x8000;
#elif defined(Model_ZCM2)
accelx = (accelx & 0x8000) ? (-(~accelx & 0xFFFF) + 1) : accelx;
accely = (accely & 0x8000) ? (-(~accely & 0xFFFF) + 1) : accely;
accelz = (accelz & 0x8000) ? (-(~accelz & 0xFFFF) + 1) : accelz;
#endif
ax = (float) accelx/4096;
ay = (float) accely/4096;
az = (float) accelz/4096;
}

void getPS3MotionAngles(float &p, float &r){
getAccel( ax, ay, az);
p = (atan2f(ay, az) + PI) * RAD_TO_DEG;
r = (atan2f(ax, az) + PI) * RAD_TO_DEG;
}

void getPS3MotionGyro(float &gx, float &gy, float &gz){
int gyrox = (psAxis[21]<<8 | psAxis[20]);
int gyroy = (psAxis[23]<<8 | psAxis[22]);
int gyroz = (psAxis[25]<<8 | psAxis[24]);
#if defined(Model_ZCM1)
gyrox = gyrox-0x8000;
gyroy = gyroy-0x8000;
gyroz = gyroz-0x8000;
#elif defined(Model_ZCM2)
gyrox = (gyrox & 0x8000) ? (-(~gyrox & 0xFFFF) + 1) : gyrox;
gyroy = (gyroy & 0x8000) ? (-(~gyroy & 0xFFFF) + 1) : gyroy;
gyroz = (gyroz & 0x8000) ? (-(~gyroz & 0xFFFF) + 1) : gyroz;
#endif

gx = (float) gyrox * RAD_TO_DEG/1024;
gy = (float) gyroy * RAD_TO_DEG/1024;
gz = (float) gyroz * RAD_TO_DEG/1024;
}
void getPS3MotionMag(int16_t &mx, int16_t &my, int16_t &mz){
#if defined(Model_ZCM1)
mx = TWELVE_BIT_SIGNED(((psAxis[33] & 0x0F) << 8) |
psAxis[34]);

my = TWELVE_BIT_SIGNED((psAxis[35] << 4) |
(psAxis[36] & 0xF0) >> 4);

mz = TWELVE_BIT_SIGNED(((psAxis[36] & 0x0F) << 8) |
psAxis[37]);
#elif defined(Model_ZCM2)
// NOTE: This model does not have magnetometers
Serial.println("Not avail for ZCM2!");
#endif
}

+ 568
- 0
examples/Bluetooth/KeyboardBT/KeyboardBT.ino View File

@@ -0,0 +1,568 @@
// Simple test of USB Host Mouse/Keyboard
//
// This example is in the public domain

#include "USBHost_t36.h"

USBHost myusb;
USBHub hub1(myusb);
USBHub hub2(myusb);
KeyboardController keyboard1(myusb);
//KeyboardController keyboard2(myusb);
USBHIDParser hid1(myusb);
USBHIDParser hid2(myusb);
USBHIDParser hid3(myusb);
USBHIDParser hid4(myusb);
USBHIDParser hid5(myusb);
//MouseController mouse1(myusb);
//JoystickController joystick1(myusb);
BluetoothController bluet(myusb, true, "0000"); // Version does pairing to device
//BluetoothController bluet(myusb); // version assumes it already was paired
int user_axis[64];
uint32_t buttons_prev = 0;
RawHIDController rawhid1(myusb);
RawHIDController rawhid2(myusb, 0xffc90004);

//USBDriver *drivers[] = {&hub1, &hub2,&keyboard1, &keyboard2, &joystick1, &bluet, &hid1, &hid2, &hid3, &hid4, &hid5};
USBDriver *drivers[] = {&hub1, &hub2, &keyboard1, &bluet, &hid1, &hid2, &hid3, &hid4, &hid5};

#define CNT_DEVICES (sizeof(drivers)/sizeof(drivers[0]))
//const char * driver_names[CNT_DEVICES] = {"Hub1","Hub2", "KB1", "KB2", "JOY1D", "Bluet", "HID1" , "HID2", "HID3", "HID4", "HID5"};
const char * driver_names[CNT_DEVICES] = {"Hub1","Hub2", "KB1", "Bluet", "HID1" , "HID2", "HID3", "HID4", "HID5"};

bool driver_active[CNT_DEVICES] = {false, false, false, false};

// Lets also look at HID Input devices
//USBHIDInput *hiddrivers[] = {&mouse1, &joystick1, &rawhid1, &rawhid2};
USBHIDInput *hiddrivers[] = {&rawhid1, &rawhid2};

#define CNT_HIDDEVICES (sizeof(hiddrivers)/sizeof(hiddrivers[0]))
//const char * hid_driver_names[CNT_DEVICES] = {"Mouse1","Joystick1", "RawHid1", "RawHid2"};
const char * hid_driver_names[CNT_DEVICES] = {"RawHid1", "RawHid2"};

bool hid_driver_active[CNT_DEVICES] = {false, false, false};
bool show_changed_only = false;

uint8_t joystick_left_trigger_value = 0;
uint8_t joystick_right_trigger_value = 0;
uint64_t joystick_full_notify_mask = (uint64_t)-1;

void setup()
{
while (!Serial) ; // wait for Arduino Serial Monitor
Serial.println("\n\nUSB Host Testing");
Serial.println(sizeof(USBHub), DEC);
myusb.begin();
keyboard1.attachPress(OnPress);
//keyboard2.attachPress(OnPress);
keyboard1.attachExtrasPress(OnHIDExtrasPress);
keyboard1.attachExtrasRelease(OnHIDExtrasRelease);
//keyboard2.attachExtrasPress(OnHIDExtrasPress);
//keyboard2.attachExtrasRelease(OnHIDExtrasRelease);

rawhid1.attachReceive(OnReceiveHidData);
rawhid2.attachReceive(OnReceiveHidData);
}


void loop()
{
myusb.Task();
/*
if (Serial.available()) {
int ch = Serial.read(); // get the first char.
while (Serial.read() != -1) ;
if ((ch == 'b') || (ch == 'B')) {
Serial.println("Only notify on Basic Axis changes");
joystick1.axisChangeNotifyMask(0x3ff);
} else if ((ch == 'f') || (ch == 'F')) {
Serial.println("Only notify on Full Axis changes");
joystick1.axisChangeNotifyMask(joystick_full_notify_mask);

} else {
if (show_changed_only) {
show_changed_only = false;
Serial.println("\n*** Show All fields mode ***");
} else {
show_changed_only = true;
Serial.println("\n*** Show only changed fields mode ***");
}
}
}
*/
for (uint8_t i = 0; i < CNT_DEVICES; i++) {
if (*drivers[i] != driver_active[i]) {
if (driver_active[i]) {
Serial.printf("*** Device %s - disconnected ***\n", driver_names[i]);
driver_active[i] = false;
} else {
Serial.printf("*** Device %s %x:%x - connected ***\n", driver_names[i], drivers[i]->idVendor(), drivers[i]->idProduct());
driver_active[i] = true;

const uint8_t *psz = drivers[i]->manufacturer();
if (psz && *psz) Serial.printf(" manufacturer: %s\n", psz);
psz = drivers[i]->product();
if (psz && *psz) Serial.printf(" product: %s\n", psz);
psz = drivers[i]->serialNumber();
if (psz && *psz) Serial.printf(" Serial: %s\n", psz);
}
}
}

for (uint8_t i = 0; i < CNT_HIDDEVICES; i++) {
if (*hiddrivers[i] != hid_driver_active[i]) {
if (hid_driver_active[i]) {
Serial.printf("*** HID Device %s - disconnected ***\n", hid_driver_names[i]);
hid_driver_active[i] = false;
} else {
Serial.printf("*** HID Device %s %x:%x - connected ***\n", hid_driver_names[i], hiddrivers[i]->idVendor(), hiddrivers[i]->idProduct());
hid_driver_active[i] = true;

const uint8_t *psz = hiddrivers[i]->manufacturer();
if (psz && *psz) Serial.printf(" manufacturer: %s\n", psz);
psz = hiddrivers[i]->product();
if (psz && *psz) Serial.printf(" product: %s\n", psz);
psz = hiddrivers[i]->serialNumber();
if (psz && *psz) Serial.printf(" Serial: %s\n", psz);
}
}
}


/*
if(mouse1.available()) {
Serial.print("Mouse: buttons = ");
Serial.print(mouse1.getButtons());
Serial.print(", mouseX = ");
Serial.print(mouse1.getMouseX());
Serial.print(", mouseY = ");
Serial.print(mouse1.getMouseY());
Serial.print(", wheel = ");
Serial.print(mouse1.getWheel());
Serial.print(", wheelH = ");
Serial.print(mouse1.getWheelH());
Serial.println();
mouse1.mouseDataClear();
}

if (joystick1.available()) {
uint64_t axis_mask = joystick1.axisMask();
uint64_t axis_changed_mask = joystick1.axisChangedMask();
Serial.print("Joystick: buttons = ");
uint32_t buttons = joystick1.getButtons();
Serial.print(buttons, HEX);
//Serial.printf(" AMasks: %x %x:%x", axis_mask, (uint32_t)(user_axis_mask >> 32), (uint32_t)(user_axis_mask & 0xffffffff));
//Serial.printf(" M: %lx %lx", axis_mask, joystick1.axisChangedMask());
if (show_changed_only) {
for (uint8_t i = 0; axis_changed_mask != 0; i++, axis_changed_mask >>= 1) {
if (axis_changed_mask & 1) {
Serial.printf(" %d:%d", i, joystick1.getAxis(i));
}
}

} else {
for (uint8_t i = 0; axis_mask != 0; i++, axis_mask >>= 1) {
if (axis_mask & 1) {
Serial.printf(" %d:%d", i, joystick1.getAxis(i));
}
}
}
uint8_t ltv;
uint8_t rtv;
switch (joystick1.joystickType) {
default:
break;
case JoystickController::PS4:
ltv = joystick1.getAxis(3);
rtv = joystick1.getAxis(4);
if ((ltv != joystick_left_trigger_value) || (rtv != joystick_right_trigger_value)) {
joystick_left_trigger_value = ltv;
joystick_right_trigger_value = rtv;
joystick1.setRumble(ltv, rtv);
}
break;

case JoystickController::PS3:
ltv = joystick1.getAxis(18);
rtv = joystick1.getAxis(19);
if ((ltv != joystick_left_trigger_value) || (rtv != joystick_right_trigger_value)) {
joystick_left_trigger_value = ltv;
joystick_right_trigger_value = rtv;
joystick1.setRumble(ltv, rtv, 50);
}
break;

case JoystickController::XBOXONE:
case JoystickController::XBOX360:
ltv = joystick1.getAxis(4);
rtv = joystick1.getAxis(5);
if ((ltv != joystick_left_trigger_value) || (rtv != joystick_right_trigger_value)) {
joystick_left_trigger_value = ltv;
joystick_right_trigger_value = rtv;
joystick1.setRumble(ltv, rtv);
Serial.printf(" Set Rumble %d %d", ltv, rtv);
}
break;
}
if (buttons != buttons_prev) {
if (joystick1.joystickType == JoystickController::PS3) {
joystick1.setLEDs((buttons>>12) & 0xf); // try to get to TRI/CIR/X/SQuare
} else {
uint8_t lr = (buttons & 1)? 0xff : 0;
uint8_t lg = (buttons & 2)? 0xff : 0;
uint8_t lb = (buttons & 4)? 0xff : 0;
joystick1.setLEDs(lr, lg, lb);
}
buttons_prev = buttons;
}

Serial.println();
joystick1.joystickDataClear();
}
*/
// See if we have some RAW data
if (rawhid1) {
int ch;
uint8_t buffer[64];
uint8_t count_chars = 0;
memset(buffer, 0, sizeof(buffer));
if (Serial.available()) {
while (((ch = Serial.read()) != -1) && (count_chars < sizeof(buffer))) {
buffer[count_chars++] = ch;
}
rawhid1.sendPacket(buffer);
}
}
}



void OnPress(int key)
{
Serial.print("key '");
switch (key) {
case KEYD_UP : Serial.print("UP"); break;
case KEYD_DOWN : Serial.print("DN"); break;
case KEYD_LEFT : Serial.print("LEFT"); break;
case KEYD_RIGHT : Serial.print("RIGHT"); break;
case KEYD_INSERT : Serial.print("Ins"); break;
case KEYD_DELETE : Serial.print("Del"); break;
case KEYD_PAGE_UP : Serial.print("PUP"); break;
case KEYD_PAGE_DOWN: Serial.print("PDN"); break;
case KEYD_HOME : Serial.print("HOME"); break;
case KEYD_END : Serial.print("END"); break;
case KEYD_F1 : Serial.print("F1"); break;
case KEYD_F2 : Serial.print("F2"); break;
case KEYD_F3 : Serial.print("F3"); break;
case KEYD_F4 : Serial.print("F4"); break;
case KEYD_F5 : Serial.print("F5"); break;
case KEYD_F6 : Serial.print("F6"); break;
case KEYD_F7 : Serial.print("F7"); break;
case KEYD_F8 : Serial.print("F8"); break;
case KEYD_F9 : Serial.print("F9"); break;
case KEYD_F10 : Serial.print("F10"); break;
case KEYD_F11 : Serial.print("F11"); break;
case KEYD_F12 : Serial.print("F12"); break;
default: Serial.print((char)key); break;
}
Serial.print("' ");
Serial.print(key);
Serial.print(" MOD: ");
if (keyboard1) {
Serial.print(keyboard1.getModifiers(), HEX);
Serial.print(" OEM: ");
Serial.print(keyboard1.getOemKey(), HEX);
Serial.print(" LEDS: ");
Serial.println(keyboard1.LEDS(), HEX);
//} else {
//Serial.print(keyboard2.getModifiers(), HEX);
//Serial.print(" OEM: ");
//Serial.print(keyboard2.getOemKey(), HEX);
//Serial.print(" LEDS: ");
//Serial.println(keyboard2.LEDS(), HEX);
}

//Serial.print("key ");
//Serial.print((char)keyboard1.getKey());
//Serial.print(" ");
//Serial.print((char)keyboard2.getKey());
//Serial.println();
}
void OnHIDExtrasPress(uint32_t top, uint16_t key)
{
Serial.print("HID (");
Serial.print(top, HEX);
Serial.print(") key press:");
Serial.print(key, HEX);
if (top == 0xc0000) {
switch (key) {
case 0x20 : Serial.print(" - +10"); break;
case 0x21 : Serial.print(" - +100"); break;
case 0x22 : Serial.print(" - AM/PM"); break;
case 0x30 : Serial.print(" - Power"); break;
case 0x31 : Serial.print(" - Reset"); break;
case 0x32 : Serial.print(" - Sleep"); break;
case 0x33 : Serial.print(" - Sleep After"); break;
case 0x34 : Serial.print(" - Sleep Mode"); break;
case 0x35 : Serial.print(" - Illumination"); break;
case 0x36 : Serial.print(" - Function Buttons"); break;
case 0x40 : Serial.print(" - Menu"); break;
case 0x41 : Serial.print(" - Menu Pick"); break;
case 0x42 : Serial.print(" - Menu Up"); break;
case 0x43 : Serial.print(" - Menu Down"); break;
case 0x44 : Serial.print(" - Menu Left"); break;
case 0x45 : Serial.print(" - Menu Right"); break;
case 0x46 : Serial.print(" - Menu Escape"); break;
case 0x47 : Serial.print(" - Menu Value Increase"); break;
case 0x48 : Serial.print(" - Menu Value Decrease"); break;
case 0x60 : Serial.print(" - Data On Screen"); break;
case 0x61 : Serial.print(" - Closed Caption"); break;
case 0x62 : Serial.print(" - Closed Caption Select"); break;
case 0x63 : Serial.print(" - VCR/TV"); break;
case 0x64 : Serial.print(" - Broadcast Mode"); break;
case 0x65 : Serial.print(" - Snapshot"); break;
case 0x66 : Serial.print(" - Still"); break;
case 0x80 : Serial.print(" - Selection"); break;
case 0x81 : Serial.print(" - Assign Selection"); break;
case 0x82 : Serial.print(" - Mode Step"); break;
case 0x83 : Serial.print(" - Recall Last"); break;
case 0x84 : Serial.print(" - Enter Channel"); break;
case 0x85 : Serial.print(" - Order Movie"); break;
case 0x86 : Serial.print(" - Channel"); break;
case 0x87 : Serial.print(" - Media Selection"); break;
case 0x88 : Serial.print(" - Media Select Computer"); break;
case 0x89 : Serial.print(" - Media Select TV"); break;
case 0x8A : Serial.print(" - Media Select WWW"); break;
case 0x8B : Serial.print(" - Media Select DVD"); break;
case 0x8C : Serial.print(" - Media Select Telephone"); break;
case 0x8D : Serial.print(" - Media Select Program Guide"); break;
case 0x8E : Serial.print(" - Media Select Video Phone"); break;
case 0x8F : Serial.print(" - Media Select Games"); break;
case 0x90 : Serial.print(" - Media Select Messages"); break;
case 0x91 : Serial.print(" - Media Select CD"); break;
case 0x92 : Serial.print(" - Media Select VCR"); break;
case 0x93 : Serial.print(" - Media Select Tuner"); break;
case 0x94 : Serial.print(" - Quit"); break;
case 0x95 : Serial.print(" - Help"); break;
case 0x96 : Serial.print(" - Media Select Tape"); break;
case 0x97 : Serial.print(" - Media Select Cable"); break;
case 0x98 : Serial.print(" - Media Select Satellite"); break;
case 0x99 : Serial.print(" - Media Select Security"); break;
case 0x9A : Serial.print(" - Media Select Home"); break;
case 0x9B : Serial.print(" - Media Select Call"); break;
case 0x9C : Serial.print(" - Channel Increment"); break;
case 0x9D : Serial.print(" - Channel Decrement"); break;
case 0x9E : Serial.print(" - Media Select SAP"); break;
case 0xA0 : Serial.print(" - VCR Plus"); break;
case 0xA1 : Serial.print(" - Once"); break;
case 0xA2 : Serial.print(" - Daily"); break;
case 0xA3 : Serial.print(" - Weekly"); break;
case 0xA4 : Serial.print(" - Monthly"); break;
case 0xB0 : Serial.print(" - Play"); break;
case 0xB1 : Serial.print(" - Pause"); break;
case 0xB2 : Serial.print(" - Record"); break;
case 0xB3 : Serial.print(" - Fast Forward"); break;
case 0xB4 : Serial.print(" - Rewind"); break;
case 0xB5 : Serial.print(" - Scan Next Track"); break;
case 0xB6 : Serial.print(" - Scan Previous Track"); break;
case 0xB7 : Serial.print(" - Stop"); break;
case 0xB8 : Serial.print(" - Eject"); break;
case 0xB9 : Serial.print(" - Random Play"); break;
case 0xBA : Serial.print(" - Select DisC"); break;
case 0xBB : Serial.print(" - Enter Disc"); break;
case 0xBC : Serial.print(" - Repeat"); break;
case 0xBD : Serial.print(" - Tracking"); break;
case 0xBE : Serial.print(" - Track Normal"); break;
case 0xBF : Serial.print(" - Slow Tracking"); break;
case 0xC0 : Serial.print(" - Frame Forward"); break;
case 0xC1 : Serial.print(" - Frame Back"); break;
case 0xC2 : Serial.print(" - Mark"); break;
case 0xC3 : Serial.print(" - Clear Mark"); break;
case 0xC4 : Serial.print(" - Repeat From Mark"); break;
case 0xC5 : Serial.print(" - Return To Mark"); break;
case 0xC6 : Serial.print(" - Search Mark Forward"); break;
case 0xC7 : Serial.print(" - Search Mark Backwards"); break;
case 0xC8 : Serial.print(" - Counter Reset"); break;
case 0xC9 : Serial.print(" - Show Counter"); break;
case 0xCA : Serial.print(" - Tracking Increment"); break;
case 0xCB : Serial.print(" - Tracking Decrement"); break;
case 0xCD : Serial.print(" - Pause/Continue"); break;
case 0xE0 : Serial.print(" - Volume"); break;
case 0xE1 : Serial.print(" - Balance"); break;
case 0xE2 : Serial.print(" - Mute"); break;
case 0xE3 : Serial.print(" - Bass"); break;
case 0xE4 : Serial.print(" - Treble"); break;
case 0xE5 : Serial.print(" - Bass Boost"); break;
case 0xE6 : Serial.print(" - Surround Mode"); break;
case 0xE7 : Serial.print(" - Loudness"); break;
case 0xE8 : Serial.print(" - MPX"); break;
case 0xE9 : Serial.print(" - Volume Up"); break;
case 0xEA : Serial.print(" - Volume Down"); break;
case 0xF0 : Serial.print(" - Speed Select"); break;
case 0xF1 : Serial.print(" - Playback Speed"); break;
case 0xF2 : Serial.print(" - Standard Play"); break;
case 0xF3 : Serial.print(" - Long Play"); break;
case 0xF4 : Serial.print(" - Extended Play"); break;
case 0xF5 : Serial.print(" - Slow"); break;
case 0x100: Serial.print(" - Fan Enable"); break;
case 0x101: Serial.print(" - Fan Speed"); break;
case 0x102: Serial.print(" - Light"); break;
case 0x103: Serial.print(" - Light Illumination Level"); break;
case 0x104: Serial.print(" - Climate Control Enable"); break;
case 0x105: Serial.print(" - Room Temperature"); break;
case 0x106: Serial.print(" - Security Enable"); break;
case 0x107: Serial.print(" - Fire Alarm"); break;
case 0x108: Serial.print(" - Police Alarm"); break;
case 0x150: Serial.print(" - Balance Right"); break;
case 0x151: Serial.print(" - Balance Left"); break;
case 0x152: Serial.print(" - Bass Increment"); break;
case 0x153: Serial.print(" - Bass Decrement"); break;
case 0x154: Serial.print(" - Treble Increment"); break;
case 0x155: Serial.print(" - Treble Decrement"); break;
case 0x160: Serial.print(" - Speaker System"); break;
case 0x161: Serial.print(" - Channel Left"); break;
case 0x162: Serial.print(" - Channel Right"); break;
case 0x163: Serial.print(" - Channel Center"); break;
case 0x164: Serial.print(" - Channel Front"); break;
case 0x165: Serial.print(" - Channel Center Front"); break;
case 0x166: Serial.print(" - Channel Side"); break;
case 0x167: Serial.print(" - Channel Surround"); break;
case 0x168: Serial.print(" - Channel Low Frequency Enhancement"); break;
case 0x169: Serial.print(" - Channel Top"); break;
case 0x16A: Serial.print(" - Channel Unknown"); break;
case 0x170: Serial.print(" - Sub-channel"); break;
case 0x171: Serial.print(" - Sub-channel Increment"); break;
case 0x172: Serial.print(" - Sub-channel Decrement"); break;
case 0x173: Serial.print(" - Alternate Audio Increment"); break;
case 0x174: Serial.print(" - Alternate Audio Decrement"); break;
case 0x180: Serial.print(" - Application Launch Buttons"); break;
case 0x181: Serial.print(" - AL Launch Button Configuration Tool"); break;
case 0x182: Serial.print(" - AL Programmable Button Configuration"); break;
case 0x183: Serial.print(" - AL Consumer Control Configuration"); break;
case 0x184: Serial.print(" - AL Word Processor"); break;
case 0x185: Serial.print(" - AL Text Editor"); break;
case 0x186: Serial.print(" - AL Spreadsheet"); break;
case 0x187: Serial.print(" - AL Graphics Editor"); break;
case 0x188: Serial.print(" - AL Presentation App"); break;
case 0x189: Serial.print(" - AL Database App"); break;
case 0x18A: Serial.print(" - AL Email Reader"); break;
case 0x18B: Serial.print(" - AL Newsreader"); break;
case 0x18C: Serial.print(" - AL Voicemail"); break;
case 0x18D: Serial.print(" - AL Contacts/Address Book"); break;
case 0x18E: Serial.print(" - AL Calendar/Schedule"); break;
case 0x18F: Serial.print(" - AL Task/Project Manager"); break;
case 0x190: Serial.print(" - AL Log/Journal/Timecard"); break;
case 0x191: Serial.print(" - AL Checkbook/Finance"); break;
case 0x192: Serial.print(" - AL Calculator"); break;
case 0x193: Serial.print(" - AL A/V Capture/Playback"); break;
case 0x194: Serial.print(" - AL Local Machine Browser"); break;
case 0x195: Serial.print(" - AL LAN/WAN Browser"); break;
case 0x196: Serial.print(" - AL Internet Browser"); break;
case 0x197: Serial.print(" - AL Remote Networking/ISP Connect"); break;
case 0x198: Serial.print(" - AL Network Conference"); break;
case 0x199: Serial.print(" - AL Network Chat"); break;
case 0x19A: Serial.print(" - AL Telephony/Dialer"); break;
case 0x19B: Serial.print(" - AL Logon"); break;
case 0x19C: Serial.print(" - AL Logoff"); break;
case 0x19D: Serial.print(" - AL Logon/Logoff"); break;
case 0x19E: Serial.print(" - AL Terminal Lock/Screensaver"); break;
case 0x19F: Serial.print(" - AL Control Panel"); break;
case 0x1A0: Serial.print(" - AL Command Line Processor/Run"); break;
case 0x1A1: Serial.print(" - AL Process/Task Manager"); break;
case 0x1A2: Serial.print(" - AL Select Tast/Application"); break;
case 0x1A3: Serial.print(" - AL Next Task/Application"); break;
case 0x1A4: Serial.print(" - AL Previous Task/Application"); break;
case 0x1A5: Serial.print(" - AL Preemptive Halt Task/Application"); break;
case 0x200: Serial.print(" - Generic GUI Application Controls"); break;
case 0x201: Serial.print(" - AC New"); break;
case 0x202: Serial.print(" - AC Open"); break;
case 0x203: Serial.print(" - AC Close"); break;
case 0x204: Serial.print(" - AC Exit"); break;
case 0x205: Serial.print(" - AC Maximize"); break;
case 0x206: Serial.print(" - AC Minimize"); break;
case 0x207: Serial.print(" - AC Save"); break;
case 0x208: Serial.print(" - AC Print"); break;
case 0x209: Serial.print(" - AC Properties"); break;
case 0x21A: Serial.print(" - AC Undo"); break;
case 0x21B: Serial.print(" - AC Copy"); break;
case 0x21C: Serial.print(" - AC Cut"); break;
case 0x21D: Serial.print(" - AC Paste"); break;
case 0x21E: Serial.print(" - AC Select All"); break;
case 0x21F: Serial.print(" - AC Find"); break;
case 0x220: Serial.print(" - AC Find and Replace"); break;
case 0x221: Serial.print(" - AC Search"); break;
case 0x222: Serial.print(" - AC Go To"); break;
case 0x223: Serial.print(" - AC Home"); break;
case 0x224: Serial.print(" - AC Back"); break;
case 0x225: Serial.print(" - AC Forward"); break;
case 0x226: Serial.print(" - AC Stop"); break;
case 0x227: Serial.print(" - AC Refresh"); break;
case 0x228: Serial.print(" - AC Previous Link"); break;
case 0x229: Serial.print(" - AC Next Link"); break;
case 0x22A: Serial.print(" - AC Bookmarks"); break;
case 0x22B: Serial.print(" - AC History"); break;
case 0x22C: Serial.print(" - AC Subscriptions"); break;
case 0x22D: Serial.print(" - AC Zoom In"); break;
case 0x22E: Serial.print(" - AC Zoom Out"); break;
case 0x22F: Serial.print(" - AC Zoom"); break;
case 0x230: Serial.print(" - AC Full Screen View"); break;
case 0x231: Serial.print(" - AC Normal View"); break;
case 0x232: Serial.print(" - AC View Toggle"); break;
case 0x233: Serial.print(" - AC Scroll Up"); break;
case 0x234: Serial.print(" - AC Scroll Down"); break;
case 0x235: Serial.print(" - AC Scroll"); break;
case 0x236: Serial.print(" - AC Pan Left"); break;
case 0x237: Serial.print(" - AC Pan Right"); break;
case 0x238: Serial.print(" - AC Pan"); break;
case 0x239: Serial.print(" - AC New Window"); break;
case 0x23A: Serial.print(" - AC Tile Horizontally"); break;
case 0x23B: Serial.print(" - AC Tile Vertically"); break;
case 0x23C: Serial.print(" - AC Format"); break;

}
}
Serial.println();
}

void OnHIDExtrasRelease(uint32_t top, uint16_t key)
{
Serial.print("HID (");
Serial.print(top, HEX);
Serial.print(") key release:");
Serial.println(key, HEX);
}

bool OnReceiveHidData(uint32_t usage, const uint8_t *data, uint32_t len) {
// Called for maybe both HIDS for rawhid basic test. One is for the Teensy
// to output to Serial. while still having Raw Hid...
if (usage == 0xffc90004) {
// Lets trim off trailing null characters.
while ((len > 0) && (data[len-1] == 0)) {
len--;
}
if (len) {
Serial.print("RawHid Serial: ");
Serial.write(data, len);
}
} else {
Serial.print("RawHID data: ");
Serial.println(usage, HEX);
while (len) {
uint8_t cb = (len > 16)? 16 : len;
const uint8_t *p = data;
uint8_t i;
for (i = 0; i < cb; i++) {
Serial.printf("%02x ", *p++);
}
Serial.print(": ");
for (i = 0; i < cb; i++) {
Serial.write(((*data >= ' ')&&(*data <= '~'))? *data : '.');
data++;
}
len -= cb;
Serial.println();
}
}

return true;
}

+ 1
- 0
examples/Bluetooth/KeyboardBT/defs.h View File

@@ -0,0 +1 @@


+ 577
- 0
examples/Bluetooth/MouseBT/MouseBT.ino View File

@@ -0,0 +1,577 @@
// Simple test of USB Host Mouse/Keyboard
//
// This example is in the public domain

#include "USBHost_t36.h"

USBHost myusb;
USBHub hub1(myusb);
USBHub hub2(myusb);
KeyboardController keyboard1(myusb);
KeyboardController keyboard2(myusb);
USBHIDParser hid1(myusb);
USBHIDParser hid2(myusb);
USBHIDParser hid3(myusb);
USBHIDParser hid4(myusb);
USBHIDParser hid5(myusb);
MouseController mouse1(myusb);
JoystickController joystick1(myusb);
BluetoothController bluet(myusb, true, "0000"); // Version does pairing to device
//BluetoothController bluet(myusb); // version assumes it already was paired
int user_axis[64];
uint32_t buttons_prev = 0;
RawHIDController rawhid1(myusb);
RawHIDController rawhid2(myusb, 0xffc90004);

USBDriver *drivers[] = {&hub1, &hub2,&keyboard1, &keyboard2, &joystick1, &bluet, &hid1, &hid2, &hid3, &hid4, &hid5};
#define CNT_DEVICES (sizeof(drivers)/sizeof(drivers[0]))
const char * driver_names[CNT_DEVICES] = {"Hub1","Hub2", "KB1", "KB2", "JOY1D", "Bluet", "HID1" , "HID2", "HID3", "HID4", "HID5"};
bool driver_active[CNT_DEVICES] = {false, false, false, false};

// Lets also look at HID Input devices
USBHIDInput *hiddrivers[] = {&mouse1, &joystick1, &rawhid1, &rawhid2};
#define CNT_HIDDEVICES (sizeof(hiddrivers)/sizeof(hiddrivers[0]))
const char * hid_driver_names[CNT_DEVICES] = {"Mouse1", "Joystick1", "RawHid1", "RawHid2"};
bool hid_driver_active[CNT_DEVICES] = {false, false};
bool show_changed_only = false;

uint8_t joystick_left_trigger_value = 0;
uint8_t joystick_right_trigger_value = 0;
uint64_t joystick_full_notify_mask = (uint64_t) - 1;

void setup()
{
while (!Serial) ; // wait for Arduino Serial Monitor
Serial.println("\n\nUSB Host Testing");
Serial.println(sizeof(USBHub), DEC);
myusb.begin();
keyboard1.attachPress(OnPress);
keyboard2.attachPress(OnPress);
keyboard1.attachExtrasPress(OnHIDExtrasPress);
keyboard1.attachExtrasRelease(OnHIDExtrasRelease);
keyboard2.attachExtrasPress(OnHIDExtrasPress);
keyboard2.attachExtrasRelease(OnHIDExtrasRelease);

// The below forceBootProtocol will force which ever
// next keyboard that attaches to this device to be in boot protocol
// Only try this if you run into keyboard with issues. If this is a combined
// device like wireless mouse and keyboard this can cause mouse problems.
//keyboard1.forceBootProtocol();
rawhid1.attachReceive(OnReceiveHidData);
rawhid2.attachReceive(OnReceiveHidData);
}


void loop()
{
myusb.Task();

if (Serial.available()) {
int ch = Serial.read(); // get the first char.
while (Serial.read() != -1) ;
if ((ch == 'b') || (ch == 'B')) {
Serial.println("Only notify on Basic Axis changes");
joystick1.axisChangeNotifyMask(0x3ff);
} else if ((ch == 'f') || (ch == 'F')) {
Serial.println("Only notify on Full Axis changes");
joystick1.axisChangeNotifyMask(joystick_full_notify_mask);

} else {
if (show_changed_only) {
show_changed_only = false;
Serial.println("\n*** Show All fields mode ***");
} else {
show_changed_only = true;
Serial.println("\n*** Show only changed fields mode ***");
}
}
}

for (uint8_t i = 0; i < CNT_DEVICES; i++) {
if (*drivers[i] != driver_active[i]) {
if (driver_active[i]) {
Serial.printf("*** Device %s - disconnected ***\n", driver_names[i]);
driver_active[i] = false;
} else {
Serial.printf("*** Device %s %x:%x - connected ***\n", driver_names[i], drivers[i]->idVendor(), drivers[i]->idProduct());
driver_active[i] = true;

const uint8_t *psz = drivers[i]->manufacturer();
if (psz && *psz) Serial.printf(" manufacturer: %s\n", psz);
psz = drivers[i]->product();
if (psz && *psz) Serial.printf(" product: %s\n", psz);
psz = drivers[i]->serialNumber();
if (psz && *psz) Serial.printf(" Serial: %s\n", psz);

// Note: with some keyboards there is an issue that they don't output in boot protocol mode
// and may not work. The above code can try to force the keyboard into boot mode, but there
// are issues with doing this blindly with combo devices like wireless keyboard/mouse, which
// may cause the mouse to not work. Note: the above id is in the builtin list of
// vendor IDs that are already forced
if (drivers[i] == &keyboard1) {
if (keyboard1.idVendor() == 0x04D9) {
Serial.println("Gigabyte vendor: force boot protocol");
// Gigabyte keyboard
keyboard1.forceBootProtocol();
}
}
}
}
}

for (uint8_t i = 0; i < CNT_HIDDEVICES; i++) {
if (*hiddrivers[i] != hid_driver_active[i]) {
if (hid_driver_active[i]) {
Serial.printf("*** HID Device %s - disconnected ***\n", hid_driver_names[i]);
hid_driver_active[i] = false;
} else {
Serial.printf("*** HID Device %s %x:%x - connected ***\n", hid_driver_names[i], hiddrivers[i]->idVendor(), hiddrivers[i]->idProduct());
hid_driver_active[i] = true;

const uint8_t *psz = hiddrivers[i]->manufacturer();
if (psz && *psz) Serial.printf(" manufacturer: %s\n", psz);
psz = hiddrivers[i]->product();
if (psz && *psz) Serial.printf(" product: %s\n", psz);
psz = hiddrivers[i]->serialNumber();
if (psz && *psz) Serial.printf(" Serial: %s\n", psz);
}
}
}



if (mouse1.available()) {
Serial.print("Mouse: buttons = ");
Serial.print(mouse1.getButtons());
Serial.print(", mouseX = ");
Serial.print(mouse1.getMouseX());
Serial.print(", mouseY = ");
Serial.print(mouse1.getMouseY());
Serial.print(", wheel = ");
Serial.print(mouse1.getWheel());
Serial.print(", wheelH = ");
Serial.print(mouse1.getWheelH());
Serial.println();
mouse1.mouseDataClear();
}
if (joystick1.available()) {
uint64_t axis_mask = joystick1.axisMask();
uint64_t axis_changed_mask = joystick1.axisChangedMask();
Serial.print("Joystick: buttons = ");
uint32_t buttons = joystick1.getButtons();
Serial.print(buttons, HEX);
//Serial.printf(" AMasks: %x %x:%x", axis_mask, (uint32_t)(user_axis_mask >> 32), (uint32_t)(user_axis_mask & 0xffffffff));
//Serial.printf(" M: %lx %lx", axis_mask, joystick1.axisChangedMask());
if (show_changed_only) {
for (uint8_t i = 0; axis_changed_mask != 0; i++, axis_changed_mask >>= 1) {
if (axis_changed_mask & 1) {
Serial.printf(" %d:%d", i, joystick1.getAxis(i));
}
}

} else {
for (uint8_t i = 0; axis_mask != 0; i++, axis_mask >>= 1) {
if (axis_mask & 1) {
Serial.printf(" %d:%d", i, joystick1.getAxis(i));
}
}
}
uint8_t ltv;
uint8_t rtv;
switch (joystick1.joystickType()) {
default:
break;
case JoystickController::PS4:
ltv = joystick1.getAxis(3);
rtv = joystick1.getAxis(4);
if ((ltv != joystick_left_trigger_value) || (rtv != joystick_right_trigger_value)) {
joystick_left_trigger_value = ltv;
joystick_right_trigger_value = rtv;
joystick1.setRumble(ltv, rtv);
}
break;

case JoystickController::PS3:
ltv = joystick1.getAxis(18);
rtv = joystick1.getAxis(19);
if ((ltv != joystick_left_trigger_value) || (rtv != joystick_right_trigger_value)) {
joystick_left_trigger_value = ltv;
joystick_right_trigger_value = rtv;
joystick1.setRumble(ltv, rtv, 50);
}
break;

case JoystickController::XBOXONE:
case JoystickController::XBOX360:
ltv = joystick1.getAxis(4);
rtv = joystick1.getAxis(5);
if ((ltv != joystick_left_trigger_value) || (rtv != joystick_right_trigger_value)) {
joystick_left_trigger_value = ltv;
joystick_right_trigger_value = rtv;
joystick1.setRumble(ltv, rtv);
Serial.printf(" Set Rumble %d %d", ltv, rtv);
}
break;
}
if (buttons != buttons_prev) {
if (joystick1.joystickType() == JoystickController::PS3) {
joystick1.setLEDs((buttons >> 12) & 0xf); // try to get to TRI/CIR/X/SQuare
} else {
uint8_t lr = (buttons & 1) ? 0xff : 0;
uint8_t lg = (buttons & 2) ? 0xff : 0;
uint8_t lb = (buttons & 4) ? 0xff : 0;
joystick1.setLEDs(lr, lg, lb);
}
buttons_prev = buttons;
}

Serial.println();
joystick1.joystickDataClear();
}

// See if we have some RAW data
if (rawhid1) {
int ch;
uint8_t buffer[64];
uint8_t count_chars = 0;
memset(buffer, 0, sizeof(buffer));
if (Serial.available()) {
while (((ch = Serial.read()) != -1) && (count_chars < sizeof(buffer))) {
buffer[count_chars++] = ch;
}
rawhid1.sendPacket(buffer);
}
}
}



void OnPress(int key)
{
Serial.print("key '");
switch (key) {
case KEYD_UP : Serial.print("UP"); break;
case KEYD_DOWN : Serial.print("DN"); break;
case KEYD_LEFT : Serial.print("LEFT"); break;
case KEYD_RIGHT : Serial.print("RIGHT"); break;
case KEYD_INSERT : Serial.print("Ins"); break;
case KEYD_DELETE : Serial.print("Del"); break;
case KEYD_PAGE_UP : Serial.print("PUP"); break;
case KEYD_PAGE_DOWN: Serial.print("PDN"); break;
case KEYD_HOME : Serial.print("HOME"); break;
case KEYD_END : Serial.print("END"); break;
case KEYD_F1 : Serial.print("F1"); break;
case KEYD_F2 : Serial.print("F2"); break;
case KEYD_F3 : Serial.print("F3"); break;
case KEYD_F4 : Serial.print("F4"); break;
case KEYD_F5 : Serial.print("F5"); break;
case KEYD_F6 : Serial.print("F6"); break;
case KEYD_F7 : Serial.print("F7"); break;
case KEYD_F8 : Serial.print("F8"); break;
case KEYD_F9 : Serial.print("F9"); break;
case KEYD_F10 : Serial.print("F10"); break;
case KEYD_F11 : Serial.print("F11"); break;
case KEYD_F12 : Serial.print("F12"); break;
default: Serial.print((char)key); break;
}
Serial.print("' ");
Serial.print(key);
Serial.print(" MOD: ");
if (keyboard1) {
Serial.print(keyboard1.getModifiers(), HEX);
Serial.print(" OEM: ");
Serial.print(keyboard1.getOemKey(), HEX);
Serial.print(" LEDS: ");
Serial.println(keyboard1.LEDS(), HEX);
} else {
Serial.print(keyboard2.getModifiers(), HEX);
Serial.print(" OEM: ");
Serial.print(keyboard2.getOemKey(), HEX);
Serial.print(" LEDS: ");
Serial.println(keyboard2.LEDS(), HEX);
}

//Serial.print("key ");
//Serial.print((char)keyboard1.getKey());
//Serial.print(" ");
//Serial.print((char)keyboard2.getKey());
//Serial.println();
}
void OnHIDExtrasPress(uint32_t top, uint16_t key)
{
Serial.print("HID (");
Serial.print(top, HEX);
Serial.print(") key press:");
Serial.print(key, HEX);
if (top == 0xc0000) {
switch (key) {
case 0x20 : Serial.print(" - +10"); break;
case 0x21 : Serial.print(" - +100"); break;
case 0x22 : Serial.print(" - AM/PM"); break;
case 0x30 : Serial.print(" - Power"); break;
case 0x31 : Serial.print(" - Reset"); break;
case 0x32 : Serial.print(" - Sleep"); break;
case 0x33 : Serial.print(" - Sleep After"); break;
case 0x34 : Serial.print(" - Sleep Mode"); break;
case 0x35 : Serial.print(" - Illumination"); break;
case 0x36 : Serial.print(" - Function Buttons"); break;
case 0x40 : Serial.print(" - Menu"); break;
case 0x41 : Serial.print(" - Menu Pick"); break;
case 0x42 : Serial.print(" - Menu Up"); break;
case 0x43 : Serial.print(" - Menu Down"); break;
case 0x44 : Serial.print(" - Menu Left"); break;
case 0x45 : Serial.print(" - Menu Right"); break;
case 0x46 : Serial.print(" - Menu Escape"); break;
case 0x47 : Serial.print(" - Menu Value Increase"); break;
case 0x48 : Serial.print(" - Menu Value Decrease"); break;
case 0x60 : Serial.print(" - Data On Screen"); break;
case 0x61 : Serial.print(" - Closed Caption"); break;
case 0x62 : Serial.print(" - Closed Caption Select"); break;
case 0x63 : Serial.print(" - VCR/TV"); break;
case 0x64 : Serial.print(" - Broadcast Mode"); break;
case 0x65 : Serial.print(" - Snapshot"); break;
case 0x66 : Serial.print(" - Still"); break;
case 0x80 : Serial.print(" - Selection"); break;
case 0x81 : Serial.print(" - Assign Selection"); break;
case 0x82 : Serial.print(" - Mode Step"); break;
case 0x83 : Serial.print(" - Recall Last"); break;
case 0x84 : Serial.print(" - Enter Channel"); break;
case 0x85 : Serial.print(" - Order Movie"); break;
case 0x86 : Serial.print(" - Channel"); break;
case 0x87 : Serial.print(" - Media Selection"); break;
case 0x88 : Serial.print(" - Media Select Computer"); break;
case 0x89 : Serial.print(" - Media Select TV"); break;
case 0x8A : Serial.print(" - Media Select WWW"); break;
case 0x8B : Serial.print(" - Media Select DVD"); break;
case 0x8C : Serial.print(" - Media Select Telephone"); break;
case 0x8D : Serial.print(" - Media Select Program Guide"); break;
case 0x8E : Serial.print(" - Media Select Video Phone"); break;
case 0x8F : Serial.print(" - Media Select Games"); break;
case 0x90 : Serial.print(" - Media Select Messages"); break;
case 0x91 : Serial.print(" - Media Select CD"); break;
case 0x92 : Serial.print(" - Media Select VCR"); break;
case 0x93 : Serial.print(" - Media Select Tuner"); break;
case 0x94 : Serial.print(" - Quit"); break;
case 0x95 : Serial.print(" - Help"); break;
case 0x96 : Serial.print(" - Media Select Tape"); break;
case 0x97 : Serial.print(" - Media Select Cable"); break;
case 0x98 : Serial.print(" - Media Select Satellite"); break;
case 0x99 : Serial.print(" - Media Select Security"); break;
case 0x9A : Serial.print(" - Media Select Home"); break;
case 0x9B : Serial.print(" - Media Select Call"); break;
case 0x9C : Serial.print(" - Channel Increment"); break;
case 0x9D : Serial.print(" - Channel Decrement"); break;
case 0x9E : Serial.print(" - Media Select SAP"); break;
case 0xA0 : Serial.print(" - VCR Plus"); break;
case 0xA1 : Serial.print(" - Once"); break;
case 0xA2 : Serial.print(" - Daily"); break;
case 0xA3 : Serial.print(" - Weekly"); break;
case 0xA4 : Serial.print(" - Monthly"); break;
case 0xB0 : Serial.print(" - Play"); break;
case 0xB1 : Serial.print(" - Pause"); break;
case 0xB2 : Serial.print(" - Record"); break;
case 0xB3 : Serial.print(" - Fast Forward"); break;
case 0xB4 : Serial.print(" - Rewind"); break;
case 0xB5 : Serial.print(" - Scan Next Track"); break;
case 0xB6 : Serial.print(" - Scan Previous Track"); break;
case 0xB7 : Serial.print(" - Stop"); break;
case 0xB8 : Serial.print(" - Eject"); break;
case 0xB9 : Serial.print(" - Random Play"); break;
case 0xBA : Serial.print(" - Select DisC"); break;
case 0xBB : Serial.print(" - Enter Disc"); break;
case 0xBC : Serial.print(" - Repeat"); break;
case 0xBD : Serial.print(" - Tracking"); break;
case 0xBE : Serial.print(" - Track Normal"); break;
case 0xBF : Serial.print(" - Slow Tracking"); break;
case 0xC0 : Serial.print(" - Frame Forward"); break;
case 0xC1 : Serial.print(" - Frame Back"); break;
case 0xC2 : Serial.print(" - Mark"); break;
case 0xC3 : Serial.print(" - Clear Mark"); break;
case 0xC4 : Serial.print(" - Repeat From Mark"); break;
case 0xC5 : Serial.print(" - Return To Mark"); break;
case 0xC6 : Serial.print(" - Search Mark Forward"); break;
case 0xC7 : Serial.print(" - Search Mark Backwards"); break;
case 0xC8 : Serial.print(" - Counter Reset"); break;
case 0xC9 : Serial.print(" - Show Counter"); break;
case 0xCA : Serial.print(" - Tracking Increment"); break;
case 0xCB : Serial.print(" - Tracking Decrement"); break;
case 0xCD : Serial.print(" - Pause/Continue"); break;
case 0xE0 : Serial.print(" - Volume"); break;
case 0xE1 : Serial.print(" - Balance"); break;
case 0xE2 : Serial.print(" - Mute"); break;
case 0xE3 : Serial.print(" - Bass"); break;
case 0xE4 : Serial.print(" - Treble"); break;
case 0xE5 : Serial.print(" - Bass Boost"); break;
case 0xE6 : Serial.print(" - Surround Mode"); break;
case 0xE7 : Serial.print(" - Loudness"); break;
case 0xE8 : Serial.print(" - MPX"); break;
case 0xE9 : Serial.print(" - Volume Up"); break;
case 0xEA : Serial.print(" - Volume Down"); break;
case 0xF0 : Serial.print(" - Speed Select"); break;
case 0xF1 : Serial.print(" - Playback Speed"); break;
case 0xF2 : Serial.print(" - Standard Play"); break;
case 0xF3 : Serial.print(" - Long Play"); break;
case 0xF4 : Serial.print(" - Extended Play"); break;
case 0xF5 : Serial.print(" - Slow"); break;
case 0x100: Serial.print(" - Fan Enable"); break;
case 0x101: Serial.print(" - Fan Speed"); break;
case 0x102: Serial.print(" - Light"); break;
case 0x103: Serial.print(" - Light Illumination Level"); break;
case 0x104: Serial.print(" - Climate Control Enable"); break;
case 0x105: Serial.print(" - Room Temperature"); break;
case 0x106: Serial.print(" - Security Enable"); break;
case 0x107: Serial.print(" - Fire Alarm"); break;
case 0x108: Serial.print(" - Police Alarm"); break;
case 0x150: Serial.print(" - Balance Right"); break;
case 0x151: Serial.print(" - Balance Left"); break;
case 0x152: Serial.print(" - Bass Increment"); break;
case 0x153: Serial.print(" - Bass Decrement"); break;
case 0x154: Serial.print(" - Treble Increment"); break;
case 0x155: Serial.print(" - Treble Decrement"); break;
case 0x160: Serial.print(" - Speaker System"); break;
case 0x161: Serial.print(" - Channel Left"); break;
case 0x162: Serial.print(" - Channel Right"); break;
case 0x163: Serial.print(" - Channel Center"); break;
case 0x164: Serial.print(" - Channel Front"); break;
case 0x165: Serial.print(" - Channel Center Front"); break;
case 0x166: Serial.print(" - Channel Side"); break;
case 0x167: Serial.print(" - Channel Surround"); break;
case 0x168: Serial.print(" - Channel Low Frequency Enhancement"); break;
case 0x169: Serial.print(" - Channel Top"); break;
case 0x16A: Serial.print(" - Channel Unknown"); break;
case 0x170: Serial.print(" - Sub-channel"); break;
case 0x171: Serial.print(" - Sub-channel Increment"); break;
case 0x172: Serial.print(" - Sub-channel Decrement"); break;
case 0x173: Serial.print(" - Alternate Audio Increment"); break;
case 0x174: Serial.print(" - Alternate Audio Decrement"); break;
case 0x180: Serial.print(" - Application Launch Buttons"); break;
case 0x181: Serial.print(" - AL Launch Button Configuration Tool"); break;
case 0x182: Serial.print(" - AL Programmable Button Configuration"); break;
case 0x183: Serial.print(" - AL Consumer Control Configuration"); break;
case 0x184: Serial.print(" - AL Word Processor"); break;
case 0x185: Serial.print(" - AL Text Editor"); break;
case 0x186: Serial.print(" - AL Spreadsheet"); break;
case 0x187: Serial.print(" - AL Graphics Editor"); break;
case 0x188: Serial.print(" - AL Presentation App"); break;
case 0x189: Serial.print(" - AL Database App"); break;
case 0x18A: Serial.print(" - AL Email Reader"); break;
case 0x18B: Serial.print(" - AL Newsreader"); break;
case 0x18C: Serial.print(" - AL Voicemail"); break;
case 0x18D: Serial.print(" - AL Contacts/Address Book"); break;
case 0x18E: Serial.print(" - AL Calendar/Schedule"); break;
case 0x18F: Serial.print(" - AL Task/Project Manager"); break;
case 0x190: Serial.print(" - AL Log/Journal/Timecard"); break;
case 0x191: Serial.print(" - AL Checkbook/Finance"); break;
case 0x192: Serial.print(" - AL Calculator"); break;
case 0x193: Serial.print(" - AL A/V Capture/Playback"); break;
case 0x194: Serial.print(" - AL Local Machine Browser"); break;
case 0x195: Serial.print(" - AL LAN/WAN Browser"); break;
case 0x196: Serial.print(" - AL Internet Browser"); break;
case 0x197: Serial.print(" - AL Remote Networking/ISP Connect"); break;
case 0x198: Serial.print(" - AL Network Conference"); break;
case 0x199: Serial.print(" - AL Network Chat"); break;
case 0x19A: Serial.print(" - AL Telephony/Dialer"); break;
case 0x19B: Serial.print(" - AL Logon"); break;
case 0x19C: Serial.print(" - AL Logoff"); break;
case 0x19D: Serial.print(" - AL Logon/Logoff"); break;
case 0x19E: Serial.print(" - AL Terminal Lock/Screensaver"); break;
case 0x19F: Serial.print(" - AL Control Panel"); break;
case 0x1A0: Serial.print(" - AL Command Line Processor/Run"); break;
case 0x1A1: Serial.print(" - AL Process/Task Manager"); break;
case 0x1A2: Serial.print(" - AL Select Tast/Application"); break;
case 0x1A3: Serial.print(" - AL Next Task/Application"); break;
case 0x1A4: Serial.print(" - AL Previous Task/Application"); break;
case 0x1A5: Serial.print(" - AL Preemptive Halt Task/Application"); break;
case 0x200: Serial.print(" - Generic GUI Application Controls"); break;
case 0x201: Serial.print(" - AC New"); break;
case 0x202: Serial.print(" - AC Open"); break;
case 0x203: Serial.print(" - AC Close"); break;
case 0x204: Serial.print(" - AC Exit"); break;
case 0x205: Serial.print(" - AC Maximize"); break;
case 0x206: Serial.print(" - AC Minimize"); break;
case 0x207: Serial.print(" - AC Save"); break;
case 0x208: Serial.print(" - AC Print"); break;
case 0x209: Serial.print(" - AC Properties"); break;
case 0x21A: Serial.print(" - AC Undo"); break;
case 0x21B: Serial.print(" - AC Copy"); break;
case 0x21C: Serial.print(" - AC Cut"); break;
case 0x21D: Serial.print(" - AC Paste"); break;
case 0x21E: Serial.print(" - AC Select All"); break;
case 0x21F: Serial.print(" - AC Find"); break;
case 0x220: Serial.print(" - AC Find and Replace"); break;
case 0x221: Serial.print(" - AC Search"); break;
case 0x222: Serial.print(" - AC Go To"); break;
case 0x223: Serial.print(" - AC Home"); break;
case 0x224: Serial.print(" - AC Back"); break;
case 0x225: Serial.print(" - AC Forward"); break;
case 0x226: Serial.print(" - AC Stop"); break;
case 0x227: Serial.print(" - AC Refresh"); break;
case 0x228: Serial.print(" - AC Previous Link"); break;
case 0x229: Serial.print(" - AC Next Link"); break;
case 0x22A: Serial.print(" - AC Bookmarks"); break;
case 0x22B: Serial.print(" - AC History"); break;
case 0x22C: Serial.print(" - AC Subscriptions"); break;
case 0x22D: Serial.print(" - AC Zoom In"); break;
case 0x22E: Serial.print(" - AC Zoom Out"); break;
case 0x22F: Serial.print(" - AC Zoom"); break;
case 0x230: Serial.print(" - AC Full Screen View"); break;
case 0x231: Serial.print(" - AC Normal View"); break;
case 0x232: Serial.print(" - AC View Toggle"); break;
case 0x233: Serial.print(" - AC Scroll Up"); break;
case 0x234: Serial.print(" - AC Scroll Down"); break;
case 0x235: Serial.print(" - AC Scroll"); break;
case 0x236: Serial.print(" - AC Pan Left"); break;
case 0x237: Serial.print(" - AC Pan Right"); break;
case 0x238: Serial.print(" - AC Pan"); break;
case 0x239: Serial.print(" - AC New Window"); break;
case 0x23A: Serial.print(" - AC Tile Horizontally"); break;
case 0x23B: Serial.print(" - AC Tile Vertically"); break;
case 0x23C: Serial.print(" - AC Format"); break;

}
}
Serial.println();
}

void OnHIDExtrasRelease(uint32_t top, uint16_t key)
{
Serial.print("HID (");
Serial.print(top, HEX);
Serial.print(") key release:");
Serial.println(key, HEX);
}

bool OnReceiveHidData(uint32_t usage, const uint8_t *data, uint32_t len) {
// Called for maybe both HIDS for rawhid basic test. One is for the Teensy
// to output to Serial. while still having Raw Hid...
if (usage == 0xffc90004) {
// Lets trim off trailing null characters.
while ((len > 0) && (data[len - 1] == 0)) {
len--;
}
if (len) {
Serial.print("RawHid Serial: ");
Serial.write(data, len);
}
} else {
Serial.print("RawHID data: ");
Serial.println(usage, HEX);
while (len) {
uint8_t cb = (len > 16) ? 16 : len;
const uint8_t *p = data;
uint8_t i;
for (i = 0; i < cb; i++) {
Serial.printf("%02x ", *p++);
}
Serial.print(": ");
for (i = 0; i < cb; i++) {
Serial.write(((*data >= ' ') && (*data <= '~')) ? *data : '.');
data++;
}
len -= cb;
Serial.println();
}
}

return true;
}

+ 1
- 0
examples/Bluetooth/MouseBT/defs.h View File

@@ -0,0 +1 @@


+ 1776
- 0
examples/Bluetooth/Pacman-Teensy-BT/Pacman-Teensy-BT.ino
File diff suppressed because it is too large
View File


+ 997
- 0
examples/Bluetooth/Pacman-Teensy-BT/PacmanTiles.h
File diff suppressed because it is too large
View File


+ 77
- 0
examples/Bluetooth/Pacman-Teensy-BT/README.md View File

@@ -0,0 +1,77 @@
# Pacman-Arduino-Due / Modified for Teensy 3.6 and T4.x
Pacman Game for Arduino Due with tft ILI9341 and VGA output support

Pacman Game on Arduino Due with ILI9341 and VGA support (available 2 outputs at the same time), playable with keypad, 5 sample levels, VGA output is 240x320, source code avaliable on Github, Licensed under MIT License.

Original Pacman sketch modified to use a Teensy 3.6/T4 with ILI9341_t3n and USBHost_t36 libraries. Intended as demo for the incorporating BT or Serial gamepads such as the PS3 and PS4 into a user application.

Originally posted on:
Arduino Forum:

http://forum.arduino.cc/index.php?topic=375394.0

Video:

https://www.youtube.com/watch?v=2Hdzr6m4QdU



<pre>
/******************************************************************************/
/* */
/* PACMAN GAME FOR TEENSY */
/* */
/******************************************************************************/
/* Copyright (c) 2014 Dr. NCX (mirracle.mxx@gmail.com) */
/* */
/* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL */
/* WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED */
/* WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR */
/* BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES */
/* OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, */
/* WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, */
/* ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS */
/* SOFTWARE. */
/* */
/* MIT license, all text above must be included in any redistribution. */
/******************************************************************************/
/* Original Pacman sketch modified to use a Teensy 3.6/T4 with ILI9341_t3n */
/* and USBHost_t36 libraries. Intended as demo for the incorporating BT */
/* or Serial gamepads such as the PS3 and PS4 into a user application. */
/* The original version for the Arduino Due and SNES controllers can be */
/* found at */
/* https://forum.arduino.cc/index.php?topic=375394.0 */
/* and */
/* https://github.com/DrNCXCortex/Pacman-Arduino-Due */
/* */
/******************************************************************************/
/* ILI9341: */
/*----------------------------------------------------------------------------*/
/* 8 = RST */
/* 9 = D/C */
/* 10 = CS */
/* can be changed at user discretion */
/*----------------------------------------------------------------------------*/

/*----------------------------------------------------------------------------*/
/* KEYPAD: */
/*----------------------------------------------------------------------------*/
/* PS3: button START/Pause */
/* button SELECT */
/* button A/Diamond */
/* button B /Circle */
/* button UP */
/* button DOWN */
/* button LEFT */
/* button RIGHT */
/* */
/* PS4: button START/Pause = Share on PS4 */
/* button SELECT = Options on PS4 */
/* button A/Square */
/* button B /Circle */
/* button UP */
/* button DOWN */
/* button LEFT */
/* button RIGHT */
/* *//******************************************************************************/
</pre>

+ 2933
- 0
examples/Bluetooth/Pacman-Teensy-BT/crntsc.h
File diff suppressed because it is too large
View File


+ 2403
- 0
examples/Bluetooth/Pacman-Teensy-BT/crpal.h
File diff suppressed because it is too large
View File


+ 3082
- 0
examples/Bluetooth/Pacman-Teensy-BT/font8x8.cpp
File diff suppressed because it is too large
View File


BIN
examples/Bluetooth/Pacman-Teensy-BT/icons/apple.png View File

Before After
Width: 16  |  Height: 16  |  Size: 14KB

BIN
examples/Bluetooth/Pacman-Teensy-BT/icons/bell.png View File

Before After
Width: 16  |  Height: 16  |  Size: 337B

BIN
examples/Bluetooth/Pacman-Teensy-BT/icons/cherry.png View File

Before After
Width: 16  |  Height: 16  |  Size: 939B

BIN
examples/Bluetooth/Pacman-Teensy-BT/icons/galaxian.png View File

Before After
Width: 16  |  Height: 16  |  Size: 947B

BIN
examples/Bluetooth/Pacman-Teensy-BT/icons/grape.png View File

Before After
Width: 16  |  Height: 16  |  Size: 619B

BIN
examples/Bluetooth/Pacman-Teensy-BT/icons/key.png View File

Before After
Width: 16  |  Height: 16  |  Size: 913B

BIN
examples/Bluetooth/Pacman-Teensy-BT/icons/peach.png View File

Before After
Width: 16  |  Height: 16  |  Size: 923B

BIN
examples/Bluetooth/Pacman-Teensy-BT/icons/strawberry.png View File

Before After
Width: 16  |  Height: 16  |  Size: 942B

+ 604
- 0
examples/Digitizer/Digitizer.ino View File

@@ -0,0 +1,604 @@
// Simple test of USB Host Mouse/Keyboard
//
// This example is in the public domain

#include "USBHost_t36.h"
int mousex, mousey;

USBHost myusb;
USBHub hub1(myusb);
USBHub hub2(myusb);
KeyboardController keyboard1(myusb);
KeyboardController keyboard2(myusb);
USBHIDParser hid1(myusb);
USBHIDParser hid2(myusb);
USBHIDParser hid3(myusb);
USBHIDParser hid4(myusb);
USBHIDParser hid5(myusb);
DigitizerController digi1(myusb);
JoystickController joystick1(myusb);
//BluetoothController bluet(myusb, true, "0000"); // Version does pairing to device
BluetoothController bluet(myusb); // version assumes it already was paired
int user_axis[64];
uint8_t digi_axis[64];
uint32_t buttons_prev = 0;
//RawHIDController rawhid1(myusb);
RawHIDController rawhid2(myusb, 0xff000080);

USBDriver *drivers[] = {&hub1, &hub2,&keyboard1, &keyboard2, &joystick1, &bluet, &hid1, &hid2, &hid3, &hid4, &hid5};
#define CNT_DEVICES (sizeof(drivers)/sizeof(drivers[0]))
const char * driver_names[CNT_DEVICES] = {"Hub1","Hub2", "KB1", "KB2", "JOY1D", "Bluet", "HID1" , "HID2", "HID3", "HID4", "HID5"};
bool driver_active[CNT_DEVICES] = {false, false, false, false};

// Lets also look at HID Input devices
USBHIDInput *hiddrivers[] = {&digi1, &joystick1, &rawhid2};
#define CNT_HIDDEVICES (sizeof(hiddrivers)/sizeof(hiddrivers[0]))
const char * hid_driver_names[CNT_DEVICES] = {"digi1", "Joystick1", "RawHid2"};
bool hid_driver_active[CNT_DEVICES] = {false, false};
bool show_changed_only = false;

uint8_t joystick_left_trigger_value = 0;
uint8_t joystick_right_trigger_value = 0;
uint64_t joystick_full_notify_mask = (uint64_t) - 1;

void setup()
{
Serial1.begin(2000000);
while (!Serial) ; // wait for Arduino Serial Monitor
Serial.println("\n\nUSB Host Testing");
Serial.println(sizeof(USBHub), DEC);
myusb.begin();
keyboard1.attachPress(OnPress);
keyboard2.attachPress(OnPress);
keyboard1.attachExtrasPress(OnHIDExtrasPress);
keyboard1.attachExtrasRelease(OnHIDExtrasRelease);
keyboard2.attachExtrasPress(OnHIDExtrasPress);
keyboard2.attachExtrasRelease(OnHIDExtrasRelease);

// The below forceBootProtocol will force which ever
// next keyboard that attaches to this device to be in boot protocol
// Only try this if you run into keyboard with issues. If this is a combined
// device like wireless mouse and keyboard this can cause mouse problems.
//keyboard1.forceBootProtocol();
//rawhid1.attachReceive(OnReceiveHidData);
rawhid2.attachReceive(OnReceiveHidData);
}


void loop()
{
myusb.Task();

if (Serial.available()) {
int ch = Serial.read(); // get the first char.
while (Serial.read() != -1) ;
if ((ch == 'b') || (ch == 'B')) {
Serial.println("Only notify on Basic Axis changes");
joystick1.axisChangeNotifyMask(0x3ff);
} else if ((ch == 'f') || (ch == 'F')) {
Serial.println("Only notify on Full Axis changes");
joystick1.axisChangeNotifyMask(joystick_full_notify_mask);

} else {
if (show_changed_only) {
show_changed_only = false;
Serial.println("\n*** Show All fields mode ***");
} else {
show_changed_only = true;
Serial.println("\n*** Show only changed fields mode ***");
}
}
}

for (uint8_t i = 0; i < CNT_DEVICES; i++) {
if (*drivers[i] != driver_active[i]) {
if (driver_active[i]) {
Serial.printf("*** Device %s - disconnected ***\n", driver_names[i]);
driver_active[i] = false;
} else {
Serial.printf("*** Device %s %x:%x - connected ***\n", driver_names[i], drivers[i]->idVendor(), drivers[i]->idProduct());
driver_active[i] = true;

const uint8_t *psz = drivers[i]->manufacturer();
if (psz && *psz) Serial.printf(" manufacturer: %s\n", psz);
psz = drivers[i]->product();
if (psz && *psz) Serial.printf(" product: %s\n", psz);
psz = drivers[i]->serialNumber();
if (psz && *psz) Serial.printf(" Serial: %s\n", psz);

// Note: with some keyboards there is an issue that they don't output in boot protocol mode
// and may not work. The above code can try to force the keyboard into boot mode, but there
// are issues with doing this blindly with combo devices like wireless keyboard/mouse, which
// may cause the mouse to not work. Note: the above id is in the builtin list of
// vendor IDs that are already forced
if (drivers[i] == &keyboard1) {
if (keyboard1.idVendor() == 0x04D9) {
Serial.println("Gigabyte vendor: force boot protocol");
// Gigabyte keyboard
keyboard1.forceBootProtocol();
}
}
}
}
}

for (uint8_t i = 0; i < CNT_HIDDEVICES; i++) {
if (*hiddrivers[i] != hid_driver_active[i]) {
if (hid_driver_active[i]) {
Serial.printf("*** HID Device %s - disconnected ***\n", hid_driver_names[i]);
hid_driver_active[i] = false;
} else {
Serial.printf("*** HID Device %s %x:%x - connected ***\n", hid_driver_names[i], hiddrivers[i]->idVendor(), hiddrivers[i]->idProduct());
hid_driver_active[i] = true;

const uint8_t *psz = hiddrivers[i]->manufacturer();
if (psz && *psz) Serial.printf(" manufacturer: %s\n", psz);
psz = hiddrivers[i]->product();
if (psz && *psz) Serial.printf(" product: %s\n", psz);
psz = hiddrivers[i]->serialNumber();
if (psz && *psz) Serial.printf(" Serial: %s\n", psz);
}
}
}



if (digi1.available()) {
Serial.print("Mouse: buttons = ");
Serial.print(digi1.getButtons());
Serial.print(", mouseX = ");
Serial.print(digi1.getMouseX());
Serial.print(", mouseY = ");
Serial.print(digi1.getMouseY());
Serial.print(", wheel = ");
Serial.print(digi1.getWheel());
Serial.print(", wheelH = ");
Serial.print(digi1.getWheelH());
Serial.println();
digi1.digitizerDataClear();
for (uint8_t i = 0; i<10; i++) {
Serial.printf(" %d:%d", i, digi1.getAxis(i));
}
Serial.println();
}
if (joystick1.available()) {
uint64_t axis_mask = joystick1.axisMask();
uint64_t axis_changed_mask = joystick1.axisChangedMask();
Serial.print("Joystick: buttons = ");
uint32_t buttons = joystick1.getButtons();
Serial.print(buttons, HEX);
//Serial.printf(" AMasks: %x %x:%x", axis_mask, (uint32_t)(user_axis_mask >> 32), (uint32_t)(user_axis_mask & 0xffffffff));
//Serial.printf(" M: %lx %lx", axis_mask, joystick1.axisChangedMask());
if (show_changed_only) {
for (uint8_t i = 0; axis_changed_mask != 0; i++, axis_changed_mask >>= 1) {
if (axis_changed_mask & 1) {
Serial.printf(" %d:%d", i, joystick1.getAxis(i));
}
}

} else {
for (uint8_t i = 0; axis_mask != 0; i++, axis_mask >>= 1) {
if (axis_mask & 1) {
Serial.printf(" %d:%d", i, joystick1.getAxis(i));
}
}
}
uint8_t ltv;
uint8_t rtv;
switch (joystick1.joystickType()) {
default:
break;
case JoystickController::PS4:
ltv = joystick1.getAxis(3);
rtv = joystick1.getAxis(4);
if ((ltv != joystick_left_trigger_value) || (rtv != joystick_right_trigger_value)) {
joystick_left_trigger_value = ltv;
joystick_right_trigger_value = rtv;
joystick1.setRumble(ltv, rtv);
}
break;

case JoystickController::PS3:
ltv = joystick1.getAxis(18);
rtv = joystick1.getAxis(19);
if ((ltv != joystick_left_trigger_value) || (rtv != joystick_right_trigger_value)) {
joystick_left_trigger_value = ltv;
joystick_right_trigger_value = rtv;
joystick1.setRumble(ltv, rtv, 50);
}
break;

case JoystickController::XBOXONE:
case JoystickController::XBOX360:
ltv = joystick1.getAxis(4);
rtv = joystick1.getAxis(5);
if ((ltv != joystick_left_trigger_value) || (rtv != joystick_right_trigger_value)) {
joystick_left_trigger_value = ltv;
joystick_right_trigger_value = rtv;
joystick1.setRumble(ltv, rtv);
Serial.printf(" Set Rumble %d %d", ltv, rtv);
}
break;
}
if (buttons != buttons_prev) {
if (joystick1.joystickType() == JoystickController::PS3) {
joystick1.setLEDs((buttons >> 12) & 0xf); // try to get to TRI/CIR/X/SQuare
} else {
uint8_t lr = (buttons & 1) ? 0xff : 0;
uint8_t lg = (buttons & 2) ? 0xff : 0;
uint8_t lb = (buttons & 4) ? 0xff : 0;
joystick1.setLEDs(lr, lg, lb);
}
buttons_prev = buttons;
}

Serial.println();
joystick1.joystickDataClear();
}

// See if we have some RAW data
/* if (rawhid1) {
int ch;
uint8_t buffer[64];
uint8_t count_chars = 0;
memset(buffer, 0, sizeof(buffer));
if (Serial.available()) {
while (((ch = Serial.read()) != -1) && (count_chars < sizeof(buffer))) {
buffer[count_chars++] = ch;
}
rawhid1.sendPacket(buffer);
}
}
*/
}



void OnPress(int key)
{
Serial.print("key '");
switch (key) {
case KEYD_UP : Serial.print("UP"); break;
case KEYD_DOWN : Serial.print("DN"); break;
case KEYD_LEFT : Serial.print("LEFT"); break;
case KEYD_RIGHT : Serial.print("RIGHT"); break;
case KEYD_INSERT : Serial.print("Ins"); break;
case KEYD_DELETE : Serial.print("Del"); break;
case KEYD_PAGE_UP : Serial.print("PUP"); break;
case KEYD_PAGE_DOWN: Serial.print("PDN"); break;
case KEYD_HOME : Serial.print("HOME"); break;
case KEYD_END : Serial.print("END"); break;
case KEYD_F1 : Serial.print("F1"); break;
case KEYD_F2 : Serial.print("F2"); break;
case KEYD_F3 : Serial.print("F3"); break;
case KEYD_F4 : Serial.print("F4"); break;
case KEYD_F5 : Serial.print("F5"); break;
case KEYD_F6 : Serial.print("F6"); break;
case KEYD_F7 : Serial.print("F7"); break;
case KEYD_F8 : Serial.print("F8"); break;
case KEYD_F9 : Serial.print("F9"); break;
case KEYD_F10 : Serial.print("F10"); break;
case KEYD_F11 : Serial.print("F11"); break;
case KEYD_F12 : Serial.print("F12"); break;
default: Serial.print((char)key); break;
}
Serial.print("' ");
Serial.print(key);
Serial.print(" MOD: ");
if (keyboard1) {
Serial.print(keyboard1.getModifiers(), HEX);
Serial.print(" OEM: ");
Serial.print(keyboard1.getOemKey(), HEX);
Serial.print(" LEDS: ");
Serial.println(keyboard1.LEDS(), HEX);
} else {
Serial.print(keyboard2.getModifiers(), HEX);
Serial.print(" OEM: ");
Serial.print(keyboard2.getOemKey(), HEX);
Serial.print(" LEDS: ");
Serial.println(keyboard2.LEDS(), HEX);
}

//Serial.print("key ");
//Serial.print((char)keyboard1.getKey());
//Serial.print(" ");
//Serial.print((char)keyboard2.getKey());
//Serial.println();
}
void OnHIDExtrasPress(uint32_t top, uint16_t key)
{
Serial.print("HID (");
Serial.print(top, HEX);
Serial.print(") key press:");
Serial.print(key, HEX);
if (top == 0xc0000) {
switch (key) {
case 0x20 : Serial.print(" - +10"); break;
case 0x21 : Serial.print(" - +100"); break;
case 0x22 : Serial.print(" - AM/PM"); break;
case 0x30 : Serial.print(" - Power"); break;
case 0x31 : Serial.print(" - Reset"); break;
case 0x32 : Serial.print(" - Sleep"); break;
case 0x33 : Serial.print(" - Sleep After"); break;
case 0x34 : Serial.print(" - Sleep Mode"); break;
case 0x35 : Serial.print(" - Illumination"); break;
case 0x36 : Serial.print(" - Function Buttons"); break;
case 0x40 : Serial.print(" - Menu"); break;
case 0x41 : Serial.print(" - Menu Pick"); break;
case 0x42 : Serial.print(" - Menu Up"); break;
case 0x43 : Serial.print(" - Menu Down"); break;
case 0x44 : Serial.print(" - Menu Left"); break;
case 0x45 : Serial.print(" - Menu Right"); break;
case 0x46 : Serial.print(" - Menu Escape"); break;
case 0x47 : Serial.print(" - Menu Value Increase"); break;
case 0x48 : Serial.print(" - Menu Value Decrease"); break;
case 0x60 : Serial.print(" - Data On Screen"); break;
case 0x61 : Serial.print(" - Closed Caption"); break;
case 0x62 : Serial.print(" - Closed Caption Select"); break;
case 0x63 : Serial.print(" - VCR/TV"); break;
case 0x64 : Serial.print(" - Broadcast Mode"); break;
case 0x65 : Serial.print(" - Snapshot"); break;
case 0x66 : Serial.print(" - Still"); break;
case 0x80 : Serial.print(" - Selection"); break;
case 0x81 : Serial.print(" - Assign Selection"); break;
case 0x82 : Serial.print(" - Mode Step"); break;
case 0x83 : Serial.print(" - Recall Last"); break;
case 0x84 : Serial.print(" - Enter Channel"); break;
case 0x85 : Serial.print(" - Order Movie"); break;
case 0x86 : Serial.print(" - Channel"); break;
case 0x87 : Serial.print(" - Media Selection"); break;
case 0x88 : Serial.print(" - Media Select Computer"); break;
case 0x89 : Serial.print(" - Media Select TV"); break;
case 0x8A : Serial.print(" - Media Select WWW"); break;
case 0x8B : Serial.print(" - Media Select DVD"); break;
case 0x8C : Serial.print(" - Media Select Telephone"); break;
case 0x8D : Serial.print(" - Media Select Program Guide"); break;
case 0x8E : Serial.print(" - Media Select Video Phone"); break;
case 0x8F : Serial.print(" - Media Select Games"); break;
case 0x90 : Serial.print(" - Media Select Messages"); break;
case 0x91 : Serial.print(" - Media Select CD"); break;
case 0x92 : Serial.print(" - Media Select VCR"); break;
case 0x93 : Serial.print(" - Media Select Tuner"); break;
case 0x94 : Serial.print(" - Quit"); break;
case 0x95 : Serial.print(" - Help"); break;
case 0x96 : Serial.print(" - Media Select Tape"); break;
case 0x97 : Serial.print(" - Media Select Cable"); break;
case 0x98 : Serial.print(" - Media Select Satellite"); break;
case 0x99 : Serial.print(" - Media Select Security"); break;
case 0x9A : Serial.print(" - Media Select Home"); break;
case 0x9B : Serial.print(" - Media Select Call"); break;
case 0x9C : Serial.print(" - Channel Increment"); break;
case 0x9D : Serial.print(" - Channel Decrement"); break;
case 0x9E : Serial.print(" - Media Select SAP"); break;
case 0xA0 : Serial.print(" - VCR Plus"); break;
case 0xA1 : Serial.print(" - Once"); break;
case 0xA2 : Serial.print(" - Daily"); break;
case 0xA3 : Serial.print(" - Weekly"); break;
case 0xA4 : Serial.print(" - Monthly"); break;
case 0xB0 : Serial.print(" - Play"); break;
case 0xB1 : Serial.print(" - Pause"); break;
case 0xB2 : Serial.print(" - Record"); break;
case 0xB3 : Serial.print(" - Fast Forward"); break;
case 0xB4 : Serial.print(" - Rewind"); break;
case 0xB5 : Serial.print(" - Scan Next Track"); break;
case 0xB6 : Serial.print(" - Scan Previous Track"); break;
case 0xB7 : Serial.print(" - Stop"); break;
case 0xB8 : Serial.print(" - Eject"); break;
case 0xB9 : Serial.print(" - Random Play"); break;
case 0xBA : Serial.print(" - Select DisC"); break;
case 0xBB : Serial.print(" - Enter Disc"); break;
case 0xBC : Serial.print(" - Repeat"); break;
case 0xBD : Serial.print(" - Tracking"); break;
case 0xBE : Serial.print(" - Track Normal"); break;
case 0xBF : Serial.print(" - Slow Tracking"); break;
case 0xC0 : Serial.print(" - Frame Forward"); break;
case 0xC1 : Serial.print(" - Frame Back"); break;
case 0xC2 : Serial.print(" - Mark"); break;
case 0xC3 : Serial.print(" - Clear Mark"); break;
case 0xC4 : Serial.print(" - Repeat From Mark"); break;
case 0xC5 : Serial.print(" - Return To Mark"); break;
case 0xC6 : Serial.print(" - Search Mark Forward"); break;
case 0xC7 : Serial.print(" - Search Mark Backwards"); break;
case 0xC8 : Serial.print(" - Counter Reset"); break;
case 0xC9 : Serial.print(" - Show Counter"); break;
case 0xCA : Serial.print(" - Tracking Increment"); break;
case 0xCB : Serial.print(" - Tracking Decrement"); break;
case 0xCD : Serial.print(" - Pause/Continue"); break;
case 0xE0 : Serial.print(" - Volume"); break;
case 0xE1 : Serial.print(" - Balance"); break;
case 0xE2 : Serial.print(" - Mute"); break;
case 0xE3 : Serial.print(" - Bass"); break;
case 0xE4 : Serial.print(" - Treble"); break;
case 0xE5 : Serial.print(" - Bass Boost"); break;
case 0xE6 : Serial.print(" - Surround Mode"); break;
case 0xE7 : Serial.print(" - Loudness"); break;
case 0xE8 : Serial.print(" - MPX"); break;
case 0xE9 : Serial.print(" - Volume Up"); break;
case 0xEA : Serial.print(" - Volume Down"); break;
case 0xF0 : Serial.print(" - Speed Select"); break;
case 0xF1 : Serial.print(" - Playback Speed"); break;
case 0xF2 : Serial.print(" - Standard Play"); break;
case 0xF3 : Serial.print(" - Long Play"); break;
case 0xF4 : Serial.print(" - Extended Play"); break;
case 0xF5 : Serial.print(" - Slow"); break;
case 0x100: Serial.print(" - Fan Enable"); break;
case 0x101: Serial.print(" - Fan Speed"); break;
case 0x102: Serial.print(" - Light"); break;
case 0x103: Serial.print(" - Light Illumination Level"); break;
case 0x104: Serial.print(" - Climate Control Enable"); break;
case 0x105: Serial.print(" - Room Temperature"); break;
case 0x106: Serial.print(" - Security Enable"); break;
case 0x107: Serial.print(" - Fire Alarm"); break;
case 0x108: Serial.print(" - Police Alarm"); break;
case 0x150: Serial.print(" - Balance Right"); break;
case 0x151: Serial.print(" - Balance Left"); break;
case 0x152: Serial.print(" - Bass Increment"); break;
case 0x153: Serial.print(" - Bass Decrement"); break;
case 0x154: Serial.print(" - Treble Increment"); break;
case 0x155: Serial.print(" - Treble Decrement"); break;
case 0x160: Serial.print(" - Speaker System"); break;
case 0x161: Serial.print(" - Channel Left"); break;
case 0x162: Serial.print(" - Channel Right"); break;
case 0x163: Serial.print(" - Channel Center"); break;
case 0x164: Serial.print(" - Channel Front"); break;
case 0x165: Serial.print(" - Channel Center Front"); break;
case 0x166: Serial.print(" - Channel Side"); break;
case 0x167: Serial.print(" - Channel Surround"); break;
case 0x168: Serial.print(" - Channel Low Frequency Enhancement"); break;
case 0x169: Serial.print(" - Channel Top"); break;
case 0x16A: Serial.print(" - Channel Unknown"); break;
case 0x170: Serial.print(" - Sub-channel"); break;
case 0x171: Serial.print(" - Sub-channel Increment"); break;
case 0x172: Serial.print(" - Sub-channel Decrement"); break;
case 0x173: Serial.print(" - Alternate Audio Increment"); break;
case 0x174: Serial.print(" - Alternate Audio Decrement"); break;
case 0x180: Serial.print(" - Application Launch Buttons"); break;
case 0x181: Serial.print(" - AL Launch Button Configuration Tool"); break;
case 0x182: Serial.print(" - AL Programmable Button Configuration"); break;
case 0x183: Serial.print(" - AL Consumer Control Configuration"); break;
case 0x184: Serial.print(" - AL Word Processor"); break;
case 0x185: Serial.print(" - AL Text Editor"); break;
case 0x186: Serial.print(" - AL Spreadsheet"); break;
case 0x187: Serial.print(" - AL Graphics Editor"); break;
case 0x188: Serial.print(" - AL Presentation App"); break;
case 0x189: Serial.print(" - AL Database App"); break;
case 0x18A: Serial.print(" - AL Email Reader"); break;
case 0x18B: Serial.print(" - AL Newsreader"); break;
case 0x18C: Serial.print(" - AL Voicemail"); break;
case 0x18D: Serial.print(" - AL Contacts/Address Book"); break;
case 0x18E: Serial.print(" - AL Calendar/Schedule"); break;
case 0x18F: Serial.print(" - AL Task/Project Manager"); break;
case 0x190: Serial.print(" - AL Log/Journal/Timecard"); break;
case 0x191: Serial.print(" - AL Checkbook/Finance"); break;
case 0x192: Serial.print(" - AL Calculator"); break;
case 0x193: Serial.print(" - AL A/V Capture/Playback"); break;
case 0x194: Serial.print(" - AL Local Machine Browser"); break;
case 0x195: Serial.print(" - AL LAN/WAN Browser"); break;
case 0x196: Serial.print(" - AL Internet Browser"); break;
case 0x197: Serial.print(" - AL Remote Networking/ISP Connect"); break;
case 0x198: Serial.print(" - AL Network Conference"); break;
case 0x199: Serial.print(" - AL Network Chat"); break;
case 0x19A: Serial.print(" - AL Telephony/Dialer"); break;
case 0x19B: Serial.print(" - AL Logon"); break;
case 0x19C: Serial.print(" - AL Logoff"); break;
case 0x19D: Serial.print(" - AL Logon/Logoff"); break;
case 0x19E: Serial.print(" - AL Terminal Lock/Screensaver"); break;
case 0x19F: Serial.print(" - AL Control Panel"); break;
case 0x1A0: Serial.print(" - AL Command Line Processor/Run"); break;
case 0x1A1: Serial.print(" - AL Process/Task Manager"); break;
case 0x1A2: Serial.print(" - AL Select Tast/Application"); break;
case 0x1A3: Serial.print(" - AL Next Task/Application"); break;
case 0x1A4: Serial.print(" - AL Previous Task/Application"); break;
case 0x1A5: Serial.print(" - AL Preemptive Halt Task/Application"); break;
case 0x200: Serial.print(" - Generic GUI Application Controls"); break;
case 0x201: Serial.print(" - AC New"); break;
case 0x202: Serial.print(" - AC Open"); break;
case 0x203: Serial.print(" - AC Close"); break;
case 0x204: Serial.print(" - AC Exit"); break;
case 0x205: Serial.print(" - AC Maximize"); break;
case 0x206: Serial.print(" - AC Minimize"); break;
case 0x207: Serial.print(" - AC Save"); break;
case 0x208: Serial.print(" - AC Print"); break;
case 0x209: Serial.print(" - AC Properties"); break;
case 0x21A: Serial.print(" - AC Undo"); break;
case 0x21B: Serial.print(" - AC Copy"); break;
case 0x21C: Serial.print(" - AC Cut"); break;
case 0x21D: Serial.print(" - AC Paste"); break;
case 0x21E: Serial.print(" - AC Select All"); break;
case 0x21F: Serial.print(" - AC Find"); break;
case 0x220: Serial.print(" - AC Find and Replace"); break;
case 0x221: Serial.print(" - AC Search"); break;
case 0x222: Serial.print(" - AC Go To"); break;
case 0x223: Serial.print(" - AC Home"); break;
case 0x224: Serial.print(" - AC Back"); break;
case 0x225: Serial.print(" - AC Forward"); break;
case 0x226: Serial.print(" - AC Stop"); break;
case 0x227: Serial.print(" - AC Refresh"); break;
case 0x228: Serial.print(" - AC Previous Link"); break;
case 0x229: Serial.print(" - AC Next Link"); break;
case 0x22A: Serial.print(" - AC Bookmarks"); break;
case 0x22B: Serial.print(" - AC History"); break;
case 0x22C: Serial.print(" - AC Subscriptions"); break;
case 0x22D: Serial.print(" - AC Zoom In"); break;
case 0x22E: Serial.print(" - AC Zoom Out"); break;
case 0x22F: Serial.print(" - AC Zoom"); break;
case 0x230: Serial.print(" - AC Full Screen View"); break;
case 0x231: Serial.print(" - AC Normal View"); break;
case 0x232: Serial.print(" - AC View Toggle"); break;
case 0x233: Serial.print(" - AC Scroll Up"); break;
case 0x234: Serial.print(" - AC Scroll Down"); break;
case 0x235: Serial.print(" - AC Scroll"); break;
case 0x236: Serial.print(" - AC Pan Left"); break;
case 0x237: Serial.print(" - AC Pan Right"); break;
case 0x238: Serial.print(" - AC Pan"); break;
case 0x239: Serial.print(" - AC New Window"); break;
case 0x23A: Serial.print(" - AC Tile Horizontally"); break;
case 0x23B: Serial.print(" - AC Tile Vertically"); break;
case 0x23C: Serial.print(" - AC Format"); break;

}
}
Serial.println();
}

void OnHIDExtrasRelease(uint32_t top, uint16_t key)
{
Serial.print("HID (");
Serial.print(top, HEX);
Serial.print(") key release:");
Serial.println(key, HEX);
}

bool OnReceiveHidData(uint32_t usage, const uint8_t *data, uint32_t len) {
// Called for maybe both HIDS for rawhid basic test. One is for the Teensy
// to output to Serial. while still having Raw Hid...
if (usage == 0xffc90004) {
// Lets trim off trailing null characters.
while ((len > 0) && (data[len - 1] == 0)) {
len--;
}
if (len) {
Serial.print("RawHid Serial: ");
Serial.write(data, len);
}
} else {
Serial.print("RawHIDx data: ");
Serial.println(usage, HEX);
uint8_t len1 = len;
for(int j = 0; j < len; j++){
user_axis[j] = data[j];
}
/*
while (len) {
uint8_t cb = (len > 16) ? 16 : len;
const uint8_t *p = data;
uint8_t i;
for (i = 0; i < cb; i++) {
Serial.printf("%02x ", *p++);
}
Serial.print(": ");
for (i = 0; i < cb; i++) {
Serial.write(((*data >= ' ') && (*data <= '~')) ? *data : '.');
data++;
}
len -= cb;
Serial.println();
}
*/
}

for (uint8_t i = 0; i<9; i++) {
Serial.printf(" %d:%d", i, user_axis[i]);
}
Serial.println();
Serial.print("Mouse: buttons = ");
Serial.print(user_axis[3]);
Serial.print(", mouseX = ");
Serial.print(user_axis[4]);
Serial.print(", mouseY = ");
Serial.print(user_axis[5]);
Serial.println();
return true;
}

+ 1
- 0
examples/Digitizer/defs.h View File

@@ -0,0 +1 @@


examples/Joystick/Joystick.ino → examples/Serial/Joystick/Joystick.ino View File

@@ -97,7 +97,7 @@ void loop()
}
uint8_t ltv;
uint8_t rtv;
switch (joysticks[joystick_index].joystickType) {
switch (joysticks[joystick_index].joystickType()) {
default:
break;
case JoystickController::PS4:
@@ -133,7 +133,7 @@ void loop()
break;
}
if (buttons != buttons_prev) {
if (joysticks[joystick_index].joystickType == JoystickController::PS3) {
if (joysticks[joystick_index].joystickType() == JoystickController::PS3) {
joysticks[joystick_index].setLEDs((buttons >> 12) & 0xf); // try to get to TRI/CIR/X/SQuare
} else {
uint8_t lr = (buttons & 1) ? 0xff : 0;

+ 209
- 0
examples/Serial/Joystick/Joystick/Joystick.ino View File

@@ -0,0 +1,209 @@
// Simple test of USB Host Joystick
//
// This example is in the public domain

#include "USBHost_t36.h"

USBHost myusb;
USBHub hub1(myusb);
USBHIDParser hid1(myusb);

#define COUNT_JOYSTICKS 4
JoystickController joysticks[COUNT_JOYSTICKS](myusb);
int user_axis[64];
uint32_t buttons_prev = 0;

USBDriver *drivers[] = {&hub1, &joysticks[0], &joysticks[1], &joysticks[2], &joysticks[3], &hid1};
#define CNT_DEVICES (sizeof(drivers)/sizeof(drivers[0]))
const char * driver_names[CNT_DEVICES] = {"Hub1", "joystick[0D]", "joystick[1D]", "joystick[2D]", "joystick[3D]", "HID1"};
bool driver_active[CNT_DEVICES] = {false, false, false, false};

// Lets also look at HID Input devices
USBHIDInput *hiddrivers[] = {&joysticks[0], &joysticks[1], &joysticks[2], &joysticks[3]};
#define CNT_HIDDEVICES (sizeof(hiddrivers)/sizeof(hiddrivers[0]))
const char * hid_driver_names[CNT_DEVICES] = {"joystick[0H]", "joystick[1H]", "joystick[2H]", "joystick[3H]"};
bool hid_driver_active[CNT_DEVICES] = {false};
bool show_changed_only = false;

uint8_t joystick_left_trigger_value[COUNT_JOYSTICKS] = {0};
uint8_t joystick_right_trigger_value[COUNT_JOYSTICKS] = {0};
uint64_t joystick_full_notify_mask = (uint64_t) - 1;

int psAxis[64];


//=============================================================================
// Setup
//=============================================================================
void setup()
{
Serial1.begin(2000000);
while (!Serial) ; // wait for Arduino Serial Monitor
Serial.println("\n\nUSB Host Joystick Testing");
myusb.begin();
}


//=============================================================================
// loop
//=============================================================================
void loop()
{
myusb.Task();
PrintDeviceListChanges();

if (Serial.available()) {
int ch = Serial.read(); // get the first char.
while (Serial.read() != -1) ;
if ((ch == 'b') || (ch == 'B')) {
Serial.println("Only notify on Basic Axis changes");
for (int joystick_index = 0; joystick_index < COUNT_JOYSTICKS; joystick_index++)
joysticks[joystick_index].axisChangeNotifyMask(0x3ff);
} else if ((ch == 'f') || (ch == 'F')) {
Serial.println("Only notify on Full Axis changes");
for (int joystick_index = 0; joystick_index < COUNT_JOYSTICKS; joystick_index++)
joysticks[joystick_index].axisChangeNotifyMask(joystick_full_notify_mask);

} else {
if (show_changed_only) {
show_changed_only = false;
Serial.println("\n*** Show All fields mode ***");
} else {
show_changed_only = true;
Serial.println("\n*** Show only changed fields mode ***");
}
}
}

for (int joystick_index = 0; joystick_index < COUNT_JOYSTICKS; joystick_index++) {
if (joysticks[joystick_index].available()) {
uint64_t axis_mask = joysticks[joystick_index].axisMask();
uint64_t axis_changed_mask = joysticks[joystick_index].axisChangedMask();
uint32_t buttons = joysticks[joystick_index].getButtons();
Serial.printf("Joystick(%d): buttons = %x", joystick_index, buttons);
//Serial.printf(" AMasks: %x %x:%x", axis_mask, (uint32_t)(user_axis_mask >> 32), (uint32_t)(user_axis_mask & 0xffffffff));
//Serial.printf(" M: %lx %lx", axis_mask, joysticks[joystick_index].axisChangedMask());
if (show_changed_only) {
for (uint8_t i = 0; axis_changed_mask != 0; i++, axis_changed_mask >>= 1) {
if (axis_changed_mask & 1) {
Serial.printf(" %d:%d", i, joysticks[joystick_index].getAxis(i));
}
}

} else {
for (uint8_t i = 0; axis_mask != 0; i++, axis_mask >>= 1) {
if (axis_mask & 1) {
Serial.printf(" %d:%d", i, joysticks[joystick_index].getAxis(i));
}
}
}
uint8_t ltv;
uint8_t rtv;

for (uint8_t i = 0; i<64; i++) {
psAxis[i] = joysticks[joystick_index].getAxis(i);
}
switch (joysticks[joystick_index].joystickType()) {
default:
break;
case JoystickController::PS4:
printAngles();
ltv = joysticks[joystick_index].getAxis(3);
rtv = joysticks[joystick_index].getAxis(4);
if ((ltv != joystick_left_trigger_value[joystick_index]) || (rtv != joystick_right_trigger_value[joystick_index])) {
joystick_left_trigger_value[joystick_index] = ltv;
joystick_right_trigger_value[joystick_index] = rtv;
joysticks[joystick_index].setRumble(ltv, rtv);
}
break;

case JoystickController::PS3:
ltv = joysticks[joystick_index].getAxis(18);
rtv = joysticks[joystick_index].getAxis(19);
if ((ltv != joystick_left_trigger_value[joystick_index]) || (rtv != joystick_right_trigger_value[joystick_index])) {
joystick_left_trigger_value[joystick_index] = ltv;
joystick_right_trigger_value[joystick_index] = rtv;
joysticks[joystick_index].setRumble(ltv, rtv,50);
}
break;

case JoystickController::XBOXONE:
case JoystickController::XBOX360:
ltv = joysticks[joystick_index].getAxis(3);
rtv = joysticks[joystick_index].getAxis(4);
if ((ltv != joystick_left_trigger_value[joystick_index]) || (rtv != joystick_right_trigger_value[joystick_index])) {
joystick_left_trigger_value[joystick_index] = ltv;
joystick_right_trigger_value[joystick_index] = rtv;
joysticks[joystick_index].setRumble(ltv, rtv,50);
Serial.printf(" Set Rumble %d %d", ltv, rtv);
}
break;
}
if (buttons != buttons_prev) {
if (joysticks[joystick_index].joystickType() == JoystickController::PS3) {
//joysticks[joystick_index].setLEDs((buttons >> 12) & 0xf); // try to get to TRI/CIR/X/SQuare
uint8_t leds = 0;
if (buttons & 0x8000) leds = 1; //Srq
if (buttons & 0x2000) leds = 2; //Cir
if (buttons & 0x1000) leds = 4; //Tri
if (buttons & 0x4000) leds = 8; //X //Tri
joysticks[joystick_index].setLEDs(leds);
} else {
uint8_t lr = (buttons & 1) ? 0xff : 0;
uint8_t lg = (buttons & 2) ? 0xff : 0;
uint8_t lb = (buttons & 4) ? 0xff : 0;
joysticks[joystick_index].setLEDs(lr, lg, lb);
}
buttons_prev = buttons;
}

Serial.println();
joysticks[joystick_index].joystickDataClear();
}
}

}

//=============================================================================
// Show when devices are added or removed
//=============================================================================
void PrintDeviceListChanges() {
for (uint8_t i = 0; i < CNT_DEVICES; i++) {
if (*drivers[i] != driver_active[i]) {
if (driver_active[i]) {
Serial.printf("*** Device %s - disconnected ***\n", driver_names[i]);
driver_active[i] = false;
} else {
Serial.printf("*** Device %s %x:%x - connected ***\n", driver_names[i], drivers[i]->idVendor(), drivers[i]->idProduct());
driver_active[i] = true;

const uint8_t *psz = drivers[i]->manufacturer();
if (psz && *psz) Serial.printf(" manufacturer: %s\n", psz);
psz = drivers[i]->product();
if (psz && *psz) Serial.printf(" product: %s\n", psz);
psz = drivers[i]->serialNumber();
if (psz && *psz) Serial.printf(" Serial: %s\n", psz);
}
}
}

for (uint8_t i = 0; i < CNT_HIDDEVICES; i++) {
if (*hiddrivers[i] != hid_driver_active[i]) {
if (hid_driver_active[i]) {
Serial.printf("*** HID Device %s - disconnected ***\n", hid_driver_names[i]);
hid_driver_active[i] = false;
} else {
Serial.printf("*** HID Device %s %x:%x - connected ***\n", hid_driver_names[i], hiddrivers[i]->idVendor(), hiddrivers[i]->idProduct());
hid_driver_active[i] = true;

const uint8_t *psz = hiddrivers[i]->manufacturer();
if (psz && *psz) Serial.printf(" manufacturer: %s\n", psz);
psz = hiddrivers[i]->product();
if (psz && *psz) Serial.printf(" product: %s\n", psz);
psz = hiddrivers[i]->serialNumber();
if (psz && *psz) Serial.printf(" Serial: %s\n", psz);
}
}
}
}

+ 65
- 0
examples/Serial/Joystick/Joystick/ps4Helpers.ino View File

@@ -0,0 +1,65 @@
float gx, gy, gz;
float ax, ay, az;
float pitch, roll;
uint16_t xc, yc;
uint8_t isTouch;
int16_t xc_old, yc_old;

void printAngles(){
//test function calls
float gx, gy, gz;
getAccel(ax, ay, az);
Serial.printf("Accel-g's: %f, %f, %f\n", ax, ay, az);
getGyro(gx, gy, gz);
Serial.printf("Gyro-deg/sec: %f, %f, %f\n", gx, gy, gz);

getAngles(pitch, roll);
Serial.printf("Pitch/Roll: %f, %f\n", pitch, roll);

getCoords(xc, yc, isTouch);
}

void getCoords(uint16_t &xc, uint16_t &yc, uint8_t &isTouch){

//uint8_t finger = 0; //only getting finger 1
uint8_t Id = 0;


// Trackpad touch 1: id, active, x, y
xc = ((psAxis[37] & 0x0f) << 8) | psAxis[36];
yc = psAxis[38] << 4 | ((psAxis[37] & 0xf0) >> 4),

isTouch = psAxis[35] >> 7;
if(xc != xc_old || yc != yc_old){
Serial.printf("Touch: %d, %d, %d, %d\n", psAxis[33], isTouch, xc, yc);
xc_old = xc;
yc_old = yc;
}
}

void getAccel( float &ax, float &ay, float &az){
int accelx = (int16_t)(psAxis[20]<<8) | psAxis[19];
int accelz = (int16_t)(psAxis[22]<<8) | psAxis[21];
int accely = (int16_t)(psAxis[24]<<8) | psAxis[23];
ax = (float) accelx/8192;
ay = (float) accely/8192;
az = (float) accelz/8192;
}

void getAngles(float &p, float &r){
getAccel( ax, ay, az);
p = (atan2f(ay, az) + PI) * RAD_TO_DEG;
r = (atan2f(ax, az) + PI) * RAD_TO_DEG;
}

void getGyro(float &gx, float &gy, float &gz){
int gyroy = (int16_t)(psAxis[14]<<8) | psAxis[13];
int gyroz = (int16_t)(psAxis[16]<<8) | psAxis[15];
int gyrox = (int16_t)(psAxis[18]<<8) | psAxis[17];

gx = (float) gyrox * RAD_TO_DEG/1024;
gy = (float) gyroy * RAD_TO_DEG/1024;
gz = (float) gyroz * RAD_TO_DEG/1024;
}

examples/MIDI/InputFunctions/InputFunctions.ino → examples/Serial/MIDI/InputFunctions/InputFunctions.ino View File


examples/MIDI/Interface_16x16/Interface_16x16.ino → examples/Serial/MIDI/Interface_16x16/Interface_16x16.ino View File


examples/Mouse/Mouse.ino → examples/Serial/Mouse/Mouse.ino View File

@@ -16,14 +16,16 @@ USBHIDParser hid4(myusb);
USBHIDParser hid5(myusb);
MouseController mouse1(myusb);
JoystickController joystick1(myusb);
//BluetoothController bluet(myusb, true, "0000"); // Version does pairing to device
BluetoothController bluet(myusb); // version assumes it already was paired
int user_axis[64];
uint32_t buttons_prev = 0;
RawHIDController rawhid1(myusb);
RawHIDController rawhid2(myusb, 0xffc90004);

USBDriver *drivers[] = {&hub1, &hub2, &keyboard1, &keyboard2, &joystick1, &hid1, &hid2, &hid3, &hid4, &hid5};
USBDriver *drivers[] = {&hub1, &hub2,&keyboard1, &keyboard2, &joystick1, &bluet, &hid1, &hid2, &hid3, &hid4, &hid5};
#define CNT_DEVICES (sizeof(drivers)/sizeof(drivers[0]))
const char * driver_names[CNT_DEVICES] = {"Hub1", "Hub2", "KB1", "KB2", "JOY1D", "HID1", "HID2", "HID3", "HID4", "HID5"};
const char * driver_names[CNT_DEVICES] = {"Hub1","Hub2", "KB1", "KB2", "JOY1D", "Bluet", "HID1" , "HID2", "HID3", "HID4", "HID5"};
bool driver_active[CNT_DEVICES] = {false, false, false, false};

// Lets also look at HID Input devices
@@ -176,7 +178,7 @@ void loop()
}
uint8_t ltv;
uint8_t rtv;
switch (joystick1.joystickType) {
switch (joystick1.joystickType()) {
default:
break;
case JoystickController::PS4:
@@ -212,7 +214,7 @@ void loop()
break;
}
if (buttons != buttons_prev) {
if (joystick1.joystickType == JoystickController::PS3) {
if (joystick1.joystickType() == JoystickController::PS3) {
joystick1.setLEDs((buttons >> 12) & 0xf); // try to get to TRI/CIR/X/SQuare
} else {
uint8_t lr = (buttons & 1) ? 0xff : 0;

examples/Mouse/defs.h → examples/Serial/Mouse/defs.h View File


examples/SerialTest/SerialTest.ino → examples/Test/SerialTest/SerialTest.ino View File


examples/SerialTest/defs.h → examples/Test/SerialTest/defs.h View File


examples/Test/Test.ino → examples/Test/Test/Test.ino View File


+ 970
- 0
examples/USBHost_viewer/USBHost_viewer.ino View File

@@ -0,0 +1,970 @@
//=============================================================================
// Simple test viewer app for several of the USB devices on ili9341 display
//
// Currently requires the libraries
// ili9341_t3n that can be located: https://github.com/KurtE/ILI9341_t3n
// spin: https://github.com/KurtE/SPIN
//
// Teensy 3.6 Pins
// 8 = RST
// 9 = D/C
// 10 = CS
//
// Teensy 4.0 Beta Pins
// 23 = RST (Marked MCLK on T4 beta breakout)
// 10 = CS (Marked CS)
// 9 = DC (Marked MEMCS)
//
// This example is in the public domain
//=============================================================================

#include "USBHost_t36.h"
#include <ili9341_t3n_font_Arial.h>
#define TEENSY64

//=============================================================================
// Connection configuration of ILI9341 LCD TFT
//=============================================================================
DMAMEM uint16_t frame_buffer[ILI9341_TFTWIDTH * ILI9341_TFTHEIGHT];
#if defined(__MK66FX1M0__) && !defined(TEENSY64)
#define TFT_RST 255
#define TFT_DC 20
#define TFT_CS 21
ILI9341_t3n tft = ILI9341_t3n(TFT_CS, TFT_DC, TFT_RST);
#elif defined(__IMXRT1052__) || defined(__IMXRT1062__)
// On Teensy 4 beta with Paul's breakout out:
// Using pins (MOSI, MISO, SCK which are labeled on Audio board breakout location
// which are not in the Normal processor positions
// Also DC=10(CS), CS=9(BCLK) and RST 23(MCLK)
#define TFT_RST 23
#define TFT_DC 9
#define TFT_CS 10
ILI9341_t3n tft = ILI9341_t3n(TFT_CS, TFT_DC, TFT_RST);
#elif defined(TEENSY64)
#define TFT_RST 255
#define TFT_DC 20
#define TFT_CS 21
#define TFT_SCK 14
#define TFT_MISO 39
#define TFT_MOSI 28
ILI9341_t3n tft = ILI9341_t3n(TFT_CS, TFT_DC, TFT_RST, TFT_MOSI, TFT_SCK, TFT_MISO);
#else
#error "This example App will only work with Teensy 3.6 or Teensy 4."
#endif

//=============================================================================
// USB Host Ojbects
//=============================================================================
USBHost myusb;
USBHub hub1(myusb);
USBHub hub2(myusb);
KeyboardController keyboard1(myusb);
KeyboardController keyboard2(myusb);
USBHIDParser hid1(myusb);
USBHIDParser hid2(myusb);
USBHIDParser hid3(myusb);
USBHIDParser hid4(myusb);
USBHIDParser hid5(myusb);
MouseController mouse(myusb);
DigitizerController tablet(myusb);
JoystickController joystick(myusb);
BluetoothController bluet(myusb, true, "0000"); // Version does pairing to device
//BluetoothController bluet(myusb); // version assumes it already was paired
RawHIDController rawhid2(myusb);

// Lets only include in the lists The most top level type devices we wish to show information for.
//USBDriver *drivers[] = {&keyboard1, &keyboard2, &joystick};
USBDriver *drivers[] = {&keyboard1, &keyboard2, &joystick, &bluet, &hid1, &hid2};

#define CNT_DEVICES (sizeof(drivers)/sizeof(drivers[0]))
//const char * driver_names[CNT_DEVICES] = {"KB1", "KB2", "Joystick(device)"};
const char * driver_names[CNT_DEVICES] = {"KB1", "KB2", "Joystick(device)", "Bluet", "HID1" , "HID2"};
//bool driver_active[CNT_DEVICES] = {false, false, false};
bool driver_active[CNT_DEVICES] = {false, false, false, false, false};

// Lets also look at HID Input devices
USBHIDInput *hiddrivers[] = {&tablet, &joystick, &mouse, &rawhid2};
#define CNT_HIDDEVICES (sizeof(hiddrivers)/sizeof(hiddrivers[0]))
const char * hid_driver_names[CNT_HIDDEVICES] = {"tablet", "joystick", "mouse", "RawHid2"};

bool hid_driver_active[CNT_HIDDEVICES] = {false, false, false, false};

BTHIDInput *bthiddrivers[] = {&joystick, &mouse};
#define CNT_BTHIDDEVICES (sizeof(bthiddrivers)/sizeof(bthiddrivers[0]))
const char * bthid_driver_names[CNT_HIDDEVICES] = {"joystick", "mouse"};
bool bthid_driver_active[CNT_HIDDEVICES] = {false, false};

//=============================================================================
// Other state variables.
//=============================================================================

// Save away values for buttons, x, y, wheel, wheelh
int buttons_cur = 0;
int x_cur = 0,
y_cur = 0,
z_cur = 0;
int x2_cur = 0,
y2_cur = 0,
z2_cur = 0,
L1_cur = 0,
R1_cur = 0;
int wheel_cur = 0;
int wheelH_cur = 0;
int axis_cur[10];

String p = "KB1";
bool BT = 0;

int user_axis[64];
uint32_t buttons_prev = 0;
uint32_t buttons;

bool show_changed_only = false;
bool new_device_detected = false;
int16_t y_position_after_device_info = 0;

uint8_t joystick_left_trigger_value = 0;
uint8_t joystick_right_trigger_value = 0;
uint64_t joystick_full_notify_mask = (uint64_t) - 1;

//=============================================================================
// Setup
//=============================================================================
void setup()
{
Serial1.begin(2000000);
while (!Serial && millis() < 3000) ; // wait for Arduino Serial Monitor
Serial.println("\n\nUSB Host Testing");
myusb.begin();
rawhid2.attachReceive(OnReceiveHidData);
keyboard1.attachPress(OnPress);
keyboard2.attachPress(OnPress);
keyboard1.attachExtrasPress(OnHIDExtrasPress);
keyboard1.attachExtrasRelease(OnHIDExtrasRelease);
keyboard2.attachExtrasPress(OnHIDExtrasPress);
keyboard2.attachExtrasRelease(OnHIDExtrasRelease);

// The below forceBootProtocol will force which ever
// next keyboard that attaches to this device to be in boot protocol
// Only try this if you run into keyboard with issues. If this is a combined
// device like wireless mouse and keyboard this can cause mouse problems.
//keyboard1.forceBootProtocol();

tft.begin();
// explicitly set the frame buffer
tft.setFrameBuffer(frame_buffer);
delay(100);
tft.setRotation(3); // 180
delay(100);

tft.fillScreen(ILI9341_BLACK);
tft.setTextColor(ILI9341_YELLOW);
tft.setTextSize(2);
tft.println("Waiting for Device...");
tft.useFrameBuffer(true);
}


//=============================================================================
// Loop
//=============================================================================
void loop()
{
myusb.Task();

// Update the display with
UpdateActiveDeviceInfo();

// Now lets try displaying Tablet data
ProcessTabletData();

// And joystick data
ProcessJoystickData();

// Process Mouse Data
ProcessMouseData();
}


//=============================================================================
// UpdateActiveDeviceInfo
//=============================================================================
//=============================================================================
// UpdateActiveDeviceInfo
//=============================================================================
void UpdateActiveDeviceInfo() {
// First see if any high level devices
for (uint8_t i = 0; i < CNT_DEVICES; i++) {
if (*drivers[i] != driver_active[i]) {
if (driver_active[i]) {
Serial.printf("*** Device %s - disconnected ***\n", driver_names[i]);
driver_active[i] = false;
} else {
new_device_detected = true;
Serial.printf("*** Device %s %x:%x - connected ***\n", driver_names[i], drivers[i]->idVendor(), drivers[i]->idProduct());
driver_active[i] = true;
tft.fillScreen(ILI9341_BLACK); // clear the screen.
tft.setCursor(0, 0);
tft.setTextColor(ILI9341_YELLOW);
tft.setFont(Arial_12);
tft.printf("Device %s %x:%x\n", driver_names[i], drivers[i]->idVendor(), drivers[i]->idProduct());

const uint8_t *psz = drivers[i]->manufacturer();
if (psz && *psz) tft.printf(" manufacturer: %s\n", psz);
psz = drivers[i]->product();
if (psz && *psz) tft.printf(" product: %s\n", psz);
psz = drivers[i]->serialNumber();
if (psz && *psz) tft.printf(" Serial: %s\n", psz);
tft.updateScreen(); // update the screen now
}
}
}
// Then Hid Devices
for (uint8_t i = 0; i < CNT_HIDDEVICES; i++) {
if (*hiddrivers[i] != hid_driver_active[i]) {
if (hid_driver_active[i]) {
Serial.printf("*** HID Device %s - disconnected ***\n", hid_driver_names[i]);
hid_driver_active[i] = false;
} else {
new_device_detected = true;
Serial.printf("*** HID Device %s %x:%x - connected ***\n", hid_driver_names[i], hiddrivers[i]->idVendor(), hiddrivers[i]->idProduct());
hid_driver_active[i] = true;
tft.fillScreen(ILI9341_BLACK); // clear the screen.
tft.setCursor(0, 0);
tft.setTextColor(ILI9341_YELLOW);
tft.setFont(Arial_12);
tft.printf("HID Device %s %x:%x\n", hid_driver_names[i], hiddrivers[i]->idVendor(), hiddrivers[i]->idProduct());

const uint8_t *psz = hiddrivers[i]->manufacturer();
if (psz && *psz) tft.printf(" manufacturer: %s\n", psz);
psz = hiddrivers[i]->product();
if (psz && *psz) tft.printf(" product: %s\n", psz);
psz = hiddrivers[i]->serialNumber();
if (psz && *psz) tft.printf(" Serial: %s\n", psz);
tft.updateScreen(); // update the screen now
}
}
}

// Then Bluetooth devices
for (uint8_t i = 0; i < CNT_BTHIDDEVICES; i++) {
if (*bthiddrivers[i] != bthid_driver_active[i]) {
if (bthid_driver_active[i]) {
Serial.printf("*** BTHID Device %s - disconnected ***\n", hid_driver_names[i]);
bthid_driver_active[i] = false;
} else {
new_device_detected = true;
Serial.printf("*** BTHID Device %s %x:%x - connected ***\n", hid_driver_names[i], hiddrivers[i]->idVendor(), hiddrivers[i]->idProduct());
bthid_driver_active[i] = true;
tft.fillScreen(ILI9341_BLACK); // clear the screen.
tft.setCursor(0, 0);
tft.setTextColor(ILI9341_YELLOW);
tft.setFont(Arial_12);
tft.printf("Bluetooth Device %s %x:%x\n", bthid_driver_names[i], bthiddrivers[i]->idVendor(), bthiddrivers[i]->idProduct());

const uint8_t *psz = bthiddrivers[i]->manufacturer();
if (psz && *psz) tft.printf(" manufacturer: %s\n", psz);
psz = bthiddrivers[i]->product();
if (psz && *psz) tft.printf(" product: %s\n", psz);
psz = bthiddrivers[i]->serialNumber();
if (psz && *psz) tft.printf(" Serial: %s\n", psz);
tft.updateScreen(); // update the screen now
}
}
}
}

//=============================================================================
// ProcessTabletData
//=============================================================================
void ProcessTabletData() {
if (tablet.available()) {
if (new_device_detected) {
// Lets display the titles.
int16_t x;
tft.getCursor(&x, &y_position_after_device_info);
tft.setTextColor(ILI9341_YELLOW);
tft.printf("Buttons:\nX:\nY:\nWheel:\nWheel H:\nAxis:");
new_device_detected = false;
}
bool something_changed = false;
if (tablet.getButtons() != buttons_cur) {
buttons_cur = tablet.getButtons();
something_changed = true;
}
if (tablet.getMouseX() != x_cur) {
x_cur = tablet.getMouseX();
something_changed = true;
}
if (tablet.getMouseY() != y_cur) {
y_cur = tablet.getMouseY();
something_changed = true;
}
if (tablet.getWheel() != wheel_cur) {
wheel_cur = tablet.getWheel();
something_changed = true;
}
if (tablet.getWheelH() != wheelH_cur) {
wheelH_cur = tablet.getWheelH();
something_changed = true;
}
// BUGBUG:: play with some Axis...
for (uint8_t i = 0; i < 10; i++) {
int axis = tablet.getAxis(i);
if (axis != axis_cur[i]) {
axis_cur[i] = axis;
something_changed = true;
}
}

if (something_changed) {
#define TABLET_DATA_X 100
int16_t x, y2;
unsigned char line_space = Arial_12.line_space;
tft.setTextColor(ILI9341_WHITE, ILI9341_BLACK);
//tft.setTextDatum(BR_DATUM);
int16_t y = y_position_after_device_info;
tft.setCursor(TABLET_DATA_X, y);
tft.printf("%d(%x)", buttons_cur, buttons_cur);
tft.getCursor(&x, &y2);
tft.fillRect(x, y, 320, line_space, ILI9341_BLACK);

y += line_space; OutputNumberField(TABLET_DATA_X, y, x_cur, 320);
y += line_space; OutputNumberField(TABLET_DATA_X, y, y_cur, 320);
y += line_space; OutputNumberField(TABLET_DATA_X, y, wheel_cur, 320);
y += line_space; OutputNumberField(TABLET_DATA_X, y, wheelH_cur, 320);

// Output other Axis data
for (uint8_t i = 0; i < 9; i += 3) {
y += line_space;
OutputNumberField(TABLET_DATA_X, y, axis_cur[i], 75);
OutputNumberField(TABLET_DATA_X + 75, y, axis_cur[i + 1], 75);
OutputNumberField(TABLET_DATA_X + 150, y, axis_cur[i + 2], 75);
}
tft.updateScreen(); // update the screen now

}
tablet.digitizerDataClear();
}
}
//=============================================================================
// OutputNumberField
//=============================================================================
void OutputNumberField(int16_t x, int16_t y, int val, int16_t field_width) {
int16_t x2, y2;
tft.setCursor(x, y);
tft.print(val, DEC); tft.getCursor(&x2, &y2);
tft.fillRect(x2, y, field_width - (x2 - x), Arial_12.line_space, ILI9341_BLACK);
}

//=============================================================================
// ProcessMouseData
//=============================================================================
void ProcessMouseData() {
if (mouse.available()) {
if (new_device_detected) {
// Lets display the titles.
int16_t x;
tft.getCursor(&x, &y_position_after_device_info);
tft.setTextColor(ILI9341_YELLOW);
tft.printf("Buttons:\nX:\nY:\nWheel:\nWheel H:");
new_device_detected = false;
}

bool something_changed = false;
if (mouse.getButtons() != buttons_cur) {
buttons_cur = mouse.getButtons();
something_changed = true;
}
if (mouse.getMouseX() != x_cur) {
x_cur = mouse.getMouseX();
something_changed = true;
}
if (mouse.getMouseY() != y_cur) {
y_cur = mouse.getMouseY();
something_changed = true;
}
if (mouse.getWheel() != wheel_cur) {
wheel_cur = mouse.getWheel();
something_changed = true;
}
if (mouse.getWheelH() != wheelH_cur) {
wheelH_cur = mouse.getWheelH();
something_changed = true;
}
if (something_changed) {
#define MOUSE_DATA_X 100
int16_t x, y2;
unsigned char line_space = Arial_12.line_space;
tft.setTextColor(ILI9341_WHITE, ILI9341_BLACK);
//tft.setTextDatum(BR_DATUM);
int16_t y = y_position_after_device_info;
tft.setCursor(TABLET_DATA_X, y);
tft.printf("%d(%x)", buttons_cur, buttons_cur);
tft.getCursor(&x, &y2);
tft.fillRect(x, y, 320, line_space, ILI9341_BLACK);

y += line_space; OutputNumberField(MOUSE_DATA_X, y, x_cur, 320);
y += line_space; OutputNumberField(MOUSE_DATA_X, y, y_cur, 320);
y += line_space; OutputNumberField(MOUSE_DATA_X, y, wheel_cur, 320);
y += line_space; OutputNumberField(MOUSE_DATA_X, y, wheelH_cur, 320);
tft.updateScreen(); // update the screen now
}

mouse.mouseDataClear();
}
}

//=============================================================================
// ProcessJoystickData
//=============================================================================
void ProcessJoystickData() {
if (joystick.available()) {
uint64_t axis_mask = joystick.axisMask();
uint64_t axis_changed_mask = joystick.axisChangedMask();
Serial.print("Joystick: buttons = ");
buttons = joystick.getButtons();
Serial.print(buttons, HEX);
//Serial.printf(" AMasks: %x %x:%x", axis_mask, (uint32_t)(user_axis_mask >> 32), (uint32_t)(user_axis_mask & 0xffffffff));
//Serial.printf(" M: %lx %lx", axis_mask, joystick.axisChangedMask());
if (show_changed_only) {
for (uint8_t i = 0; axis_changed_mask != 0; i++, axis_changed_mask >>= 1) {
if (axis_changed_mask & 1) {
Serial.printf(" %d:%d", i, joystick.getAxis(i));
}
}
} else {
for (uint8_t i = 0; axis_mask != 0; i++, axis_mask >>= 1) {
if (axis_mask & 1) {
Serial.printf(" %d:%d", i, joystick.getAxis(i));
}
}
}
for (uint8_t i = 0; i < 64; i++) {
user_axis[i] = joystick.getAxis(i);
}
uint8_t ltv;
uint8_t rtv;
switch (joystick.joystickType()) {
default:
break;
case JoystickController::PS4:
ltv = joystick.getAxis(3);
rtv = joystick.getAxis(4);
if ((ltv != joystick_left_trigger_value) || (rtv != joystick_right_trigger_value)) {
joystick_left_trigger_value = ltv;
joystick_right_trigger_value = rtv;
joystick.setRumble(ltv, rtv);
}
break;

case JoystickController::PS3:
ltv = joystick.getAxis(18);
rtv = joystick.getAxis(19);
if ((ltv != joystick_left_trigger_value) || (rtv != joystick_right_trigger_value)) {
joystick_left_trigger_value = ltv;
joystick_right_trigger_value = rtv;
joystick.setRumble(ltv, rtv, 50);
}
break;

case JoystickController::XBOXONE:
case JoystickController::XBOX360:
ltv = joystick.getAxis(4);
rtv = joystick.getAxis(5);
if ((ltv != joystick_left_trigger_value) || (rtv != joystick_right_trigger_value)) {
joystick_left_trigger_value = ltv;
joystick_right_trigger_value = rtv;
joystick.setRumble(ltv, rtv);
Serial.printf(" Set Rumble %d %d", ltv, rtv);
}
break;
}
if (buttons != buttons_cur) {
if (joystick.joystickType() == JoystickController::PS3) {
joystick.setLEDs((buttons >> 12) & 0xf); // try to get to TRI/CIR/X/SQuare
} else {
uint8_t lr = (buttons & 1) ? 0xff : 0;
uint8_t lg = (buttons & 2) ? 0xff : 0;
uint8_t lb = (buttons & 4) ? 0xff : 0;
joystick.setLEDs(lr, lg, lb);
}
buttons_cur = buttons;
}
Serial.println();
tft_JoystickData();
joystick.joystickDataClear();
}
}


//=============================================================================
// TFT_joystick
//=============================================================================
void tft_JoystickData() {
if (new_device_detected) {
// Lets display the titles.
int16_t x;
tft.getCursor(&x, &y_position_after_device_info);
tft.setTextColor(ILI9341_YELLOW);
tft.printf("Buttons:\nX:\nY:\nX2\nY2(Z):\nL1:\nR1:\nHAT:");
new_device_detected = false;
}

bool something_changed = false;
if (buttons != buttons_prev) { //buttons
something_changed = true;
}
if (user_axis[0] != x_cur) { //xL
x_cur = user_axis[0];
something_changed = true;
}
if (user_axis[1] != y_cur) { //yL
y_cur = user_axis[1];
something_changed = true;
}
if (user_axis[9] != wheel_cur) { //Hat
wheel_cur = user_axis[9];
something_changed = true;
}
//Second Axis
if (user_axis[2] != x2_cur) { //xR
x2_cur = user_axis[2];
something_changed = true;
}
if (user_axis[5] != y2_cur) { //yR or z-axis
y2_cur = user_axis[5];
something_changed = true;
}
//Rumble Axis
switch (joystick.joystickType()) {
case JoystickController::XBOXONE:
case JoystickController::XBOX360:
case JoystickController::PS4:
if (user_axis[3] != L1_cur) { //xR
L1_cur = user_axis[3];
something_changed = true;
}
if (user_axis[4] != R1_cur) { //yR or z-axis
R1_cur = user_axis[4];
something_changed = true;
}
break;
case JoystickController::PS3:
if (user_axis[18] != L1_cur) { //xR
L1_cur = user_axis[18];
something_changed = true;
}
if (user_axis[19] != R1_cur) { //yR or z-axis
R1_cur = user_axis[19];
something_changed = true;
}
break;
}
if (something_changed) {
#define MOUSE_DATA_X 100
int16_t x, y2;
unsigned char line_space = Arial_12.line_space;
tft.setTextColor(ILI9341_WHITE, ILI9341_BLACK);
//tft.setTextDatum(BR_DATUM);
int16_t y = y_position_after_device_info;
tft.setCursor(TABLET_DATA_X, y);
tft.printf("%d(%x)", buttons, buttons);
tft.getCursor(&x, &y2);
tft.fillRect(x, y, 320, line_space, ILI9341_BLACK);

y += line_space; OutputNumberField(MOUSE_DATA_X, y, x_cur, 320); //x
y += line_space; OutputNumberField(MOUSE_DATA_X, y, y_cur, 320); //y
y += line_space; OutputNumberField(MOUSE_DATA_X, y, x2_cur, 320); //x2(z)
y += line_space; OutputNumberField(MOUSE_DATA_X, y, y2_cur, 320); //y2
switch (joystick.joystickType()) {
case JoystickController::PS4:
case JoystickController::PS3:
case JoystickController::XBOXONE:
case JoystickController::XBOX360:
y += line_space; OutputNumberField(MOUSE_DATA_X, y, L1_cur, 320);
y += line_space; OutputNumberField(MOUSE_DATA_X, y, R1_cur, 320);
break;
default:
y += line_space; OutputNumberField(MOUSE_DATA_X, y, 0, 320);
y += line_space; OutputNumberField(MOUSE_DATA_X, y, 0, 320);
y += line_space; OutputNumberField(MOUSE_DATA_X, y, wheel_cur, 320); //hat
break;
}
tft.updateScreen(); // update the screen now
}
}

//=============================================================================
// ProcessMouseData
//=============================================================================
bool OnReceiveHidData(uint32_t usage, const uint8_t *data, uint32_t len) {
// Called for maybe both HIDS for rawhid basic test. One is for the Teensy
// to output to Serial. while still having Raw Hid...
if (usage == 0xFF000080
) {
//Serial.print("RawHIDx data: ");
//Serial.println(usage, HEX);
for (uint32_t j = 0; j < len; j++) {
user_axis[j] = data[j];
}

bool something_changed = false;
if (user_axis[3] != buttons_cur) {
buttons_cur = user_axis[3];
something_changed = true;
}
if (user_axis[4] != x_cur) {
x_cur = user_axis[4];
something_changed = true;
}
if (user_axis[5] != y_cur) {
y_cur = user_axis[5];
something_changed = true;
}
if (tablet.getWheel() != wheel_cur) {
wheel_cur = 0;
something_changed = true;
}
if (tablet.getWheelH() != wheelH_cur) {
wheelH_cur = 0;
something_changed = true;
}
if (something_changed) {
tft.fillRect(45, 197, 240, 20, ILI9341_RED);
tft.drawNumber(buttons_cur, 50, 200);
tft.drawNumber(x_cur, 100, 200);
tft.drawNumber(y_cur, 150, 200);
tft.drawNumber(wheel_cur, 200, 200);
tft.drawNumber(wheelH_cur, 250, 200);
tft.updateScreen(); // update the screen now
}
} else {
// Lets trim off trailing null characters.
while ((len > 0) && (data[len - 1] == 0)) {
len--;
}
if (len) {
//Serial.print("RawHid Serial: ");
//Serial.write(data, len);
}
}
return true;
}

void MaybeSetupTextScrollArea()
{
if (new_device_detected) {
BT = 0;
new_device_detected = false;
}
if (BT == 0) {
tft.enableScroll();
tft.setScrollTextArea(20, 70, 280, 140);
tft.setScrollBackgroundColor(ILI9341_GREEN);
tft.setFont(Arial_11);
tft.setTextColor(ILI9341_BLACK);
tft.setCursor(20, 70);
BT = 1;
}
}

void OnPress(int key)
{
MaybeSetupTextScrollArea();
tft.print("key: ");
switch (key) {
case KEYD_UP : tft.print("UP"); break;
case KEYD_DOWN : tft.print("DN"); break;
case KEYD_LEFT : tft.print("LEFT"); break;
case KEYD_RIGHT : tft.print("RIGHT"); break;
case KEYD_INSERT : tft.print("Ins"); break;
case KEYD_DELETE : tft.print("Del"); break;
case KEYD_PAGE_UP : tft.print("PUP"); break;
case KEYD_PAGE_DOWN: tft.print("PDN"); break;
case KEYD_HOME : tft.print("HOME"); break;
case KEYD_END : tft.print("END"); break;
case KEYD_F1 : tft.print("F1"); break;
case KEYD_F2 : tft.print("F2"); break;
case KEYD_F3 : tft.print("F3"); break;
case KEYD_F4 : tft.print("F4"); break;
case KEYD_F5 : tft.print("F5"); break;
case KEYD_F6 : tft.print("F6"); break;
case KEYD_F7 : tft.print("F7"); break;
case KEYD_F8 : tft.print("F8"); break;
case KEYD_F9 : tft.print("F9"); break;
case KEYD_F10 : tft.print("F10"); break;
case KEYD_F11 : tft.print("F11"); break;
case KEYD_F12 : tft.print("F12"); break;
default: tft.print((char)key); break;
}
tft.print("' ");
tft.print(key);
tft.print(" MOD: ");
if (keyboard1) {
tft.print(keyboard1.getModifiers(), HEX);
tft.print(" OEM: ");
tft.print(keyboard1.getOemKey(), HEX);
tft.print(" LEDS: ");
tft.println(keyboard1.LEDS(), HEX);
} else {
tft.print(keyboard2.getModifiers(), HEX);
tft.print(" OEM: ");
tft.print(keyboard2.getOemKey(), HEX);
tft.print(" LEDS: ");
tft.println(keyboard2.LEDS(), HEX);
}

//Serial.print("key ");
//Serial.print((char)keyboard1.getKey());
//Serial.print(" ");
//Serial.print((char)keyboard2.getKey());
//Serial.println();
tft.updateScreen(); // update the screen now
}

void OnHIDExtrasPress(uint32_t top, uint16_t key)
{
MaybeSetupTextScrollArea();
tft.print("HID (");
tft.print(top, HEX);
tft.print(") key press:");
tft.print(key, HEX);
if (top == 0xc0000) {
switch (key) {
case 0x20 : tft.print(" - +10"); break;
case 0x21 : tft.print(" - +100"); break;
case 0x22 : tft.print(" - AM/PM"); break;
case 0x30 : tft.print(" - Power"); break;
case 0x31 : tft.print(" - Reset"); break;
case 0x32 : tft.print(" - Sleep"); break;
case 0x33 : tft.print(" - Sleep After"); break;
case 0x34 : tft.print(" - Sleep Mode"); break;
case 0x35 : tft.print(" - Illumination"); break;
case 0x36 : tft.print(" - Function Buttons"); break;
case 0x40 : tft.print(" - Menu"); break;
case 0x41 : tft.print(" - Menu Pick"); break;
case 0x42 : tft.print(" - Menu Up"); break;
case 0x43 : tft.print(" - Menu Down"); break;
case 0x44 : tft.print(" - Menu Left"); break;
case 0x45 : tft.print(" - Menu Right"); break;
case 0x46 : tft.print(" - Menu Escape"); break;
case 0x47 : tft.print(" - Menu Value Increase"); break;
case 0x48 : tft.print(" - Menu Value Decrease"); break;
case 0x60 : tft.print(" - Data On Screen"); break;
case 0x61 : tft.print(" - Closed Caption"); break;
case 0x62 : tft.print(" - Closed Caption Select"); break;
case 0x63 : tft.print(" - VCR/TV"); break;
case 0x64 : tft.print(" - Broadcast Mode"); break;
case 0x65 : tft.print(" - Snapshot"); break;
case 0x66 : tft.print(" - Still"); break;
case 0x80 : tft.print(" - Selection"); break;
case 0x81 : tft.print(" - Assign Selection"); break;
case 0x82 : tft.print(" - Mode Step"); break;
case 0x83 : tft.print(" - Recall Last"); break;
case 0x84 : tft.print(" - Enter Channel"); break;
case 0x85 : tft.print(" - Order Movie"); break;
case 0x86 : tft.print(" - Channel"); break;
case 0x87 : tft.print(" - Media Selection"); break;
case 0x88 : tft.print(" - Media Select Computer"); break;
case 0x89 : tft.print(" - Media Select TV"); break;
case 0x8A : tft.print(" - Media Select WWW"); break;
case 0x8B : tft.print(" - Media Select DVD"); break;
case 0x8C : tft.print(" - Media Select Telephone"); break;
case 0x8D : tft.print(" - Media Select Program Guide"); break;
case 0x8E : tft.print(" - Media Select Video Phone"); break;
case 0x8F : tft.print(" - Media Select Games"); break;
case 0x90 : tft.print(" - Media Select Messages"); break;
case 0x91 : tft.print(" - Media Select CD"); break;
case 0x92 : tft.print(" - Media Select VCR"); break;
case 0x93 : tft.print(" - Media Select Tuner"); break;
case 0x94 : tft.print(" - Quit"); break;
case 0x95 : tft.print(" - Help"); break;
case 0x96 : tft.print(" - Media Select Tape"); break;
case 0x97 : tft.print(" - Media Select Cable"); break;
case 0x98 : tft.print(" - Media Select Satellite"); break;
case 0x99 : tft.print(" - Media Select Security"); break;
case 0x9A : tft.print(" - Media Select Home"); break;
case 0x9B : tft.print(" - Media Select Call"); break;
case 0x9C : tft.print(" - Channel Increment"); break;
case 0x9D : tft.print(" - Channel Decrement"); break;
case 0x9E : tft.print(" - Media Select SAP"); break;
case 0xA0 : tft.print(" - VCR Plus"); break;
case 0xA1 : tft.print(" - Once"); break;
case 0xA2 : tft.print(" - Daily"); break;
case 0xA3 : tft.print(" - Weekly"); break;
case 0xA4 : tft.print(" - Monthly"); break;
case 0xB0 : tft.print(" - Play"); break;
case 0xB1 : tft.print(" - Pause"); break;
case 0xB2 : tft.print(" - Record"); break;
case 0xB3 : tft.print(" - Fast Forward"); break;
case 0xB4 : tft.print(" - Rewind"); break;
case 0xB5 : tft.print(" - Scan Next Track"); break;
case 0xB6 : tft.print(" - Scan Previous Track"); break;
case 0xB7 : tft.print(" - Stop"); break;
case 0xB8 : tft.print(" - Eject"); break;
case 0xB9 : tft.print(" - Random Play"); break;
case 0xBA : tft.print(" - Select DisC"); break;
case 0xBB : tft.print(" - Enter Disc"); break;
case 0xBC : tft.print(" - Repeat"); break;
case 0xBD : tft.print(" - Tracking"); break;
case 0xBE : tft.print(" - Track Normal"); break;
case 0xBF : tft.print(" - Slow Tracking"); break;
case 0xC0 : tft.print(" - Frame Forward"); break;
case 0xC1 : tft.print(" - Frame Back"); break;
case 0xC2 : tft.print(" - Mark"); break;
case 0xC3 : tft.print(" - Clear Mark"); break;
case 0xC4 : tft.print(" - Repeat From Mark"); break;
case 0xC5 : tft.print(" - Return To Mark"); break;
case 0xC6 : tft.print(" - Search Mark Forward"); break;
case 0xC7 : tft.print(" - Search Mark Backwards"); break;
case 0xC8 : tft.print(" - Counter Reset"); break;
case 0xC9 : tft.print(" - Show Counter"); break;
case 0xCA : tft.print(" - Tracking Increment"); break;
case 0xCB : tft.print(" - Tracking Decrement"); break;
case 0xCD : tft.print(" - Pause/Continue"); break;
case 0xE0 : tft.print(" - Volume"); break;
case 0xE1 : tft.print(" - Balance"); break;
case 0xE2 : tft.print(" - Mute"); break;
case 0xE3 : tft.print(" - Bass"); break;
case 0xE4 : tft.print(" - Treble"); break;
case 0xE5 : tft.print(" - Bass Boost"); break;
case 0xE6 : tft.print(" - Surround Mode"); break;
case 0xE7 : tft.print(" - Loudness"); break;
case 0xE8 : tft.print(" - MPX"); break;
case 0xE9 : tft.print(" - Volume Up"); break;
case 0xEA : tft.print(" - Volume Down"); break;
case 0xF0 : tft.print(" - Speed Select"); break;
case 0xF1 : tft.print(" - Playback Speed"); break;
case 0xF2 : tft.print(" - Standard Play"); break;
case 0xF3 : tft.print(" - Long Play"); break;
case 0xF4 : tft.print(" - Extended Play"); break;
case 0xF5 : tft.print(" - Slow"); break;
case 0x100: tft.print(" - Fan Enable"); break;
case 0x101: tft.print(" - Fan Speed"); break;
case 0x102: tft.print(" - Light"); break;
case 0x103: tft.print(" - Light Illumination Level"); break;
case 0x104: tft.print(" - Climate Control Enable"); break;
case 0x105: tft.print(" - Room Temperature"); break;
case 0x106: tft.print(" - Security Enable"); break;
case 0x107: tft.print(" - Fire Alarm"); break;
case 0x108: tft.print(" - Police Alarm"); break;
case 0x150: tft.print(" - Balance Right"); break;
case 0x151: tft.print(" - Balance Left"); break;
case 0x152: tft.print(" - Bass Increment"); break;
case 0x153: tft.print(" - Bass Decrement"); break;
case 0x154: tft.print(" - Treble Increment"); break;
case 0x155: tft.print(" - Treble Decrement"); break;
case 0x160: tft.print(" - Speaker System"); break;
case 0x161: tft.print(" - Channel Left"); break;
case 0x162: tft.print(" - Channel Right"); break;
case 0x163: tft.print(" - Channel Center"); break;
case 0x164: tft.print(" - Channel Front"); break;
case 0x165: tft.print(" - Channel Center Front"); break;
case 0x166: tft.print(" - Channel Side"); break;
case 0x167: tft.print(" - Channel Surround"); break;
case 0x168: tft.print(" - Channel Low Frequency Enhancement"); break;
case 0x169: tft.print(" - Channel Top"); break;
case 0x16A: tft.print(" - Channel Unknown"); break;
case 0x170: tft.print(" - Sub-channel"); break;
case 0x171: tft.print(" - Sub-channel Increment"); break;
case 0x172: tft.print(" - Sub-channel Decrement"); break;
case 0x173: tft.print(" - Alternate Audio Increment"); break;
case 0x174: tft.print(" - Alternate Audio Decrement"); break;
case 0x180: tft.print(" - Application Launch Buttons"); break;
case 0x181: tft.print(" - AL Launch Button Configuration Tool"); break;
case 0x182: tft.print(" - AL Programmable Button Configuration"); break;
case 0x183: tft.print(" - AL Consumer Control Configuration"); break;
case 0x184: tft.print(" - AL Word Processor"); break;
case 0x185: tft.print(" - AL Text Editor"); break;
case 0x186: tft.print(" - AL Spreadsheet"); break;
case 0x187: tft.print(" - AL Graphics Editor"); break;
case 0x188: tft.print(" - AL Presentation App"); break;
case 0x189: tft.print(" - AL Database App"); break;
case 0x18A: tft.print(" - AL Email Reader"); break;
case 0x18B: tft.print(" - AL Newsreader"); break;
case 0x18C: tft.print(" - AL Voicemail"); break;
case 0x18D: tft.print(" - AL Contacts/Address Book"); break;
case 0x18E: tft.print(" - AL Calendar/Schedule"); break;
case 0x18F: tft.print(" - AL Task/Project Manager"); break;
case 0x190: tft.print(" - AL Log/Journal/Timecard"); break;
case 0x191: tft.print(" - AL Checkbook/Finance"); break;
case 0x192: tft.print(" - AL Calculator"); break;
case 0x193: tft.print(" - AL A/V Capture/Playback"); break;
case 0x194: tft.print(" - AL Local Machine Browser"); break;
case 0x195: tft.print(" - AL LAN/WAN Browser"); break;
case 0x196: tft.print(" - AL Internet Browser"); break;
case 0x197: tft.print(" - AL Remote Networking/ISP Connect"); break;
case 0x198: tft.print(" - AL Network Conference"); break;
case 0x199: tft.print(" - AL Network Chat"); break;
case 0x19A: tft.print(" - AL Telephony/Dialer"); break;
case 0x19B: tft.print(" - AL Logon"); break;
case 0x19C: tft.print(" - AL Logoff"); break;
case 0x19D: tft.print(" - AL Logon/Logoff"); break;
case 0x19E: tft.print(" - AL Terminal Lock/Screensaver"); break;
case 0x19F: tft.print(" - AL Control Panel"); break;
case 0x1A0: tft.print(" - AL Command Line Processor/Run"); break;
case 0x1A1: tft.print(" - AL Process/Task Manager"); break;
case 0x1A2: tft.print(" - AL Select Tast/Application"); break;
case 0x1A3: tft.print(" - AL Next Task/Application"); break;
case 0x1A4: tft.print(" - AL Previous Task/Application"); break;
case 0x1A5: tft.print(" - AL Preemptive Halt Task/Application"); break;
case 0x200: tft.print(" - Generic GUI Application Controls"); break;
case 0x201: tft.print(" - AC New"); break;
case 0x202: tft.print(" - AC Open"); break;
case 0x203: tft.print(" - AC Close"); break;
case 0x204: tft.print(" - AC Exit"); break;
case 0x205: tft.print(" - AC Maximize"); break;
case 0x206: tft.print(" - AC Minimize"); break;
case 0x207: tft.print(" - AC Save"); break;
case 0x208: tft.print(" - AC Print"); break;
case 0x209: tft.print(" - AC Properties"); break;
case 0x21A: tft.print(" - AC Undo"); break;
case 0x21B: tft.print(" - AC Copy"); break;
case 0x21C: tft.print(" - AC Cut"); break;
case 0x21D: tft.print(" - AC Paste"); break;
case 0x21E: tft.print(" - AC Select All"); break;
case 0x21F: tft.print(" - AC Find"); break;
case 0x220: tft.print(" - AC Find and Replace"); break;
case 0x221: tft.print(" - AC Search"); break;
case 0x222: tft.print(" - AC Go To"); break;
case 0x223: tft.print(" - AC Home"); break;
case 0x224: tft.print(" - AC Back"); break;
case 0x225: tft.print(" - AC Forward"); break;
case 0x226: tft.print(" - AC Stop"); break;
case 0x227: tft.print(" - AC Refresh"); break;
case 0x228: tft.print(" - AC Previous Link"); break;
case 0x229: tft.print(" - AC Next Link"); break;
case 0x22A: tft.print(" - AC Bookmarks"); break;
case 0x22B: tft.print(" - AC History"); break;
case 0x22C: tft.print(" - AC Subscriptions"); break;
case 0x22D: tft.print(" - AC Zoom In"); break;
case 0x22E: tft.print(" - AC Zoom Out"); break;
case 0x22F: tft.print(" - AC Zoom"); break;
case 0x230: tft.print(" - AC Full Screen View"); break;
case 0x231: tft.print(" - AC Normal View"); break;
case 0x232: tft.print(" - AC View Toggle"); break;
case 0x233: tft.print(" - AC Scroll Up"); break;
case 0x234: tft.print(" - AC Scroll Down"); break;
case 0x235: tft.print(" - AC Scroll"); break;
case 0x236: tft.print(" - AC Pan Left"); break;
case 0x237: tft.print(" - AC Pan Right"); break;
case 0x238: tft.print(" - AC Pan"); break;
case 0x239: tft.print(" - AC New Window"); break;
case 0x23A: tft.print(" - AC Tile Horizontally"); break;
case 0x23B: tft.print(" - AC Tile Vertically"); break;
case 0x23C: tft.print(" - AC Format"); break;

}
}
tft.println();
tft.updateScreen(); // update the screen now
}

void OnHIDExtrasRelease(uint32_t top, uint16_t key)
{
tft.print("HID (");
tft.print(top, HEX);
tft.print(") key release:");
tft.println(key, HEX);
}

+ 1
- 0
examples/USBHost_viewer/defs.h View File

@@ -0,0 +1 @@


+ 7
- 5
hid.cpp View File

@@ -165,7 +165,8 @@ void USBHIDParser::control(const Transfer_t *transfer)
println(" got report descriptor");
parse();
queue_Data_Transfer(in_pipe, report, in_size, this);
if (device->idVendor == 0x054C && device->idProduct == 0x0268) {
if (device->idVendor == 0x054C &&
((device->idProduct == 0x0268) || (device->idProduct == 0x042F)/* || (device->idProduct == 0x03D5)*/)) {
println("send special PS3 feature command");
mk_setup(setup, 0x21, 9, 0x03F4, 0, 4); // ps3 tell to send report 1?
static uint8_t ps3_feature_F4_report[] = {0x42, 0x0c, 0x00, 0x00};
@@ -205,12 +206,12 @@ void USBHIDParser::disconnect()
// Called when the HID device sends a report
void USBHIDParser::in_data(const Transfer_t *transfer)
{
/*Serial.printf("HID: ");
/*USBHDBGSerial.printf("HID: ");
uint8_t *pb = (uint8_t*)transfer->buffer;
for (uint8_t i = 0; i < transfer->length; i++) {
Serial.printf("%x ",pb[i]);
USBHDBGSerial.printf("%x ",pb[i]);
}
Serial.printf("\n"); */
USBHDBGSerial.printf("\n"); */

print("HID: ");
print(use_report_id);
@@ -402,6 +403,7 @@ USBHIDInput * USBHIDParser::find_driver(uint32_t topusage)
}
driver = driver->next;
}
println("No Driver claimed topusage: ", topusage, HEX);
return NULL;
}

@@ -587,7 +589,7 @@ void USBHIDParser::parse(uint16_t type_and_report_id, const uint8_t *data, uint3
}
uminmax = true;
}
//Serial.printf("TU:%x US:%x %x %d %d: C:%d, %d, MM:%d, %x %x\n", topusage, usage_page, val, logical_min, logical_max,
//USBHDBGSerial.printf("TU:%x US:%x %x %d %d: C:%d, %d, MM:%d, %x %x\n", topusage, usage_page, val, logical_min, logical_max,
// report_count, usage_count, uminmax, usage[0], usage[1]);
for (uint32_t i=0; i < report_count; i++) {
uint32_t u;

+ 475
- 46
joystick.cpp View File

@@ -27,6 +27,13 @@
#define print USBHost::print_
#define println USBHost::println_

//#define DEBUG_JOYSTICK
#ifdef DEBUG_JOYSTICK
#define DBGPrintf USBHDBGSerial.printf
#else
#define DBGPrintf(...)
#endif

// PID/VID to joystick mapping - Only the XBOXOne is used to claim the USB interface directly,
// The others are used after claim-hid code to know which one we have and to use it for
// doing other features.
@@ -34,7 +41,11 @@ JoystickController::product_vendor_mapping_t JoystickController::pid_vid_mapping
{ 0x045e, 0x02ea, XBOXONE, false },{ 0x045e, 0x02dd, XBOXONE, false },
{ 0x045e, 0x0719, XBOX360, false},
{ 0x054C, 0x0268, PS3, true},
{ 0x054C, 0x05C4, PS4, true}, {0x054C, 0x09CC, PS4, true }
{ 0x054C, 0x042F, PS3, true}, // PS3 Navigation controller
{ 0x054C, 0x03D5, PS3_MOTION, true}, // PS3 Motion controller
{ 0x054C, 0x05C4, PS4, true}, {0x054C, 0x09CC, PS4, true },
{ 0x046D, 0xC626, SpaceNav, true}, // 3d Connextion Space Navigator, 0x10008
{ 0x046D, 0xC628, SpaceNav, true} // 3d Connextion Space Navigator, 0x10008
};


@@ -47,6 +58,7 @@ void JoystickController::init()
contribute_String_Buffers(mystring_bufs, sizeof(mystring_bufs)/sizeof(strbuf_t));
driver_ready_for_device(this);
USBHIDParser::driver_ready_for_hid_collection(this);
BluetoothController::driver_ready_for_bluetooth(this);
}

//-----------------------------------------------------------------------------
@@ -83,6 +95,7 @@ uint16_t JoystickController::idProduct()
const uint8_t *JoystickController::manufacturer()
{
if ((device != nullptr) && (device->strbuf != nullptr)) return &device->strbuf->buffer[device->strbuf->iStrings[strbuf_t::STR_ID_MAN]];
//if ((btdevice != nullptr) && (btdevice->strbuf != nullptr)) return &btdevice->strbuf->buffer[btdevice->strbuf->iStrings[strbuf_t::STR_ID_MAN]];
if ((mydevice != nullptr) && (mydevice->strbuf != nullptr)) return &mydevice->strbuf->buffer[mydevice->strbuf->iStrings[strbuf_t::STR_ID_MAN]];
return nullptr;
}
@@ -91,6 +104,7 @@ const uint8_t *JoystickController::product()
{
if ((device != nullptr) && (device->strbuf != nullptr)) return &device->strbuf->buffer[device->strbuf->iStrings[strbuf_t::STR_ID_PROD]];
if ((mydevice != nullptr) && (mydevice->strbuf != nullptr)) return &mydevice->strbuf->buffer[mydevice->strbuf->iStrings[strbuf_t::STR_ID_PROD]];
if (btdevice != nullptr) return remote_name_;
return nullptr;
}

@@ -110,11 +124,13 @@ bool JoystickController::setRumble(uint8_t lValue, uint8_t rValue, uint8_t timeo
rumble_rValue_ = rValue;
rumble_timeout_ = timeout;

switch (joystickType) {
switch (joystickType_) {
default:
break;
case PS3:
return transmitPS3UserFeedbackMsg();
case PS3_MOTION:
return transmitPS3MotionUserFeedbackMsg();
case PS4:
return transmitPS4UserFeedbackMsg();
case XBOXONE:
@@ -157,6 +173,7 @@ bool JoystickController::setRumble(uint8_t lValue, uint8_t rValue, uint8_t timeo
return false;
}


bool JoystickController::setLEDs(uint8_t lr, uint8_t lg, uint8_t lb)
{
// Need to know which joystick we are on. Start off with XBox support - maybe need to add some enum value for the known
@@ -166,9 +183,11 @@ bool JoystickController::setLEDs(uint8_t lr, uint8_t lg, uint8_t lb)
leds_[1] = lg;
leds_[2] = lb;

switch (joystickType) {
switch (joystickType_) {
case PS3:
return transmitPS3UserFeedbackMsg();
case PS3_MOTION:
return transmitPS3MotionUserFeedbackMsg();
case PS4:
return transmitPS4UserFeedbackMsg();
case XBOX360:
@@ -200,21 +219,44 @@ bool JoystickController::setLEDs(uint8_t lr, uint8_t lg, uint8_t lb)
}

bool JoystickController::transmitPS4UserFeedbackMsg() {
if (!driver_) return false;
uint8_t packet[32];
memset(packet, 0, sizeof(packet));

packet[0] = 0x05; // Report ID
packet[1]= 0xFF;

packet[4] = rumble_lValue_; // Small Rumble
packet[5] = rumble_rValue_; // Big rumble
packet[6] = leds_[0]; // RGB value
packet[7] = leds_[1];
packet[8] = leds_[2];
// 9, 10 flash ON, OFF times in 100ths of sedond? 2.5 seconds = 255
Serial.printf("Joystick update Rumble/LEDs");
return driver_->sendPacket(packet, 32);
if (driver_) {
uint8_t packet[32];
memset(packet, 0, sizeof(packet));

packet[0] = 0x05; // Report ID
packet[1]= 0xFF;

packet[4] = rumble_lValue_; // Small Rumble
packet[5] = rumble_rValue_; // Big rumble
packet[6] = leds_[0]; // RGB value
packet[7] = leds_[1];
packet[8] = leds_[2];
// 9, 10 flash ON, OFF times in 100ths of second? 2.5 seconds = 255
DBGPrintf("Joystick update Rumble/LEDs\n");
return driver_->sendPacket(packet, 32);
} else if (btdriver_) {
uint8_t packet[79];
memset(packet, 0, sizeof(packet));
//0xa2, 0x11, 0xc0, 0x20, 0xf0, 0x04, 0x00
packet[0] = 0x52;
packet[1] = 0x11; // Report ID
packet[2] = 0x80;
//packet[3] = 0x20;
packet[4] = 0xFF;

packet[7] = rumble_lValue_; // Small Rumble
packet[8] = rumble_rValue_; // Big rumble
packet[9] = leds_[0]; // RGB value
packet[10] = leds_[1];
packet[11] = leds_[2];

// 12, 13 flash ON, OFF times in 100ths of sedond? 2.5 seconds = 255
DBGPrintf("Joystick update Rumble/LEDs\n");
btdriver_->sendL2CapCommand(packet, sizeof(packet), 0x40);

return true;
}
return false;
}

static const uint8_t PS3_USER_FEEDBACK_INIT[] = {
@@ -230,16 +272,58 @@ static const uint8_t PS3_USER_FEEDBACK_INIT[] = {
0x00, 0x00, 0x00 };

bool JoystickController::transmitPS3UserFeedbackMsg() {
if (!driver_) return false;
memcpy(txbuf_, PS3_USER_FEEDBACK_INIT, 48);
if (driver_) {
memcpy(txbuf_, PS3_USER_FEEDBACK_INIT, 48);

txbuf_[1] = rumble_lValue_? rumble_timeout_ : 0;
txbuf_[2] = rumble_lValue_; // Small Rumble
txbuf_[3] = rumble_rValue_? rumble_timeout_ : 0;
txbuf_[4] = rumble_rValue_; // Big rumble
txbuf_[9] = leds_[2] << 1; // RGB value // using third led now...
//DBGPrintf("\nJoystick update Rumble/LEDs %d %d %d %d %d\n", txbuf_[1], txbuf_[2], txbuf_[3], txbuf_[4], txbuf_[9]);
return driver_->sendControlPacket(0x21, 9, 0x201, 0, 48, txbuf_);
} else if (btdriver_) {
txbuf_[0] = 0x52;
txbuf_[1] = 0x1;
memcpy(&txbuf_[2], PS3_USER_FEEDBACK_INIT, 48);

txbuf_[3] = rumble_lValue_? rumble_timeout_ : 0;
txbuf_[4] = rumble_lValue_; // Small Rumble
txbuf_[5] = rumble_rValue_? rumble_timeout_ : 0;
txbuf_[6] = rumble_rValue_; // Big rumble
txbuf_[11] = leds_[2] << 1; // RGB value
DBGPrintf("\nJoystick update Rumble/LEDs %d %d %d %d %d\n", txbuf_[3], txbuf_[4], txbuf_[5], txbuf_[6], txbuf_[11]);
btdriver_->sendL2CapCommand(txbuf_, 50, BluetoothController::CONTROL_SCID);
return true;
}
return false;
}

txbuf_[1] = rumble_lValue_? rumble_timeout_ : 0;
txbuf_[2] = rumble_lValue_; // Small Rumble
txbuf_[3] = rumble_rValue_? rumble_timeout_ : 0;
txbuf_[4] = rumble_rValue_; // Big rumble
txbuf_[9] = leds_[0] << 1; // RGB value
//Serial.printf("\nJoystick update Rumble/LEDs %d %d %d %d %d\n", txbuf_[1], txbuf_[2], txbuf_[3], txbuf_[4], txbuf_[9]);
return driver_->sendControlPacket(0x21, 9, 0x201, 0, 48, txbuf_);
#define MOVE_REPORT_BUFFER_SIZE 7
#define MOVE_HID_BUFFERSIZE 50 // Size of the buffer for the Playstation Motion Controller

bool JoystickController::transmitPS3MotionUserFeedbackMsg() {
if (driver_) {
txbuf_[0] = 0x02; // Set report ID, this is needed for Move commands to work
txbuf_[2] = leds_[0];
txbuf_[3] = leds_[1];
txbuf_[4] = leds_[2];
txbuf_[6] = rumble_lValue_; // Set the rumble value into the write buffer

//return driver_->sendControlPacket(0x21, 9, 0x201, 0, MOVE_REPORT_BUFFER_SIZE, txbuf_);
return driver_->sendPacket(txbuf_, MOVE_REPORT_BUFFER_SIZE);

} else if (btdriver_) {
txbuf_[0] = 0xA2; // HID BT DATA_request (0xA0) | Report Type (Output 0x02)
txbuf_[1] = 0x02; // Report ID
txbuf_[3] = leds_[0];
txbuf_[4] = leds_[1];
txbuf_[5] = leds_[2];
txbuf_[7] = rumble_lValue_;
btdriver_->sendL2CapCommand(txbuf_, MOVE_HID_BUFFERSIZE, BluetoothController::INTERRUPT_SCID);
return true;
}
return false;
}

//*****************************************************************************
@@ -249,7 +333,7 @@ if (!driver_) return false;
hidclaim_t JoystickController::claim_collection(USBHIDParser *driver, Device_t *dev, uint32_t topusage)
{
// only claim Desktop/Joystick and Desktop/Gamepad
if (topusage != 0x10004 && topusage != 0x10005) return CLAIM_NO;
if (topusage != 0x10004 && topusage != 0x10005 && topusage != 0x10008) return CLAIM_NO;
// only claim from one physical device
if (mydevice != NULL && dev != mydevice) return CLAIM_NO;

@@ -264,9 +348,11 @@ hidclaim_t JoystickController::claim_collection(USBHIDParser *driver, Device_t *
connected_ = true; // remember that hardware is actually connected...

// Lets see if we know what type of joystick this is. That is, is it a PS3 or PS4 or ...
joystickType = mapVIDPIDtoJoystickType(mydevice->idVendor, mydevice->idProduct, false);
switch (joystickType) {
joystickType_ = mapVIDPIDtoJoystickType(mydevice->idVendor, mydevice->idProduct, false);
DBGPrintf("JoystickController::claim_collection joystickType_=%d\n", joystickType_);
switch (joystickType_) {
case PS3:
case PS3_MOTION: // not sure yet
additional_axis_usage_page_ = 0x1;
additional_axis_usage_start_ = 0x100;
additional_axis_usage_count_ = 39;
@@ -279,12 +365,12 @@ hidclaim_t JoystickController::claim_collection(USBHIDParser *driver, Device_t *
axis_change_notify_mask_ = (uint64_t)0xfffffffffffff3ffl; // Start off assume all bits - 10 and 11
break;
default:
additional_axis_usage_page_ = 0;
additional_axis_usage_start_ = 0;
additional_axis_usage_count_ = 0;
additional_axis_usage_page_ = 0x09;
additional_axis_usage_start_ = 0x21;
additional_axis_usage_count_ = 5;
axis_change_notify_mask_ = 0x3ff; // Start off assume only the 10 bits...
}
Serial.printf("Claim Additional axis: %x %x %d\n", additional_axis_usage_page_, additional_axis_usage_start_, additional_axis_usage_count_);
DBGPrintf("Claim Additional axis: %x %x %d\n", additional_axis_usage_page_, additional_axis_usage_start_, additional_axis_usage_count_);
return CLAIM_REPORT;
}

@@ -305,7 +391,8 @@ void JoystickController::hid_input_begin(uint32_t topusage, uint32_t type, int l

void JoystickController::hid_input_data(uint32_t usage, int32_t value)
{
//Serial.printf("Joystick: usage=%X, value=%d\n", usage, value);
DBGPrintf("joystickType_=%d\n", joystickType_);
DBGPrintf("Joystick: usage=%X, value=%d\n", usage, value);
uint32_t usage_page = usage >> 16;
usage &= 0xFFFF;
if (usage_page == 9 && usage >= 1 && usage <= 32) {
@@ -334,7 +421,7 @@ void JoystickController::hid_input_data(uint32_t usage, int32_t value)
}
} else if (usage_page == additional_axis_usage_page_) {
// see if the usage is witin range.
//Serial.printf("UP: usage_page=%x usage=%x User: %x %d\n", usage_page, usage, user_buttons_usage_start, user_buttons_count_);
//DBGPrintf("UP: usage_page=%x usage=%x User: %x %d\n", usage_page, usage, user_buttons_usage_start, user_buttons_count_);
if ((usage >= additional_axis_usage_start_) && (usage < (additional_axis_usage_start_ + additional_axis_usage_count_))) {
// We are in the user range.
uint16_t usage_index = usage - additional_axis_usage_start_ + STANDARD_AXIS_COUNT;
@@ -348,11 +435,11 @@ void JoystickController::hid_input_data(uint32_t usage, int32_t value)
}
axis_mask_ |= ((uint64_t)1 << usage_index); // Keep record of which axis we have data on.
}
//Serial.printf("UB: index=%x value=%x\n", usage_index, value);
//DBGPrintf("UB: index=%x value=%x\n", usage_index, value);
}

} else {
Serial.printf("UP: usage_page=%x usage=%x add: %x %x %d\n", usage_page, usage, additional_axis_usage_page_, additional_axis_usage_start_, additional_axis_usage_count_);
DBGPrintf("UP: usage_page=%x usage=%x add: %x %x %d\n", usage_page, usage, additional_axis_usage_page_, additional_axis_usage_start_, additional_axis_usage_count_);

}
// TODO: hat switch?
@@ -367,7 +454,7 @@ void JoystickController::hid_input_end()

bool JoystickController::hid_process_out_data(const Transfer_t *transfer)
{
//Serial.printf("JoystickController::hid_process_out_data\n");
//DBGPrintf("JoystickController::hid_process_out_data\n");
return true;
}

@@ -479,7 +566,8 @@ bool JoystickController::claim(Device_t *dev, int type, const uint8_t *descripto
connected_ = 0; // remember that hardware is actually connected...
}
memset(axis, 0, sizeof(axis)); // clear out any data.
joystickType = jtype; // remember we are an XBox One.
joystickType_ = jtype; // remember we are an XBox One.
DBGPrintf(" JoystickController::claim joystickType_ %d\n", joystickType_);
return true;
}

@@ -512,6 +600,8 @@ void JoystickController::tx_callback(const Transfer_t *transfer)
// Information came from several places on the web including:
// https://github.com/quantus/xbox-one-controller-protocol
/************************************************************/
// 20 00 C5 0E 00 00 00 00 00 00 F0 06 AD FB 7A 0A DD F7 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
// 20 00 E0 0E 40 00 00 00 00 00 F0 06 AD FB 7A 0A DD F7 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
typedef struct {
uint8_t type;
uint8_t const_0;
@@ -545,14 +635,15 @@ typedef struct {
int16_t axis[4];
} xbox360data_t;

static const uint8_t xbox_axis_order_mapping[] = {4, 5, 0, 1, 2, 3};
static const uint8_t xbox_axis_order_mapping[] = {3, 4, 0, 1, 2, 5};

void JoystickController::rx_data(const Transfer_t *transfer)
{
print("JoystickController::rx_data: ");
print("JoystickController::rx_data (", joystickType_, DEC);
print("): ");
print_hexbytes((uint8_t*)transfer->buffer, transfer->length);

if (joystickType == XBOXONE) {
if (joystickType_ == XBOXONE) {
// Process XBOX One data
axis_mask_ = 0x3f;
axis_changed_mask_ = 0; // assume none for now
@@ -562,6 +653,8 @@ void JoystickController::rx_data(const Transfer_t *transfer)
if (xb1d->buttons != buttons) {
buttons = xb1d->buttons;
anychange = true;
joystickEvent = true;
println(" Button Change: ", buttons, HEX);
}
for (uint8_t i = 0; i < sizeof (xbox_axis_order_mapping); i++) {
// The first two values were unsigned.
@@ -575,7 +668,7 @@ void JoystickController::rx_data(const Transfer_t *transfer)
joystickEvent = true;
}

} else if (joystickType == XBOX360) {
} else if (joystickType_ == XBOX360) {
// First byte appears to status - if the byte is 0x8 it is a connect or disconnect of the controller.
xbox360data_t *xb360d = (xbox360data_t *)transfer->buffer;
if (xb360d->state == 0x08) {
@@ -595,8 +688,8 @@ void JoystickController::rx_data(const Transfer_t *transfer)
println("XBox360w - controllerStatus: ", xb360d->controller_status, HEX);
} else if(xb360d->id_or_type == 0x01) { // Lets only process report 1.
//const uint8_t *pbuffer = (uint8_t*)transfer->buffer;
//for (uint8_t i = 0; i < transfer->length; i++) Serial.printf("%02x ", pbuffer[i]);
//Serial.printf("\n");
//for (uint8_t i = 0; i < transfer->length; i++) DBGPrintf("%02x ", pbuffer[i]);
//DBGPrintf("\n");
if (buttons != xb360d->buttons) {
buttons = xb360d->buttons;
@@ -643,4 +736,340 @@ void JoystickController::disconnect()
// TODO: free resources
}

bool JoystickController::claim_bluetooth(BluetoothController *driver, uint32_t bluetooth_class, uint8_t *remoteName)
{
if ((((bluetooth_class & 0xff00) == 0x2500) || (((bluetooth_class & 0xff00) == 0x500))) && ((bluetooth_class & 0x3C) == 0x08)) {
DBGPrintf("JoystickController::claim_bluetooth TRUE\n");
btdriver_ = driver;
btdevice = (Device_t*)driver; // remember this way
if (remoteName) mapNameToJoystickType(remoteName);
return true;
}

if (remoteName && mapNameToJoystickType(remoteName)) {
if ((joystickType_ == PS3) || (joystickType_ == PS3_MOTION)) {
DBGPrintf("JoystickController::claim_bluetooth TRUE PS3 hack...\n");
btdriver_ = driver;
btdevice = (Device_t*)driver; // remember this way
special_process_required = SP_PS3_IDS; // PS3 maybe needs different IDS.
return true;
}
}
return false;
}


bool JoystickController::process_bluetooth_HID_data(const uint8_t *data, uint16_t length)
{
// Example data from PS4 controller
//01 7e 7f 82 84 08 00 00 00 00
// LX LY RX RY BT BT PS LT RT
DBGPrintf("JoystickController::process_bluetooth_HID_data: data[0]=%x\n", data[0]);
// May have to look at this one with other controllers...
if (data[0] == 1) {
//print(" Joystick Data: ");
// print_hexbytes(data, length);
if (length > TOTAL_AXIS_COUNT) length = TOTAL_AXIS_COUNT; // don't overflow arrays...
DBGPrintf(" Joystick Data: ");
for(uint16_t i =0; i < length; i++) DBGPrintf("%02x ", data[i]);
DBGPrintf("\r\n");
if (joystickType_ == PS3) {
// Quick and dirty hack to match PS3 HID data
uint32_t cur_buttons = data[2] | ((uint16_t)data[3] << 8) | ((uint32_t)data[4] << 16);
if (cur_buttons != buttons) {
buttons = cur_buttons;
joystickEvent = true; // something changed.
}

uint64_t mask = 0x1;
axis_mask_ = 0x27; // assume bits 0, 1, 2, 5
for (uint16_t i = 0; i < 3; i++) {
if (axis[i] != data[i+6]) {
axis_changed_mask_ |= mask;
axis[i] = data[i+6];
}
mask <<= 1; // shift down the mask.
}
if (axis[5] != data[9]) {
axis_changed_mask_ |= (1<<5);
axis[5] = data[9];
}
if (axis[3] != data[18]) {
axis_changed_mask_ |= (1<<3);
axis[3] = data[18];
}
if (axis[4] != data[19]) {
axis_changed_mask_ |= (1<<4);
axis[4] = data[19];
}
// Then rest of data
mask = 0x1 << 10; // setup for other bits
for (uint16_t i = 10; i < length; i++ ) {
axis_mask_ |= mask;
if(data[i] != axis[i]) {
axis_changed_mask_ |= mask;
axis[i] = data[i];
}
mask <<= 1; // shift down the mask.
}
} else if (joystickType_ == PS3_MOTION) {
// Quick and dirty PS3_Motion data.
uint32_t cur_buttons = data[1] | ((uint16_t)data[2] << 8) | ((uint32_t)data[3] << 16);
if (cur_buttons != buttons) {
buttons = cur_buttons;
joystickEvent = true; // something changed.
}

// Hard to know what is best here. for now just copy raw data over...
// will do this for now... Format of thought to be data.
// data[1-3] Buttons (mentioned 4 as well but appears to be counter
// axis[0-1] data[5] Trigger, Previous trigger value
// 2-5 Unknown probably place holders for Axis like data for other PS3
// 6 - Time stamp
// 7 - Battery
// 8-19 - Accel: XL, XH, YL, YH, ZL, ZH, XL2, XH2, YL2, YH2, ZL2, ZH2
// 20-31 - Gyro: Xl,Xh,Yl,Yh,Zl,Zh,Xl2,Xh2,Yl2,Yh2,Zl2,Zh2
// 32 - Temp High
// 33 - Temp Low (4 bits) Maybe Magneto x High on other??
uint64_t mask = 0x1;
axis_mask_ = 0; // assume bits 0, 1, 2, 5
// Then rest of data
mask = 0x1 << 10; // setup for other bits
for (uint16_t i = 5; i < length; i++ ) {
axis_mask_ |= mask;
if(data[i] != axis[i-5]) {
axis_changed_mask_ |= mask;
axis[i-5] = data[i];
}
mask <<= 1; // shift down the mask.
}

} else {
uint64_t mask = 0x1;
axis_mask_ = 0;

for (uint16_t i = 0; i < length; i++ ) {
axis_mask_ |= mask;
if(data[i] != axis[i]) {
axis_changed_mask_ |= mask;
axis[i] = data[i];
}
mask <<= 1; // shift down the mask.
// DBGPrintf("%02x ", axis[i]);
}

}

if (axis_changed_mask_ & axis_change_notify_mask_)
joystickEvent = true;
connected_ = true;
return true;

} else if(data[0] == 0x11){
DBGPrintf("\n Joystick Data: ");
uint64_t mask = 0x1;
axis_mask_ = 0;
axis_changed_mask_ = 0;
//This moves data to be equivalent to what we see for
//data[0] = 0x01
uint8_t tmp_data[length-2];
for (uint16_t i = 0; i < (length-2); i++ ) {
tmp_data[i] = 0;
tmp_data[i] = data[i+2];
}
/*
* [1] LX, [2] = LY, [3] = RX, [4] = RY
* [5] combo, tri, cir, x, sqr, D-PAD (4bits, 0-3
* [6] R3,L3, opt, share, R2, L2, R1, L1
* [7] Counter (bit7-2), T-PAD, PS
* [8] Left Trigger, [9] Right Trigger
* [10-11] Timestamp
* [12] Battery (0 to 0xff)
* [13-14] acceleration x
* [15-16] acceleration y
* [17-18] acceleration z
* [19-20] gyro x
* [21-22] gyro y
* [23-24] gyro z
* [25-29] unknown
* [30] 0x00,phone,mic, usb, battery level (4bits)
* rest is trackpad? to do implement?
*/
//PS Bit
tmp_data[7] = (tmp_data[7] >> 0) & 1;
//set arrow buttons to axis[0]
tmp_data[10] = tmp_data[5] & ((1 << 4) - 1);
//set buttons for last 4bits in the axis[5]
tmp_data[5] = tmp_data[5] >> 4;
// Quick and dirty hack to match PS4 HID data
uint32_t cur_buttons = tmp_data[7] | (tmp_data[10]) | ((tmp_data[6]*10)) | ((uint16_t)tmp_data[5] << 16) ;
if (cur_buttons != buttons) {
buttons = cur_buttons;
joystickEvent = true; // something changed.
}
mask = 0x1;
axis_mask_ = 0x27; // assume bits 0, 1, 2, 5
for (uint16_t i = 0; i < 3; i++) {
if (axis[i] != tmp_data[i+1]) {
axis_changed_mask_ |= mask;
axis[i] = tmp_data[i+1];
}
mask <<= 1; // shift down the mask.
}
if (axis[5] != tmp_data[4]) {
axis_changed_mask_ |= (1<<5);
axis[5] = tmp_data[4];
}
if (axis[3] != tmp_data[8]) {
axis_changed_mask_ |= (1<<3);
axis[3] = tmp_data[8];
}
if (axis[4] != tmp_data[9]) {
axis_changed_mask_ |= (1<<4);
axis[4] = tmp_data[9];
}
//limit for masking
mask = 0x1;
for (uint16_t i = 6; i < (64); i++ ) {
axis_mask_ |= mask;
if(tmp_data[i] != axis[i]) {
axis_changed_mask_ |= mask;
axis[i] = tmp_data[i];
}
mask <<= 1; // shift down the mask.
DBGPrintf("%02x ", axis[i]);
}
DBGPrintf("\n");
//DBGPrintf("Axis Mask (axis_mask_, axis_changed_mask_; %d, %d\n", axis_mask_,axis_changed_mask_);
joystickEvent = true;
connected_ = true;
}
return false;
}

bool JoystickController::mapNameToJoystickType(const uint8_t *remoteName)
{
// Sort of a hack, but try to map the name given from remote to a type...
if (strncmp((const char *)remoteName, "Wireless Controller", 19) == 0) {
DBGPrintf(" JoystickController::mapNameToJoystickType %s - set to PS4\n", remoteName);
joystickType_ = PS4;
} else if (strncmp((const char *)remoteName, "PLAYSTATION(R)3", 15) == 0) {
DBGPrintf(" JoystickController::mapNameToJoystickType %x %s - set to PS3\n", (uint32_t)this, remoteName);
joystickType_ = PS3;
} else if (strncmp((const char *)remoteName, "Navigation Controller", 21) == 0) {
DBGPrintf(" JoystickController::mapNameToJoystickType %x %s - set to PS3\n", (uint32_t)this, remoteName);
joystickType_ = PS3;
} else if (strncmp((const char *)remoteName, "Motion Controller", 17) == 0) {
DBGPrintf(" JoystickController::mapNameToJoystickType %x %s - set to PS3 Motion\n", (uint32_t)this, remoteName);
joystickType_ = PS3_MOTION;
} else if (strncmp((const char *)remoteName, "Xbox Wireless", 13) == 0) {
DBGPrintf(" JoystickController::mapNameToJoystickType %x %s - set to XBOXONE\n", (uint32_t)this, remoteName);
joystickType_ = XBOXONE;
} else {
DBGPrintf(" JoystickController::mapNameToJoystickType %s - Unknown\n", remoteName);
}
DBGPrintf(" Joystick Type: %d\n", joystickType_);
return true;
}


bool JoystickController::remoteNameComplete(const uint8_t *remoteName)
{
// Sort of a hack, but try to map the name given from remote to a type...
if (mapNameToJoystickType(remoteName)) {
switch (joystickType_) {
case PS4: special_process_required = SP_NEED_CONNECT; break;
case PS3: special_process_required = SP_PS3_IDS; break;
case PS3_MOTION: special_process_required = SP_PS3_IDS; break;
default:
break;
}
}
return true;
}

void JoystickController::connectionComplete()
{
DBGPrintf(" JoystickController::connectionComplete %x joystick type %d\n", (uint32_t)this, joystickType_);
switch (joystickType_) {
case PS4:
{
uint8_t packet[2];
packet[0] = 0x43; // HID BT Get_report (0x40) | Report Type (Feature 0x03)
packet[1] = 0x02; // Report ID
DBGPrintf("Set PS4 report\n");
delay(1);
btdriver_->sendL2CapCommand(packet, sizeof(packet), 0x40);
}
break;
case PS3:
{
uint8_t packet[6];
packet[0] = 0x53; // HID BT Set_report (0x50) | Report Type (Feature 0x03)
packet[1] = 0xF4; // Report ID
packet[2] = 0x42; // Special PS3 Controller enable commands
packet[3] = 0x03;
packet[4] = 0x00;
packet[5] = 0x00;

DBGPrintf("enable six axis\n");
delay(1);
btdriver_->sendL2CapCommand(packet, sizeof(packet), BluetoothController::CONTROL_SCID);
}
break;
case PS3_MOTION:
setLEDs(0, 0xff, 0); // Maybe try setting to green?
default:
break;
}
}

void JoystickController::release_bluetooth()
{
btdevice = nullptr; // remember this way
btdriver_ = nullptr;
connected_ = false;
special_process_required = false;

}


bool JoystickController::PS3Pair(uint8_t* bdaddr) {
if (!driver_) return false;
if (joystickType_ == PS3) {
/* Set the internal Bluetooth address */
txbuf_[0] = 0x01;
txbuf_[1] = 0x00;

for(uint8_t i = 0; i < 6; i++)
txbuf_[i + 2] = bdaddr[5 - i]; // Copy into buffer, has to be written reversed, so it is MSB first

// 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
return driver_->sendControlPacket(0x21, 9, 0x3f5, 0, 8, txbuf_);
} else if (joystickType_ == PS3_MOTION) {
// Slightly different than other PS3 units...
txbuf_[0] = 0x05;
for(uint8_t i = 0; i < 6; i++)
txbuf_[i + 1] = bdaddr[i]; // Order different looks like LSB First?

txbuf_[7] = 0x10;
txbuf_[8] = 0x01;
txbuf_[9] = 0x02;
txbuf_[10] = 0x12;
// 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
return driver_->sendControlPacket(0x21, 9, 0x305, 0, 11, txbuf_);
}
return false;
}

+ 84
- 7
keyboard.cpp View File

@@ -102,6 +102,9 @@ static const keyboard_force_boot_protocol_t keyboard_forceBootMode[] = {
#define print USBHost::print_
#define println USBHost::println_




void KeyboardController::init()
{
contribute_Pipes(mypipes, sizeof(mypipes)/sizeof(Pipe_t));
@@ -109,6 +112,7 @@ void KeyboardController::init()
contribute_String_Buffers(mystring_bufs, sizeof(mystring_bufs)/sizeof(strbuf_t));
driver_ready_for_device(this);
USBHIDParser::driver_ready_for_hid_collection(this);
BluetoothController::driver_ready_for_bluetooth(this);
force_boot_protocol = false; // start off assuming not
}

@@ -380,8 +384,13 @@ void KeyboardController::LEDS(uint8_t leds) {

void KeyboardController::updateLEDS() {
// Now lets tell keyboard new state.
mk_setup(setup, 0x21, 9, 0x200, 0, sizeof(leds_.byte)); // hopefully this sets leds
queue_Control_Transfer(device, &setup, &leds_.byte, this);
if (device != nullptr) {
// Only do it this way if we are a standard USB device
mk_setup(setup, 0x21, 9, 0x200, 0, sizeof(leds_.byte)); // hopefully this sets leds
queue_Control_Transfer(device, &setup, &leds_.byte, this);
} else {
// Bluetooth, need to setup back channel to Bluetooth controller.
}
}

//=============================================================================
@@ -394,12 +403,12 @@ void KeyboardController::updateLEDS() {
hidclaim_t KeyboardController::claim_collection(USBHIDParser *driver, Device_t *dev, uint32_t topusage)
{
// Lets try to claim a few specific Keyboard related collection/reports
//Serial.printf("KBH Claim %x\n", topusage);
//USBHDBGSerial.printf("KBH Claim %x\n", topusage);
if ((topusage != TOPUSAGE_SYS_CONTROL)
&& (topusage != TOPUSAGE_CONSUMER_CONTROL)
) return CLAIM_NO;
// only claim from one physical device
//Serial.println("KeyboardController claim collection");
//USBHDBGSerial.println("KeyboardController claim collection");
// Lets only claim if this is the same device as claimed Keyboard...
if (dev != device) return CLAIM_NO;
if (mydevice != NULL && dev != mydevice) return CLAIM_NO;
@@ -417,7 +426,7 @@ void KeyboardController::disconnect_collection(Device_t *dev)

void KeyboardController::hid_input_begin(uint32_t topusage, uint32_t type, int lgmin, int lgmax)
{
//Serial.printf("KPC:hid_input_begin TUSE: %x TYPE: %x Range:%x %x\n", topusage, type, lgmin, lgmax);
//USBHDBGSerial.printf("KPC:hid_input_begin TUSE: %x TYPE: %x Range:%x %x\n", topusage, type, lgmin, lgmax);
topusage_ = topusage; // remember which report we are processing.
hid_input_begin_ = true;
hid_input_data_ = false;
@@ -427,7 +436,7 @@ void KeyboardController::hid_input_data(uint32_t usage, int32_t value)
{
// Hack ignore 0xff00 high words as these are user values...
if ((usage & 0xffff0000) == 0xff000000) return;
//Serial.printf("KeyboardController: topusage= %x usage=%X, value=%d\n", topusage_, usage, value);
//USBHDBGSerial.printf("KeyboardController: topusage= %x usage=%X, value=%d\n", topusage_, usage, value);

// See if the value is in our keys_down list
usage &= 0xffff; // only keep the actual key
@@ -466,7 +475,7 @@ void KeyboardController::hid_input_data(uint32_t usage, int32_t value)

void KeyboardController::hid_input_end()
{
//Serial.println("KPC:hid_input_end");
//USBHDBGSerial.println("KPC:hid_input_end");
if (hid_input_begin_) {

// See if we received any data from parser if not, assume all keys released...
@@ -484,6 +493,69 @@ void KeyboardController::hid_input_end()
}
}

bool KeyboardController::claim_bluetooth(BluetoothController *driver, uint32_t bluetooth_class, uint8_t *remoteName)
{
USBHDBGSerial.printf("Keyboard Controller::claim_bluetooth - Class %x\n", bluetooth_class);
if ((((bluetooth_class & 0xff00) == 0x2500) || (((bluetooth_class & 0xff00) == 0x500))) && (bluetooth_class & 0x40)) {
if (remoteName && (strncmp((const char *)remoteName, "PLAYSTATION(R)3", 15) == 0)) {
USBHDBGSerial.printf("KeyboardController::claim_bluetooth Reject PS3 hack\n");
return false;
}
USBHDBGSerial.printf("KeyboardController::claim_bluetooth TRUE\n");
//btdevice = driver;
return true;
}
return false;
}

bool KeyboardController::remoteNameComplete(const uint8_t *remoteName)
{
// Real Hack some PS3 controllers bluetoot class is keyboard...
if (strncmp((const char *)remoteName, "PLAYSTATION(R)3", 15) == 0) {
USBHDBGSerial.printf(" KeyboardController::remoteNameComplete %s - Oops PS3 unclaim\n", remoteName);
return false;
}
return true;
}




bool KeyboardController::process_bluetooth_HID_data(const uint8_t *data, uint16_t length)
{
// Example DATA from bluetooth keyboard:
// 0 1 2 3 4 5 6 7 8 910 1 2 3 4 5 6 7
// LEN D
//BT rx2_data(18): 48 20 e 0 a 0 70 0 a1 1 2 0 0 0 0 0 0 0
//BT rx2_data(18): 48 20 e 0 a 0 70 0 a1 1 2 0 4 0 0 0 0 0
//BT rx2_data(18): 48 20 e 0 a 0 70 0 a1 1 2 0 0 0 0 0 0 0
// So Len=9 passed in data starting at report ID=1...
USBHDBGSerial.printf("KeyboardController::process_bluetooth_HID_data\n");
if (data[0] != 1) return false;
print(" KB Data: ");
print_hexbytes(data, length);
for (int i=2; i < length; i++) {
uint32_t key = prev_report[i];
if (key >= 4 && !contains(key, report)) {
key_release(prev_report[0], key);
}
}
for (int i=2; i < 8; i++) {
uint32_t key = data[i];
if (key >= 4 && !contains(key, prev_report)) {
key_press(data[1], key);
}
}
// Save away the data.. But shift down one byte... Don't need the report number
memcpy(prev_report, &data[1], 8);
return true;
}

void KeyboardController::release_bluetooth()
{
//btdevice = nullptr;
}

//*****************************************************************************
// Some simple query functions depend on which interface we are using...
//*****************************************************************************
@@ -492,6 +564,7 @@ uint16_t KeyboardController::idVendor()
{
if (device != nullptr) return device->idVendor;
if (mydevice != nullptr) return mydevice->idVendor;
if (btdevice != nullptr) return btdevice->idVendor;
return 0;
}

@@ -499,12 +572,14 @@ uint16_t KeyboardController::idProduct()
{
if (device != nullptr) return device->idProduct;
if (mydevice != nullptr) return mydevice->idProduct;
if (btdevice != nullptr) return btdevice->idProduct;
return 0;
}

const uint8_t *KeyboardController::manufacturer()
{
if ((device != nullptr) && (device->strbuf != nullptr)) return &device->strbuf->buffer[device->strbuf->iStrings[strbuf_t::STR_ID_MAN]];
if ((btdevice != nullptr) && (btdevice->strbuf != nullptr)) return &btdevice->strbuf->buffer[btdevice->strbuf->iStrings[strbuf_t::STR_ID_MAN]];
if ((mydevice != nullptr) && (mydevice->strbuf != nullptr)) return &mydevice->strbuf->buffer[mydevice->strbuf->iStrings[strbuf_t::STR_ID_MAN]];
return nullptr;
}
@@ -513,6 +588,7 @@ const uint8_t *KeyboardController::product()
{
if ((device != nullptr) && (device->strbuf != nullptr)) return &device->strbuf->buffer[device->strbuf->iStrings[strbuf_t::STR_ID_PROD]];
if ((mydevice != nullptr) && (mydevice->strbuf != nullptr)) return &mydevice->strbuf->buffer[mydevice->strbuf->iStrings[strbuf_t::STR_ID_PROD]];
if ((btdevice != nullptr) && (btdevice->strbuf != nullptr)) return &btdevice->strbuf->buffer[btdevice->strbuf->iStrings[strbuf_t::STR_ID_PROD]];
return nullptr;
}

@@ -520,6 +596,7 @@ const uint8_t *KeyboardController::serialNumber()
{
if ((device != nullptr) && (device->strbuf != nullptr)) return &device->strbuf->buffer[device->strbuf->iStrings[strbuf_t::STR_ID_SERIAL]];
if ((mydevice != nullptr) && (mydevice->strbuf != nullptr)) return &mydevice->strbuf->buffer[mydevice->strbuf->iStrings[strbuf_t::STR_ID_SERIAL]];
if ((btdevice != nullptr) && (btdevice->strbuf != nullptr)) return &btdevice->strbuf->buffer[btdevice->strbuf->iStrings[strbuf_t::STR_ID_SERIAL]];
return nullptr;
}


+ 2
- 0
keywords.txt View File

@@ -4,6 +4,7 @@ USBHub KEYWORD1
USBHIDParser KEYWORD1
KeyboardController KEYWORD1
MouseController KEYWORD1
DigitizerController KEYWORD1
MIDIDevice KEYWORD1
MIDIDevice_BigBuffer KEYWORD1
USBSerial KEYWORD1
@@ -90,6 +91,7 @@ setRumbleOn KEYWORD2
setLEDs KEYWORD2
joystickType KEYWORD2
PS3 LITERAL1
PS3_MOTION LITERAL1
PS4 LITERAL1
XBOXONE LITERAL1
XBOX360 LITERAL1

+ 62
- 2
mouse.cpp View File

@@ -25,11 +25,17 @@
#include "USBHost_t36.h" // Read this header first for key info


void MouseController::init()
{
USBHIDParser::driver_ready_for_hid_collection(this);
BluetoothController::driver_ready_for_bluetooth(this);
}


hidclaim_t MouseController::claim_collection(USBHIDParser *driver, Device_t *dev, uint32_t topusage)
{
// only claim Desktop/Mouse
if (topusage != 0x10002) return CLAIM_NO;
if ((topusage != 0x10002) && (topusage != 0x10001)) return CLAIM_NO;
// only claim from one physical device
if (mydevice != NULL && dev != mydevice) return CLAIM_NO;
mydevice = dev;
@@ -52,7 +58,7 @@ void MouseController::hid_input_begin(uint32_t topusage, uint32_t type, int lgmi

void MouseController::hid_input_data(uint32_t usage, int32_t value)
{
//Serial.printf("Mouse: usage=%X, value=%d\n", usage, value);
//USBHDBGSerial.printf("Mouse: usage=%X, value=%d\n", usage, value);
uint32_t usage_page = usage >> 16;
usage &= 0xFFFF;
if (usage_page == 9 && usage >= 1 && usage <= 8) {
@@ -101,3 +107,57 @@ void MouseController::mouseDataClear() {
}


bool MouseController::claim_bluetooth(BluetoothController *driver, uint32_t bluetooth_class, uint8_t *remoteName)
{
// How to handle combo devices?
USBHDBGSerial.printf("MouseController Controller::claim_bluetooth - Class %x\n", bluetooth_class);
if ((((bluetooth_class & 0xff00) == 0x2500) || (((bluetooth_class & 0xff00) == 0x500))) && (bluetooth_class & 0x80)) {
USBHDBGSerial.printf("MouseController::claim_bluetooth TRUE\n");
btdevice = (Device_t*)driver; // remember this way
return true;
}
return false;
}

bool MouseController::process_bluetooth_HID_data(const uint8_t *data, uint16_t length)
{
// Example DATA from bluetooth keyboard:
// 0 1 2 3 4 5 6 7 8 910 1 2 3 4 5 6 7
// LEN D
//BT rx2_data(14): b 20 a 0 6 0 71 0 a1 2 0 9 fe 0
//BT rx2_data(14): b 20 a 0 6 0 71 0 a1 2 0 8 fd 0

// So Len=9 passed in data starting at report ID=1...
if (length == 0) return false;
#ifdef USBHOST_PRINT_DEBUG
USBHDBGSerial.printf("MouseController::process_bluetooth_HID_data %d\n", length);
USBHDBGSerial.printf(" Mouse Data: ");
const uint8_t *p = (const uint8_t *)data;
uint16_t len = length;
do {
if (*p < 16) USBHDBGSerial.print('0');
USBHDBGSerial.print(*p++, HEX);
USBHDBGSerial.print(' ');
} while (--len);
USBHDBGSerial.println();
#endif
// Looks like report 2 is for the mouse info.
if (data[0] != 2) return false;
buttons = data[1];
mouseX = (int8_t)data[2];
mouseY = (int8_t)data[3];
if (length >= 5) {
wheel = (int8_t)data[4];
if (length >= 6) {
wheelH = (int8_t)data[5];
}
}
mouseEvent = true;

return true;
}

void MouseController::release_bluetooth()
{
//btdevice = nullptr;
}

+ 145
- 145
print.cpp View File

@@ -34,39 +34,39 @@
void USBHost::print_(const Transfer_t *transfer)
{
if (!((uint32_t)transfer & 0xFFFFFFE0)) return;
Serial.print("Transfer @ ");
Serial.println(((uint32_t)transfer & 0xFFFFFFE0), HEX);
Serial.print(" next: ");
Serial.println(transfer->qtd.next, HEX);
Serial.print(" anext: ");
Serial.println(transfer->qtd.alt_next, HEX);
Serial.print(" token: ");
Serial.println(transfer->qtd.token, HEX);
Serial.print(" bufs: ");
USBHDBGSerial.print("Transfer @ ");
USBHDBGSerial.println(((uint32_t)transfer & 0xFFFFFFE0), HEX);
USBHDBGSerial.print(" next: ");
USBHDBGSerial.println(transfer->qtd.next, HEX);
USBHDBGSerial.print(" anext: ");
USBHDBGSerial.println(transfer->qtd.alt_next, HEX);
USBHDBGSerial.print(" token: ");
USBHDBGSerial.println(transfer->qtd.token, HEX);
USBHDBGSerial.print(" bufs: ");
for (int i=0; i < 5; i++) {
Serial.print(transfer->qtd.buffer[i], HEX);
if (i < 4) Serial.print(',');
USBHDBGSerial.print(transfer->qtd.buffer[i], HEX);
if (i < 4) USBHDBGSerial.print(',');
}
Serial.println();
USBHDBGSerial.println();
}

void USBHost::print_(const Transfer_t *first, const Transfer_t *last)
{
Serial.print("Transfer Followup List ");
Serial.print((uint32_t)first, HEX);
Serial.print(" to ");
Serial.println((uint32_t)last, HEX);
Serial.println(" forward:");
USBHDBGSerial.print("Transfer Followup List ");
USBHDBGSerial.print((uint32_t)first, HEX);
USBHDBGSerial.print(" to ");
USBHDBGSerial.println((uint32_t)last, HEX);
USBHDBGSerial.println(" forward:");
while (first) {
Serial.print(" ");
Serial.print((uint32_t)first, HEX);
USBHDBGSerial.print(" ");
USBHDBGSerial.print((uint32_t)first, HEX);
print_token(first->qtd.token);
first = first->next_followup;
}
Serial.println(" backward:");
USBHDBGSerial.println(" backward:");
while (last) {
Serial.print(" ");
Serial.print((uint32_t)last, HEX);
USBHDBGSerial.print(" ");
USBHDBGSerial.print((uint32_t)last, HEX);
print_token(last->qtd.token);
last = last->prev_followup;
}
@@ -76,163 +76,163 @@ void USBHost::print_token(uint32_t token)
{
switch ((token >> 8) & 3) {
case 0:
Serial.print(" OUT ");
Serial.println((token >> 16) & 0x7FFF);
USBHDBGSerial.print(" OUT ");
USBHDBGSerial.println((token >> 16) & 0x7FFF);
break;
case 1:
Serial.print(" IN ");
Serial.println((token >> 16) & 0x7FFF);
USBHDBGSerial.print(" IN ");
USBHDBGSerial.println((token >> 16) & 0x7FFF);
break;
case 2:
Serial.println(" SETUP");
USBHDBGSerial.println(" SETUP");
break;
default:
Serial.println(" unknown");
USBHDBGSerial.println(" unknown");
}
}

void USBHost::print_(const Pipe_t *pipe)
{
if (!((uint32_t)pipe & 0xFFFFFFE0)) return;
Serial.print("Pipe ");
if (pipe->type == 0) Serial.print("control");
else if (pipe->type == 1) Serial.print("isochronous");
else if (pipe->type == 2) Serial.print("bulk");
else if (pipe->type == 3) Serial.print("interrupt");
Serial.print(pipe->direction ? " IN" : " OUT");
Serial.print(" @ ");
Serial.println((uint32_t)pipe, HEX);
Serial.print(" horiz link: ");
Serial.println(pipe->qh.horizontal_link, HEX);
Serial.print(" capabilities: ");
Serial.print(pipe->qh.capabilities[0], HEX);
Serial.print(',');
Serial.println(pipe->qh.capabilities[1], HEX);
Serial.println(" overlay:");
Serial.print(" cur: ");
Serial.println(pipe->qh.current, HEX);
Serial.print(" next: ");
Serial.println(pipe->qh.next, HEX);
Serial.print(" anext: ");
Serial.println(pipe->qh.alt_next, HEX);
Serial.print(" token: ");
Serial.println(pipe->qh.token, HEX);
Serial.print(" bufs: ");
USBHDBGSerial.print("Pipe ");
if (pipe->type == 0) USBHDBGSerial.print("control");
else if (pipe->type == 1) USBHDBGSerial.print("isochronous");
else if (pipe->type == 2) USBHDBGSerial.print("bulk");
else if (pipe->type == 3) USBHDBGSerial.print("interrupt");
USBHDBGSerial.print(pipe->direction ? " IN" : " OUT");
USBHDBGSerial.print(" @ ");
USBHDBGSerial.println((uint32_t)pipe, HEX);
USBHDBGSerial.print(" horiz link: ");
USBHDBGSerial.println(pipe->qh.horizontal_link, HEX);
USBHDBGSerial.print(" capabilities: ");
USBHDBGSerial.print(pipe->qh.capabilities[0], HEX);
USBHDBGSerial.print(',');
USBHDBGSerial.println(pipe->qh.capabilities[1], HEX);
USBHDBGSerial.println(" overlay:");
USBHDBGSerial.print(" cur: ");
USBHDBGSerial.println(pipe->qh.current, HEX);
USBHDBGSerial.print(" next: ");
USBHDBGSerial.println(pipe->qh.next, HEX);
USBHDBGSerial.print(" anext: ");
USBHDBGSerial.println(pipe->qh.alt_next, HEX);
USBHDBGSerial.print(" token: ");
USBHDBGSerial.println(pipe->qh.token, HEX);
USBHDBGSerial.print(" bufs: ");
for (int i=0; i < 5; i++) {
Serial.print(pipe->qh.buffer[i], HEX);
if (i < 4) Serial.print(',');
USBHDBGSerial.print(pipe->qh.buffer[i], HEX);
if (i < 4) USBHDBGSerial.print(',');
}
Serial.println();
USBHDBGSerial.println();
const Transfer_t *t = (Transfer_t *)pipe->qh.next;
while (((uint32_t)t & 0xFFFFFFE0)) {
print_(t);
t = (Transfer_t *)t->qtd.next;
}
//Serial.print();
//USBHDBGSerial.print();
}

void USBHost::print_driverlist(const char *name, const USBDriver *driver)
{
Serial.print("USBDriver (");
Serial.print(name);
Serial.print(") list: ");
USBHDBGSerial.print("USBDriver (");
USBHDBGSerial.print(name);
USBHDBGSerial.print(") list: ");
if (driver == NULL) {
Serial.println("(empty");
USBHDBGSerial.println("(empty");
return;
}
uint32_t count=0;
for (const USBDriver *p = driver; p; p = p->next) {
Serial.print((uint32_t)p, HEX);
if (p->next) Serial.print(" -> ");
USBHDBGSerial.print((uint32_t)p, HEX);
if (p->next) USBHDBGSerial.print(" -> ");
if (++count > 30) {
Serial.println("abort:list too long");
USBHDBGSerial.println("abort:list too long");
return;
}
}
Serial.println();
USBHDBGSerial.println();
}

void USBHost::print_qh_list(const Pipe_t *list)
{
if (!list) {
Serial.println("(empty)");
USBHDBGSerial.println("(empty)");
return;
}
const Pipe_t *node = list;
while (1) {
Serial.print((uint32_t)node, HEX);
USBHDBGSerial.print((uint32_t)node, HEX);
node = (const Pipe_t *)(node->qh.horizontal_link & 0xFFFFFFE0);
if (!node) break;
if (node == list) {
Serial.print(" (loops)");
USBHDBGSerial.print(" (loops)");
break;
}
Serial.print(" -> ");
USBHDBGSerial.print(" -> ");
}
Serial.println();
USBHDBGSerial.println();
}

static void print_class_subclass_protocol(uint8_t c, uint8_t s, uint8_t p)
{
Serial.print(c);
if (c == 3) Serial.print("(HID)");
if (c == 8) Serial.print("(Mass Storage)");
if (c == 9) Serial.print("(Hub)");
Serial.print(" / ");
Serial.print(s);
if (c == 3 && s == 1) Serial.print("(Boot)");
if (c == 8 && s == 6) Serial.print("(SCSI)");
Serial.print(" / ");
Serial.print(p);
if (c == 3 && s == 1 && p == 1) Serial.print("(Keyboard)");
if (c == 3 && s == 1 && p == 2) Serial.print("(Mouse)");
if (c == 8 && s == 6 && p == 0x50) Serial.print("(Bulk Only)");
if (c == 8 && s == 6 && p == 0x62) Serial.print("(UAS)");
if (c == 9 && s == 0 && p == 1) Serial.print("(Single-TT)");
if (c == 9 && s == 0 && p == 2) Serial.print("(Multi-TT)");
Serial.println();
USBHDBGSerial.print(c);
if (c == 3) USBHDBGSerial.print("(HID)");
if (c == 8) USBHDBGSerial.print("(Mass Storage)");
if (c == 9) USBHDBGSerial.print("(Hub)");
USBHDBGSerial.print(" / ");
USBHDBGSerial.print(s);
if (c == 3 && s == 1) USBHDBGSerial.print("(Boot)");
if (c == 8 && s == 6) USBHDBGSerial.print("(SCSI)");
USBHDBGSerial.print(" / ");
USBHDBGSerial.print(p);
if (c == 3 && s == 1 && p == 1) USBHDBGSerial.print("(Keyboard)");
if (c == 3 && s == 1 && p == 2) USBHDBGSerial.print("(Mouse)");
if (c == 8 && s == 6 && p == 0x50) USBHDBGSerial.print("(Bulk Only)");
if (c == 8 && s == 6 && p == 0x62) USBHDBGSerial.print("(UAS)");
if (c == 9 && s == 0 && p == 1) USBHDBGSerial.print("(Single-TT)");
if (c == 9 && s == 0 && p == 2) USBHDBGSerial.print("(Multi-TT)");
USBHDBGSerial.println();
}

void USBHost::print_device_descriptor(const uint8_t *p)
{
Serial.println("Device Descriptor:");
Serial.print(" ");
USBHDBGSerial.println("Device Descriptor:");
USBHDBGSerial.print(" ");
print_hexbytes(p, p[0]);
if (p[0] != 18) {
Serial.println("error: device must be 18 bytes");
USBHDBGSerial.println("error: device must be 18 bytes");
return;
}
if (p[1] != 1) {
Serial.println("error: device must type 1");
USBHDBGSerial.println("error: device must type 1");
return;
}
Serial.printf(" VendorID = %04X, ProductID = %04X, Version = %04X",
USBHDBGSerial.printf(" VendorID = %04X, ProductID = %04X, Version = %04X",
p[8] | (p[9] << 8), p[10] | (p[11] << 8), p[12] | (p[13] << 8));
Serial.println();
Serial.print(" Class/Subclass/Protocol = ");
USBHDBGSerial.println();
USBHDBGSerial.print(" Class/Subclass/Protocol = ");
print_class_subclass_protocol(p[4], p[5], p[6]);
Serial.print(" Number of Configurations = ");
Serial.println(p[17]);
USBHDBGSerial.print(" Number of Configurations = ");
USBHDBGSerial.println(p[17]);
}

void USBHost::print_config_descriptor(const uint8_t *p, uint32_t maxlen)
{
// Descriptor Types: (USB 2.0, page 251)
Serial.println("Configuration Descriptor:");
Serial.print(" ");
USBHDBGSerial.println("Configuration Descriptor:");
USBHDBGSerial.print(" ");
print_hexbytes(p, p[0]);
if (p[0] != 9) {
Serial.println("error: config must be 9 bytes");
USBHDBGSerial.println("error: config must be 9 bytes");
return;
}
if (p[1] != 2) {
Serial.println("error: config must type 2");
USBHDBGSerial.println("error: config must type 2");
return;
}
Serial.print(" NumInterfaces = ");
Serial.println(p[4]);
Serial.print(" ConfigurationValue = ");
Serial.println(p[5]);
USBHDBGSerial.print(" NumInterfaces = ");
USBHDBGSerial.println(p[4]);
USBHDBGSerial.print(" ConfigurationValue = ");
USBHDBGSerial.println(p[5]);

uint32_t len = p[2] | (p[3] << 8);
if (len > maxlen) len = maxlen;
@@ -241,48 +241,48 @@ void USBHost::print_config_descriptor(const uint8_t *p, uint32_t maxlen)

while (len > 0) {
if (p[0] > len) {
Serial.print(" ");
USBHDBGSerial.print(" ");
print_hexbytes(p, len);
Serial.println(" error: length beyond total data size");
USBHDBGSerial.println(" error: length beyond total data size");
break;
}
Serial.print(" ");
USBHDBGSerial.print(" ");
print_hexbytes(p, p[0]);
if (p[0] == 9 && p[1] == 4) { // Interface Descriptor
Serial.print(" Interface = ");
Serial.println(p[2]);
Serial.print(" Number of endpoints = ");
Serial.println(p[4]);
Serial.print(" Class/Subclass/Protocol = ");
USBHDBGSerial.print(" Interface = ");
USBHDBGSerial.println(p[2]);
USBHDBGSerial.print(" Number of endpoints = ");
USBHDBGSerial.println(p[4]);
USBHDBGSerial.print(" Class/Subclass/Protocol = ");
print_class_subclass_protocol(p[5], p[6], p[7]);
} else if (p[0] >= 7 && p[0] <= 9 && p[1] == 5) { // Endpoint Descriptor
Serial.print(" Endpoint = ");
Serial.print(p[2] & 15);
Serial.println((p[2] & 128) ? " IN" : " OUT");
Serial.print(" Type = ");
USBHDBGSerial.print(" Endpoint = ");
USBHDBGSerial.print(p[2] & 15);
USBHDBGSerial.println((p[2] & 128) ? " IN" : " OUT");
USBHDBGSerial.print(" Type = ");
switch (p[3] & 3) {
case 0: Serial.println("Control"); break;
case 1: Serial.println("Isochronous"); break;
case 2: Serial.println("Bulk"); break;
case 3: Serial.println("Interrupt"); break;
case 0: USBHDBGSerial.println("Control"); break;
case 1: USBHDBGSerial.println("Isochronous"); break;
case 2: USBHDBGSerial.println("Bulk"); break;
case 3: USBHDBGSerial.println("Interrupt"); break;
}
Serial.print(" Max Size = ");
Serial.println(p[4] | (p[5] << 8));
Serial.print(" Polling Interval = ");
Serial.println(p[6]);
USBHDBGSerial.print(" Max Size = ");
USBHDBGSerial.println(p[4] | (p[5] << 8));
USBHDBGSerial.print(" Polling Interval = ");
USBHDBGSerial.println(p[6]);
} else if (p[0] == 8 && p[1] == 11) { // IAD
Serial.print(" Interface Association = ");
Serial.print(p[2]);
Serial.print(" through ");
Serial.println(p[2] + p[3] - 1);
Serial.print(" Class / Subclass / Protocol = ");
USBHDBGSerial.print(" Interface Association = ");
USBHDBGSerial.print(p[2]);
USBHDBGSerial.print(" through ");
USBHDBGSerial.println(p[2] + p[3] - 1);
USBHDBGSerial.print(" Class / Subclass / Protocol = ");
print_class_subclass_protocol(p[4], p[5], p[7]);
} else if (p[0] >= 9 && p[1] == 0x21) { // HID
Serial.print(" HID, ");
Serial.print(p[5]);
Serial.print(" report descriptor");
if (p[5] != 1) Serial.print('s');
Serial.println();
USBHDBGSerial.print(" HID, ");
USBHDBGSerial.print(p[5]);
USBHDBGSerial.print(" report descriptor");
if (p[5] != 1) USBHDBGSerial.print('s');
USBHDBGSerial.println();
}
len -= p[0];
p += p[0];
@@ -293,25 +293,25 @@ void USBHost::print_string_descriptor(const char *name, const uint8_t *p)
{
uint32_t len = p[0];
if (len < 4) return;
Serial.print(name);
USBHDBGSerial.print(name);
len -= 2;
p += 2;
while (len >= 2) {
uint32_t c = p[0] | (p[1] << 8);
if (c < 0x80) {
Serial.write(c);
USBHDBGSerial.write(c);
} else if (c < 0x800) {
Serial.write((c >> 6) | 0xC0);
Serial.write((c & 0x3F) | 0x80);
USBHDBGSerial.write((c >> 6) | 0xC0);
USBHDBGSerial.write((c & 0x3F) | 0x80);
} else {
Serial.write((c >> 12) | 0xE0);
Serial.write(((c >> 6) & 0x3F) | 0x80);
Serial.write((c & 0x3F) | 0x80);
USBHDBGSerial.write((c >> 12) | 0xE0);
USBHDBGSerial.write(((c >> 6) & 0x3F) | 0x80);
USBHDBGSerial.write((c & 0x3F) | 0x80);
}
len -= 2;
p += 2;
}
Serial.println();
USBHDBGSerial.println();
//print_hexbytes(p, p[0]);
}

@@ -321,11 +321,11 @@ void USBHost::print_hexbytes(const void *ptr, uint32_t len)
if (ptr == NULL || len == 0) return;
const uint8_t *p = (const uint8_t *)ptr;
do {
if (*p < 16) Serial.print('0');
Serial.print(*p++, HEX);
Serial.print(' ');
if (*p < 16) USBHDBGSerial.print('0');
USBHDBGSerial.print(*p++, HEX);
USBHDBGSerial.print(' ');
} while (--len);
Serial.println();
USBHDBGSerial.println();
}

#endif

+ 8
- 8
rawhid.cpp View File

@@ -34,7 +34,7 @@ hidclaim_t RawHIDController::claim_collection(USBHIDParser *driver, Device_t *de
{
// only claim RAWHID devices currently: 16c0:0486
#ifdef USBHOST_PRINT_DEBUG
Serial.printf("Rawhid Claim: %x:%x usage: %x\n", dev->idVendor, dev->idProduct, topusage);
USBHDBGSerial.printf("Rawhid Claim: %x:%x usage: %x\n", dev->idVendor, dev->idProduct, topusage);
#endif

if ((dev->idVendor != 0x16c0 || (dev->idProduct) != 0x486)) return CLAIM_NO;
@@ -59,7 +59,7 @@ void RawHIDController::disconnect_collection(Device_t *dev)
bool RawHIDController::hid_process_in_data(const Transfer_t *transfer)
{
#ifdef USBHOST_PRINT_DEBUG
Serial.printf("RawHIDController::hid_process_in_data: %x\n", usage_);
USBHDBGSerial.printf("RawHIDController::hid_process_in_data: %x\n", usage_);
#endif

if (receiveCB) {
@@ -71,7 +71,7 @@ bool RawHIDController::hid_process_in_data(const Transfer_t *transfer)
bool RawHIDController::hid_process_out_data(const Transfer_t *transfer)
{
#ifdef USBHOST_PRINT_DEBUG
Serial.printf("RawHIDController::hid_process_out_data: %x\n", usage_);
USBHDBGSerial.printf("RawHIDController::hid_process_out_data: %x\n", usage_);
#endif
return true;
}
@@ -89,7 +89,7 @@ void RawHIDController::hid_input_begin(uint32_t topusage, uint32_t type, int lgm
// These should not be called as we are claiming the whole interface and not
// allowing the parse to happen
#ifdef USBHOST_PRINT_DEBUG
Serial.printf("RawHID::hid_input_begin %x %x %x %x\n", topusage, type, lgmin, lgmax);
USBHDBGSerial.printf("RawHID::hid_input_begin %x %x %x %x\n", topusage, type, lgmin, lgmax);
#endif
//hid_input_begin_ = true;
}
@@ -99,9 +99,9 @@ void RawHIDController::hid_input_data(uint32_t usage, int32_t value)
// These should not be called as we are claiming the whole interface and not
// allowing the parse to happen
#ifdef USBHOST_PRINT_DEBUG
Serial.printf("RawHID: usage=%X, value=%d", usage, value);
if ((value >= ' ') && (value <='~')) Serial.printf("(%c)", value);
Serial.println();
USBHDBGSerial.printf("RawHID: usage=%X, value=%d", usage, value);
if ((value >= ' ') && (value <='~')) USBHDBGSerial.printf("(%c)", value);
USBHDBGSerial.println();
#endif
}

@@ -110,7 +110,7 @@ void RawHIDController::hid_input_end()
// These should not be called as we are claiming the whole interface and not
// allowing the parse to happen
#ifdef USBHOST_PRINT_DEBUG
Serial.println("RawHID::hid_input_end");
USBHDBGSerial.println("RawHID::hid_input_end");
#endif
// if (hid_input_begin_) {
// hid_input_begin_ = false;

Loading…
Cancel
Save