T3.6 USB Host - Bluetooth

FYI - I have been playing around some more trying to support multiple Bluetooth devices like a mouse and keyboard at the same time.

This in between other distractions like: Life, health, T4, ... ;)

I am making some progress, but it is needing me to change a few underlying things. Like I was sort of hard coding:
uint16_t control_dcid_ = 0x70;
uint16_t interrupt_dcid_ = 0x71;

to 0x70 and 0x71, except when PS3 overwrote it. So instead I start off at 0x70 and increment them... With this, when I do it, when both mouse and keyboard attach they are given different values...

Then for example if I connect the keyboard and type a key... You see something like this (debug output on)

Code:
BT rx2_data(18): 48 20 e 0 a 0 71 0 a1 1 0 0 0 0 0 0 0 0 
HID HDR Data: len: 10, Type: 1
KeyboardController::process_bluetooth_HID_data
  KB Data: 01 00 00 00 00 00 00 00 00 
  release, key=11

Then I connect the Mouse... And then start receiving mouse messages:
Code:
=====================
BT rx2_data(14): 43 20 a 0 6 0 73 0 a1 2 0 0 0 0 
HID HDR Data: len: 6, Type: 2
MouseController::process_bluetooth_HID_data 5
  Mouse Data: 02 00 00 00 00 
Mouse: buttons = 0,  mouseX = 0,  mouseY = 0,  wheel = 0,  wheelH = 0

=====================
BT rx2_data(14): 43 20 a 0 6 0 73 0 a1 2 0 0 2 0 
HID HDR Data: len: 6, Type: 2
MouseController::process_bluetooth_HID_data 5
  Mouse Data: 02 00 00 02 00 
Mouse: buttons = 0,  mouseX = 0,  mouseY = 2,  wheel = 0,  wheelH = 0

=====================

Note at this point current code if I then typed a letter on the keyboard, the mouse code would try to process it...
Both are actually connected at this point, but code is setup that last one wins...

But the information is here, that is if you look at keyboard data above: 48 20 e 0 a 0 71 0 a1 1 0 0 0 0 0 0 0 0

The green part is the actual keyboard data: the first 8 bytes are HCI and L2CAP headers, the interesting one in red 71 is the connection ID...

Then again if you look at Mouse data: 43 20 a 0 6 0 73 0 a1 2 0 0 2 0

You see, that Keyboard is on conversation 0x71 and mouse on 0x73, which current code ignores. So now in process of moving the connection information into an array of sub-structures which contain the connection information including pointer to which object (mouse or keyboard...), And then when rx2_data comes through look at that connection ID and pass it off to hopefully the right BT client object...

Currently limiting to 4 BT connections... Will see how well this works and/or maybe instead move some/all of this data into the BTHID objects...

Currently working in new github branch, so that if BT branch PR is integrated, this won't interfere... If the new branch works well, then will Pull it into BT branch...
 
Quick update (in case anyone wants to play along)...

Currently I have a keyboard (Rii) and Mouse (Tecknet) that were already paired with dongle... Then used test app Mouse_KeyboardBT ... I have most of the debug stuff turned off in the below run,
But you can now see where it is now having the keyboard object processing the keyboard data and the mouse object support the mouse data...

Still WIP, but I put it up in new branch: https://github.com/KurtE/USBHost_t36/tree/WIP2-Bluetooth-multi


Code:
USB Host Testing
960
*** Device Bluet a12:1 - connected ***
  product: CSR8510 A10
  BDADDR: 0:0:0:0:0:0
BluetoothController::find_driver  driver 20003198
Keyboard Controller::claim_bluetooth - Class 540
KeyboardController::claim_bluetooth TRUE
    *** Claimed ***
KeyboardController::process_bluetooth_HID_data
KeyboardController::process_bluetooth_HID_data
key 'a'  97 MOD: KeyboardController::process_bluetooth_HID_data
KeyboardController::process_bluetooth_HID_data
key 'b'  98 MOD: KeyboardController::process_bluetooth_HID_data
KeyboardController::process_bluetooth_HID_data
key 'c'  99 MOD: KeyboardController::process_bluetooth_HID_data
KeyboardController::process_bluetooth_HID_data
key 'd'  100 MOD: KeyboardController::process_bluetooth_HID_data
BluetoothController::find_driver  driver 20003198
Keyboard Controller::claim_bluetooth - Class 580
  driver 20006178
MouseController Controller::claim_bluetooth - Class 580
MouseController::claim_bluetooth TRUE
    *** Claimed ***
*** BTHID Device Mouse(BT) - connected ***
Mouse: buttons = 1,  mouseX = 0,  mouseY = 0,  wheel = 0,  wheelH = 0
Mouse: buttons = 0,  mouseX = 0,  mouseY = 0,  wheel = 0,  wheelH = 0
Mouse: buttons = 0,  mouseX = 3,  mouseY = -40,  wheel = 0,  wheelH = 0
Mouse: buttons = 0,  mouseX = 0,  mouseY = 0,  wheel = 0,  wheelH = 0
Mouse: buttons = 0,  mouseX = 12,  mouseY = -3,  wheel = 0,  wheelH = 0
Mouse: buttons = 0,  mouseX = 2,  mouseY = 0,  wheel = 0,  wheelH = 0
Mouse: buttons = 0,  mouseX = 13,  mouseY = -1,  wheel = 0,  wheelH = 0
Mouse: buttons = 0,  mouseX = 13,  mouseY = -1,  wheel = 0,  wheelH = 0
Mouse: buttons = 0,  mouseX = 10,  mouseY = 0,  wheel = 0,  wheelH = 0
Mouse: buttons = 0,  mouseX = 7,  mouseY = 0,  wheel = 0,  wheelH = 0
Mouse: buttons = 0,  mouseX = 4,  mouseY = 0,  wheel = 0,  wheelH = 0
Mouse: buttons = 0,  mouseX = 3,  mouseY = 0,  wheel = 0,  wheelH = 0
Mouse: buttons = 0,  mouseX = 1,  mouseY = 0,  wheel = 0,  wheelH = 0
Mouse: buttons = 0,  mouseX = -1,  mouseY = 0,  wheel = 0,  wheelH = 0
Mouse: buttons = 0,  mouseX = -2,  mouseY = 0,  wheel = 0,  wheelH = 0
Mouse: buttons = 0,  mouseX = -2,  mouseY = 0,  wheel = 0,  wheelH = 0
Mouse: buttons = 0,  mouseX = -1,  mouseY = 0,  wheel = 0,  wheelH = 0
Mouse: buttons = 0,  mouseX = -2,  mouseY = 0,  wheel = 0,  wheelH = 0
Mouse: buttons = 0,  mouseX = -2,  mouseY = 0,  wheel = 0,  wheelH = 0
Mouse: buttons = 0,  mouseX = -1,  mouseY = 0,  wheel = 0,  wheelH = 0
Mouse: buttons = 0,  mouseX = -2,  mouseY = 2,  wheel = 0,  wheelH = 0
Mouse: buttons = 0,  mouseX = -3,  mouseY = 4,  wheel = 0,  wheelH = 0
Mouse: buttons = 0,  mouseX = -2,  mouseY = 3,  wheel = 0,  wheelH = 0
Mouse: buttons = 0,  mouseX = -4,  mouseY = 3,  wheel = 0,  wheelH = 0
Mouse: buttons = 0,  mouseX = -5,  mouseY = 3,  wheel = 0,  wheelH = 0
Mouse: buttons = 0,  mouseX = -5,  mouseY = 4,  wheel = 0,  wheelH = 0
Mouse: buttons = 0,  mouseX = -4,  mouseY = 2,  wheel = 0,  wheelH = 0
Mouse: buttons = 0,  mouseX = -3,  mouseY = 2,  wheel = 0,  wheelH = 0
Mouse: buttons = 0,  mouseX = -4,  mouseY = 1,  wheel = 0,  wheelH = 0
Mouse: buttons = 0,  mouseX = -5,  mouseY = 0,  wheel = 0,  wheelH = 0
Mouse: buttons = 0,  mouseX = -2,  mouseY = 1,  wheel = 0,  wheelH = 0
Mouse: buttons = 0,  mouseX = -3,  mouseY = 1,  wheel = 0,  wheelH = 0
Mouse: buttons = 0,  mouseX = -6,  mouseY = 1,  wheel = 0,  wheelH = 0
Mouse: buttons = 0,  mouseX = -7,  mouseY = 1,  wheel = 0,  wheelH = 0
Mouse: buttons = 0,  mouseX = -7,  mouseY = 0,  wheel = 0,  wheelH = 0
Mouse: buttons = 0,  mouseX = -5,  mouseY = 0,  wheel = 0,  wheelH = 0
Mouse: buttons = 0,  mouseX = -4,  mouseY = 0,  wheel = 0,  wheelH = 0
Mouse: buttons = 0,  mouseX = -3,  mouseY = 0,  wheel = 0,  wheelH = 0
Mouse: buttons = 0,  mouseX = 0,  mouseY = 1,  wheel = 0,  wheelH = 0
KeyboardController::process_bluetooth_HID_data
key 'd'  100 MOD: KeyboardController::process_bluetooth_HID_data
 
That looks like very good development KurtE!

I've run lots of the samples - but never beyond the 'casual user' mode just expecting it to work, so having this low level code resolve out multiple devices where it would not before is a great advance.
 
I'm seeing that BLE is its own thing versus regular Bluetooth - is getting BLE done/do-able on Teensy USBHost? I'm glancing around with web searches and not sure how much I don't know yet :) I'm supposing that would take a Bt dongle that has BLE support and then it would be a whole extra set of code to recognize and support BLW connects?
 
@defragster - Thanks, some of it is me, learning (sometimes slowly ;) ) as I go. So I am happy that I have at least some of the multiple devices working (limping) along... I still need to see about some of the message routing and picking right values in some cases.

Example: When mouse connects and keyboard connects, and maybe the user code wants to send back to keyboard which LEDS should be set (Caps lock, Scroll lock...)

Also need to check out multiple PS3 devices and see if I can change the 2nd one to not be 40, 41, but instead 42...

BLE (Bluetooth Low Energy) - Has it's own volume (6) in the Bluetooth core manual, with all new different messages and data flows... Ran into this with the Microsoft Sculpt Bluetooth mouse, which I have not been able to setup yet... Maybe also with the Logitech...

So yes some whole new set of code needs to be written...
 
@defragster, @mjs513 and ... - Still playing here, mainly with trying to get two PS3 controllers to work with each other... Running into some issues, that I need to fix.

Like, the BTHID objects need to test that they are not already being used before they try to accept a new connection... Have some other distractions for today...

Here is start of hacked up viewer that should in the end show two different joysticks data at same time on ILI9341_t3n ...

Code:
//=============================================================================
// 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);
USBHIDParser hid1(myusb);
USBHIDParser hid2(myusb);
JoystickController joystick1(myusb);
JoystickController joystick2(myusb);
//BluetoothController bluet(myusb, true, "0000");   // Version does pairing to device
BluetoothController bluet(myusb);   // version assumes it already was paired

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

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

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

bool hid_driver_active[CNT_HIDDEVICES] = {false};

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

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

// Save away values for buttons, x, y, wheel
typedef struct {
  uint32_t buttons_cur = 0;
  int x = 0,
      y = 0,
      x2 = 0,
      y2 = 0,
      L1 = 0,
      R1 = 0;
  int wheel = 0;
  int axis[64];
  uint32_t buttons_prev = 0;
  uint32_t buttons;
  uint8_t left_trigger_value = 0;
  uint8_t right_trigger_value = 0;

} joystick_save_data_t;

joystick_save_data_t joy_data[2];

elapsedMillis heartbeat;
uint8_t heartbeat_index = 99;
static const uint8_t heartbeat_chars[] = {'-', '/', '|', '\\'};


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

uint64_t joystick_full_notify_mask = (uint64_t) - 1;


//=============================================================================
// function declares
//=============================================================================
extern void ProcessJoystickData(JoystickController &joy, joystick_save_data_t &jsdata, uint16_t x_disp);


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

  Serial1.begin(2000000);
  while (!Serial && millis() < 3000) ; // wait for Arduino Serial Monitor
  Serial.println("\n\nUSB Host multiple joystick Testing");
  myusb.begin();

  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);
  heartbeat = 0;
}

#define JOYSTICK_DATA_X1 75
#define JOYSTICK_DATA_X2 175

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

  // Update the display with
  UpdateActiveDeviceInfo();

  // And joystick data
  ProcessJoystickData(joystick1, joy_data[0], JOYSTICK_DATA_X1);
  ProcessJoystickData(joystick2, joy_data[1], JOYSTICK_DATA_X2);
  if (heartbeat > 250) {
    heartbeat = 0;
    if (++heartbeat_index > sizeof(heartbeat_chars)) heartbeat_index = 0;
    tft.setCursor(tft.width() - 10, tft.height() - 10);
    tft.setTextColor(ILI9341_RED, ILI9341_BLACK);
    tft.setFont(Arial_12);
    tft.write(heartbeat_chars[heartbeat_index]);
    tft.updateScreen();

  }
}


//=============================================================================
// 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
        int16_t x;
        tft.getCursor(&x, &y_position_after_device_info);

      }
    }
  }
}

//=============================================================================
// 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);
}


//=============================================================================
// ProcessJoystickData
//=============================================================================

void ProcessJoystickData(JoystickController &joy, joystick_save_data_t &jsdata, uint16_t x_disp) {
  if (joy.available()) {
    uint64_t axis_mask = joy.axisMask();
    uint64_t axis_changed_mask = joy.axisChangedMask();
    Serial.print("Joystick: buttons = ");
    jsdata.buttons = joy.getButtons();
    Serial.print(jsdata.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, joy.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, joy.getAxis(i));
        }
      }
    } else {
      for (uint8_t i = 0; axis_mask != 0; i++, axis_mask >>= 1) {
        if (axis_mask & 1) {
          Serial.printf(" %d:%d", i, joy.getAxis(i));
        }
      }
    }
    for (uint8_t i = 0; i < 64; i++) {
      jsdata.axis[i] = joy.getAxis(i);
    }
    uint8_t ltv;
    uint8_t rtv;
    switch (joy.joystickType()) {
      default:
        break;
      case JoystickController::PS4:
        ltv = joy.getAxis(3);
        rtv = joy.getAxis(4);
        if ((ltv != jsdata.left_trigger_value) || (rtv != jsdata.right_trigger_value)) {
          jsdata.left_trigger_value = ltv;
          jsdata.right_trigger_value = rtv;
          joy.setRumble(ltv, rtv);
        }
        break;

      case JoystickController::PS3:
        ltv = joy.getAxis(18);
        rtv = joy.getAxis(19);
        if ((ltv != jsdata.left_trigger_value) || (rtv != jsdata.right_trigger_value)) {
          jsdata.left_trigger_value = ltv;
          jsdata.right_trigger_value = rtv;
          joy.setRumble(ltv, rtv, 50);
        }
        break;

      case JoystickController::PS3_MOTION:
        ltv = joy.getAxis(18);
        rtv = joy.getAxis(19);
        if ((ltv != jsdata.left_trigger_value) || (rtv != jsdata.right_trigger_value)) {
          jsdata.left_trigger_value = ltv;
          jsdata.right_trigger_value = rtv;
          joy.setRumble(ltv, rtv, 50);
        }
        break;

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


//=============================================================================
// TFT_joystick
//=============================================================================
void tft_JoystickData(JoystickController &joy, joystick_save_data_t &jsdata, uint16_t x_disp) {
  if (new_device_detected) {
    // Lets display the titles.
    //    tft.getCursor(&x, &y_position_after_device_info);
    tft.setCursor(0,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 (jsdata.buttons != jsdata.buttons_prev) {  //buttons
    something_changed = true;
    jsdata.buttons_prev = jsdata.buttons;
  }
  if (jsdata.axis[0] != jsdata.x) {  //xL
    jsdata.x = jsdata.axis[0];
    something_changed = true;
  }
  if (jsdata.axis[1] != jsdata.y) {  //yL
    jsdata.y = jsdata.axis[1];
    something_changed = true;
  }
  if (jsdata.axis[9] != jsdata.wheel) {  //Hat
    jsdata.wheel = jsdata.axis[9];
    something_changed = true;
  }
  //Second Axis
  if (jsdata.axis[2] != jsdata.x2) {  //xR
    jsdata.x2 = jsdata.axis[2];
    something_changed = true;
  }
  if (jsdata.axis[5] != jsdata.y2) {  //yR or z-axis
    jsdata.y2 = jsdata.axis[5];
    something_changed = true;
  }
  //Rumble Axis
  switch (joy.joystickType()) {
    case JoystickController::XBOXONE:
    case JoystickController::XBOX360:
    case JoystickController::PS4:
      if (jsdata.axis[3] != jsdata.L1) {  //xR
        jsdata.L1 = jsdata.axis[3];
        something_changed = true;
      }
      if (jsdata.axis[4] != jsdata.R1) {  //yR or z-axis
        jsdata.R1 = jsdata.axis[4];
        something_changed = true;
      }
      break;
    case JoystickController::PS3:
      if (jsdata.axis[18] != jsdata.L1) {  //xR
        jsdata.L1 = jsdata.axis[18];
        something_changed = true;
      }
      if (jsdata.axis[19] != jsdata.R1) {  //yR or z-axis
        jsdata.R1 = jsdata.axis[19];
        something_changed = true;
      }
      break;
  }
  if (something_changed) {
    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(x_disp, y);
    tft.printf("%d(%x)", jsdata.buttons, jsdata.buttons);
    tft.getCursor(&x, &y2);
    tft.fillRect(x, y, 320, line_space, ILI9341_BLACK);

    y += line_space; OutputNumberField(x_disp, y, jsdata.x, 100);  //x
    y += line_space; OutputNumberField(x_disp, y, jsdata.y, 100);  //y
    y += line_space; OutputNumberField(x_disp, y, jsdata.x2, 100); //x2(z)
    y += line_space; OutputNumberField(x_disp, y, jsdata.y2, 100); //y2
    switch (joy.joystickType()) {
      case JoystickController::PS4:
      case JoystickController::PS3:
      case JoystickController::XBOXONE:
      case JoystickController::XBOX360:
        y += line_space; OutputNumberField(x_disp, y, jsdata.L1, 100);
        y += line_space; OutputNumberField(x_disp, y, jsdata.R1, 100);
        break;
      default:
        y += line_space; OutputNumberField(x_disp, y, 0, 100);
        y += line_space; OutputNumberField(x_disp, y, 0, 100);
        y += line_space; OutputNumberField(x_disp, y, jsdata.wheel, 100); //hat
        break;
    }
    tft.updateScreen(); // update the screen now
  }
}

Now to get ready for distraction ;)
 
@KurtE

Decided to give your Multi version a try with a little regression testing. Having a tough time connecting and running a PS4. Sees the dongle fine but never connects to the PS4 when I hit the pair button. This is the dump up to the point I hit the PS button:
Code:
USB Host Testing
960
USB2 PLL running
 reset waited 6
USBHS_ASYNCLISTADDR = 0
USBHS_PERIODICLISTBASE = 20008000
periodictable = 20008000
port change: 10001803
    connect
  begin reset
port change: 10001805
  port enabled
  end recovery
new_Device: 12 Mbit/sec
new_Pipe
enumeration:
enumeration:
enumeration:
Device Descriptor:
  12 01 00 02 FF 01 01 40 5C 0A E8 21 12 01 01 02 03 01 
    VendorID = 0A5C, ProductID = 21E8, Version = 0112
    Class/Subclass/Protocol = 255 / 1 / 1
    Number of Configurations = 1
enumeration:
enumeration:
Manufacturer: Broadcom Corp
enumeration:
Product: BCM20702A0
enumeration:
Serial Number: 5CF3707A13B9
enumeration:
Config data length = 218
enumeration:
Configuration Descriptor:
  09 02 DA 00 04 01 00 E0 00 
    NumInterfaces = 4
    ConfigurationValue = 1
  09 04 00 00 03 FF 01 01 00 
    Interface = 0
    Number of endpoints = 3
    Class/Subclass/Protocol = 255 / 1 / 1
  07 05 81 03 10 00 01 
    Endpoint = 1 IN
    Type = Interrupt
    Max Size = 16
    Polling Interval = 1
  07 05 82 02 40 00 01 
    Endpoint = 2 IN
    Type = Bulk
    Max Size = 64
    Polling Interval = 1
  07 05 02 02 40 00 01 
    Endpoint = 2 OUT
    Type = Bulk
    Max Size = 64
    Polling Interval = 1
  09 04 01 00 02 FF 01 01 00 
    Interface = 1
    Number of endpoints = 2
    Class/Subclass/Protocol = 255 / 1 / 1
  07 05 83 01 00 00 01 
    Endpoint = 3 IN
    Type = Isochronous
    Max Size = 0
    Polling Interval = 1
  07 05 03 01 00 00 01 
    Endpoint = 3 OUT
    Type = Isochronous
    Max Size = 0
    Polling Interval = 1
  09 04 01 01 02 FF 01 01 00 
    Interface = 1
    Number of endpoints = 2
    Class/Subclass/Protocol = 255 / 1 / 1
  07 05 83 01 09 00 01 
    Endpoint = 3 IN
    Type = Isochronous
    Max Size = 9
    Polling Interval = 1
  07 05 03 01 09 00 01 
    Endpoint = 3 OUT
    Type = Isochronous
    Max Size = 9
    Polling Interval = 1
  09 04 01 02 02 FF 01 01 00 
    Interface = 1
    Number of endpoints = 2
    Class/Subclass/Protocol = 255 / 1 / 1
  07 05 83 01 11 00 01 
    Endpoint = 3 IN
    Type = Isochronous
    Max Size = 17
    Polling Interval = 1
  07 05 03 01 11 00 01 
    Endpoint = 3 OUT
    Type = Isochronous
    Max Size = 17
    Polling Interval = 1
  09 04 01 03 02 FF 01 01 00 
    Interface = 1
    Number of endpoints = 2
    Class/Subclass/Protocol = 255 / 1 / 1
  07 05 83 01 19 00 01 
    Endpoint = 3 IN
    Type = Isochronous
    Max Size = 25
    Polling Interval = 1
  07 05 03 01 19 00 01 
    Endpoint = 3 OUT
    Type = Isochronous
    Max Size = 25
    Polling Interval = 1
  09 04 01 04 02 FF 01 01 00 
    Interface = 1
    Number of endpoints = 2
    Class/Subclass/Protocol = 255 / 1 / 1
  07 05 83 01 21 00 01 
    Endpoint = 3 IN
    Type = Isochronous
    Max Size = 33
    Polling Interval = 1
  07 05 03 01 21 00 01 
    Endpoint = 3 OUT
    Type = Isochronous
    Max Size = 33
    Polling Interval = 1
  09 04 01 05 02 FF 01 01 00 
    Interface = 1
    Number of endpoints = 2
    Class/Subclass/Protocol = 255 / 1 / 1
  07 05 83 01 31 00 01 
    Endpoint = 3 IN
    Type = Isochronous
    Max Size = 49
    Polling Interval = 1
  07 05 03 01 31 00 01 
    Endpoint = 3 OUT
    Type = Isochronous
    Max Size = 49
    Polling Interval = 1
  09 04 02 00 02 FF FF FF 00 
    Interface = 2
    Number of endpoints = 2
    Class/Subclass/Protocol = 255 / 255 / 255
  07 05 84 02 20 00 01 
    Endpoint = 4 IN
    Type = Bulk
    Max Size = 32
    Polling Interval = 1
  07 05 04 02 20 00 01 
    Endpoint = 4 OUT
    Type = Bulk
    Max Size = 32
    Polling Interval = 1
  09 04 03 00 00 FE 01 01 00 
    Interface = 3
    Number of endpoints = 0
    Class/Subclass/Protocol = 254 / 1 / 1
  09 21 05 88 13 40 00 10 01 
    HID, 64 report descriptors
enumeration:
USBHub memory usage = 960
USBHub claim_device this=20006060
USBHub memory usage = 960
USBHub claim_device this=20006420
HIDParser claim this=200047A0
HIDParser claim this=20004DC0
HIDParser claim this=20006880
HIDParser claim this=20005400
HIDParser claim this=20005A20
JoystickController claim this=20007680
BluetoothController claim this=20006F60
BluetoothController claim this=20006f60 vid:pid=a5c:21e8
    9 4 0 0 3 ff 1 1 0 7 5 81 3 10 0 1 7 5 82 2 40 0 1 7 5 2 2 40 0 1 9 4 1 0 2 ff 1 1 0 7 5 83 1 0 0 1 7 5 3 1 0 0 1 9 4 1 1 2 ff 1 1 0 7 5 
    83 1 9 0 1 7 5 3 1 9 0 1 9 4 1 2 2 ff 1 1 0 7 5 83 1 11 0 1 7 5 3 1 11 0 1 9 4 1 3 2 ff 1 1 0 7 5 83 1 19 0 1 7 5 3 1 19 0 1 9 4 1 4 2 ff 
    1 1 0 7 5 83 1 21 0 1 7 5 3 1 21 0 1 9 4 1 5 2 ff 1 1 0 7 5 83 1 31 0 1 7 5 3 1 31 0 1 9 4 2 0 2 ff ff ff 0 7 5 84 2 20 0 1 7 5 4 2 20 0 1 9 
    4 3 0 0 fe 1 1 0 9 21 5 88 13 40 0 10 1 
      rxep=1(16) txep=2(64) rx2ep=2(64)
BluetoothController, rxep=1(16), txep=2(64)
new_Pipe
allocate_interrupt_pipe_bandwidth
 best_bandwidth = 3, at offset = 0, shift= 0
new_Pipe
allocate_interrupt_pipe_bandwidth
 best_bandwidth = 6, at offset = 0, shift= 1
new_Pipe
HCI_RESET called (03 0c 00 )
    control callback (bluetooth) 1
    Control callback (bluetooth): 1 : 3 c 0 
0E 04 01 03 0C 00 
BT rx_data(6): e 4 1 3 c 0 
    Command Completed! 
HCI_WRITE_CLASS_OF_DEV called (24 0c 03 04 08 00 )
    control callback (bluetooth) 3
    Control callback (bluetooth): 3 : 24 c 3 4 8 0 
0E 04 01 24 0C 00 
BT rx_data(6): e 4 1 24 c 0 
    Command Completed! 
HCI_Read_BD_ADDR called (09 10 00 )
    control callback (bluetooth) 4
    Control callback (bluetooth): 4 : 9 10 0 
0E 0A 01 09 10 00 B9 13 7A 70 F3 5C 
BT rx_data(12): e a 1 9 10 0 b9 13 7a 70 f3 5c 
    Command Completed! 
   BD Addr 5c:f3:70:7a:13:b9
HCI_Read_Local_Version_Information called (01 10 00 )
    control callback (bluetooth) 4
    Control callback (bluetooth): 4 : 1 10 0 
0E 0C 01 01 10 00 06 00 10 06 0F 00 0E 22 
BT rx_data(14): e c 1 1 10 0 6 0 10 6 f 0 e 22 
    Command Completed! 
    Local Version: 6
HCI_WRITE_INQUIRY_MODE called (45 0c 01 02 )
    control callback (bluetooth) 6
    Control callback (bluetooth): 6 : 45 c 1 2 
0E 04 01 45 0C 00 
BT rx_data(6): e 4 1 45 c 0 
    Command Completed! 
HCI_Set_Event_Mask called (01 0c 08 ff ff ff ff ff 5f 00 00 )
    control callback (bluetooth) 7
    Control callback (bluetooth): 7 : 1 c 8 ff ff ff ff ff 5f 0 0 
0E 04 01 01 0C 00 
BT rx_data(6): e 4 1 1 c 0 
    Command Completed! 
HCI_INQUIRY called (01 04 05 33 8b 9e 30 0a )
    control callback (bluetooth) 8
    Control callback (bluetooth): 8 : 1 4 5 33 8b 9e 30 a 
0F 04 00 01 01 04 
BT rx_data(6): f 4 0 1 1 4 
    Command 401 Status 0
*** Device Bluet a5c:21e8 - connected ***
  manufacturer: Broadcom Corp
  product: BCM20702A0
  Serial: 5CF3707A13B9
  BDADDR: b9:13:7a:70:f3:5c
2F FF 01 4E 13 00 00 7A C0 01 00 04 04 24 17 50 
BT rx_data(16): 2f ff 1 4e 13 0 0 7a c0 1 0 4 4 24 17 50 
A2 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 
BT rx_data(16): a2 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 
BT rx_data(16): 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 
BT rx_data(16): 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 
BT rx_data(16): 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 
BT rx_data(16): 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 
BT rx_data(16): 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 
BT rx_data(16): 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 
BT rx_data(16): 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 
BT rx_data(16): 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 
BT rx_data(16): 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 
BT rx_data(16): 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 
BT rx_data(16): 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 
BT rx_data(16): 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 
BT rx_data(16): 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 
BT rx_data(16): 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
00 
BT rx_data(1): 0 
    Extended Inquiry Result - Count: 1
      BD:4e:13:0:0:7a:c0, PS:1, class: 240404
2F FF 01 4E 13 00 00 7A C0 01 00 04 04 24 18 50 
BT rx_data(16): 2f ff 1 4e 13 0 0 7a c0 1 0 4 4 24 18 50 
A8 05 09 4A 4D 47 4F 02 0A 04 09 02 0D 11 0B 11 
BT rx_data(16): a8 5 9 4a 4d 47 4f 2 a 4 9 2 d 11 b 11 
0E 11 0F 11 00 00 00 00 00 00 00 00 00 00 00 00 
BT rx_data(16): e 11 f 11 0 0 0 0 0 0 0 0 0 0 0 0 
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 
BT rx_data(16): 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 
BT rx_data(16): 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 
BT rx_data(16): 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 
BT rx_data(16): 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 
BT rx_data(16): 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 
BT rx_data(16): 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 
BT rx_data(16): 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 
BT rx_data(16): 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 
BT rx_data(16): 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 
BT rx_data(16): 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 
BT rx_data(16): 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 
BT rx_data(16): 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 
BT rx_data(16): 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
00 
BT rx_data(1): 0 
    Extended Inquiry Result - Count: 1
      BD:4e:13:0:0:7a:c0, PS:1, class: 240404
      Local Name: JMGO

EDIT: Tried Keyboard and that worked no problem
 
Hi @mjs513 - I remember there were/are some issues with pairing with PS4... I assume you added the Pair version of the Bluetooth constructor...

Also I sort of was running into something like that, was not sure if the pairing happened... Then I used the non-pairing constructor and it connected... Again not sure... Will have to continue and try more...
 
@KurtE
Well I couldn't resist, my granddaughter got a Wireless Switch Pro Controller for Nintendo Switch Controller for Christmas so I hooked it up to the T4 :) It worked but...

I used the '0000' constructor and it connected but the manufacturer and sn is all gibberish. Here is an extract after the BT dongle connection. It also shows the axes stuff at the very bottom.
Code:
*** Device Bluet a5c:21e8 - connected ***
  manufacturer: Broadcom Corp
  product: BCM20702A0
  Serial: 001986000EE0
  BDADDR: e0:e:0:86:19:0
22 0F 01 0D C9 04 E9 B6 98 01 00 08 25 00 F9 2D 

BT rx_data(16): 22 f 1 d c9 4 e9 b6 98 1 0 8 25 0 f9 2d 
DC 

BT rx_data(1): dc 
    Inquiry Result with RSSI - Count: 1
      BD:d:c9:4:e9:b6:98, PS:1, class: 2508
      Peripheral device
        Gamepad
[COLOR="#FF0000"]BluetoothController::find_driver  driver 20006998
    *** Claimed ***
HCI_INQUIRY_CANCEL called (02 04 00 )
*** BTHID Device Joystick1 0:0 - connected ***
  manufacturer: )F F[h�GF F
���(D8�8�
  Serial: �9
    control callback (bluetooth) 64
[/COLOR]
    Control callback (bluetooth): 100 : 2 4 0 
0E 04 01 02 04 00 

BT rx_data(6): e 4 1 2 4 0 
    Command Completed! 
HCI_CREATE_CONNECTION called (05 04 0d 0d c9 04 e9 b6 98 18 cc 01 00 00 00 00 )
    control callback (bluetooth) 65

    Control callback (bluetooth): 101 : 5 4 d d c9 4 e9 b6 98 18 cc 1 0 0 0 0 
0F 04 00 01 05 04 

BT rx_data(6): f 4 0 1 5 4 
    Command 405 Status 0
03 0B 00 0B 00 0D C9 04 E9 B6 98 01 00 

BT rx_data(13): 3 b 0 b 0 d c9 4 e9 b6 98 1 0 
    Connection Complete - ST:0 LH:b
HCI_AUTH_REQUESTED called (11 04 02 0b 00 )
    control callback (bluetooth) 6E

    Control callback (bluetooth): 110 : 11 4 2 b 0 
0F 04 00 01 11 04 

BT rx_data(6): f 4 0 1 11 4 
    Command 411 Status 0
17 06 0D C9 04 E9 B6 98 

BT rx_data(8): 17 6 d c9 4 e9 b6 98 
    Event: Link Key Request d:c9:4:e9:b6:98
HCI_LINK_KEY_NEG_REPLY called (0c 04 06 0d c9 04 e9 b6 98 )
    control callback (bluetooth) 78

    Control callback (bluetooth): 120 : c 4 6 d c9 4 e9 b6 98 
0E 0A 01 0C 04 00 0D C9 04 E9 B6 98 

BT rx_data(12): e a 1 c 4 0 d c9 4 e9 b6 98 
    Command Completed! 
16 06 0D C9 04 E9 B6 98 

BT rx_data(8): 16 6 d c9 4 e9 b6 98 
    Event: Pin Code Request d:c9:4:e9:b6:98
HCI_PIN_CODE_REPLY called (0d 04 17 0d c9 04 e9 b6 98 04 30 30 30 30 00 00 00 00 00 00 00 00 00 00 00 00 )
    control callback (bluetooth) 82

    Control callback (bluetooth): 130 : d 4 17 d c9 4 e9 b6 98 4 30 30 30 30 0 0 0 0 0 0 0 0 0 0 0 0 
0E 0A 01 0D 04 00 0D C9 04 E9 B6 98 

BT rx_data(12): e a 1 d 4 0 d c9 4 e9 b6 98 
    Command Completed! 
1B 03 0B 00 05 

BT rx_data(5): 1b 3 b 0 5 
06 03 18 0B 00 

BT rx_data(5): 6 3 18 b 0 
    Event: HCI Authentication complete(24): handle: b
ConnectionRequest called(0b 20 0c 00 08 00 01 00 02 00 04 00 11 00 70 00 )
    tx_data(bluetooth) 82

tx_data callback (bluetooth): 0 : b 20 c 0 8 0 1 0 2 0 4 0 11 0 70 0 

=====================
BT rx2_data(20): b 20 10 0 c 0 1 0 3 0 8 0 70 0 70 0 0 0 0 0 
    L2CAP Connection Response: ID: 0, Dest:70, Source:70, Result:0, Status: 0
      Control Response
L2CAP_ConfigRequest called(0b 20 10 00 0c 00 01 00 04 00 08 00 70 00 00 00 01 02 ff ff )
    tx_data(bluetooth) 82

tx_data callback (bluetooth): 0 : b 20 10 0 c 0 1 0 4 0 8 0 70 0 0 0 1 2 ff ff 
13 05 01 0B 00 02 00 

BT rx_data(7): 13 5 1 b 0 2 0 

=====================
BT rx2_data(16): b 20 c 0 8 0 1 0 4 1 4 0 70 0 0 0 
    L2CAP config Request: ID: 1, Dest:70, Flags:0,  Options: 0 0 0 0
      Control Configuration request
L2CAP_ConfigResponse called(0b 20 12 00 0e 00 01 00 05 01 0a 00 70 00 00 00 00 00 01 02 a0 02 )

=====================
BT rx2_data(18): b 20 e 0 a 0 1 0 5 0 6 0 70 0 0 0 0 0 
    L2CAP config Response: ID: 0, Source:70, Flags:0, Result:0, Config: 0
Set HID Protocol 0 (0b 20 05 00 01 00 70 00 70 )
    tx_data(bluetooth) 82

tx_data callback (bluetooth): 200 : b 20 5 0 1 0 70 0 70 1 a 0 70 0 0 0 0 0 1 2 a0 2 
ConnectionRequest called(0b 20 0c 00 08 00 01 00 02 01 04 00 13 00 71 00 )
    tx_data(bluetooth) 82

tx_data callback (bluetooth): 0 : b 20 c 0 8 0 1 0 2 
    tx_data(bluetooth) 82

tx_data callback (bluetooth): 0 : b 20 c 0 8 0 1 0 2 1 4 0 13 0 71 0 
13 05 01 0B 00 02 00 

BT rx_data(7): 13 5 1 b 0 2 0 

=====================
BT rx2_data(20): b 20 10 0 c 0 1 0 3 1 8 0 71 0 71 0 0 0 0 0 
    L2CAP Connection Response: ID: 1, Dest:71, Source:71, Result:0, Status: 0
      Interrupt Response
L2CAP_ConfigRequest called(0b 20 10 00 0c 00 01 00 04 02 08 00 71 00 00 00 01 02 ff ff )
    tx_data(bluetooth) 82

tx_data callback (bluetooth): 0 : b 20 10 0 c 0 1 0 4 2 8 0 71 0 0 0 1 2 ff ff 
13 05 01 0B 00 02 00 

BT rx_data(7): 13 5 1 b 0 2 0 

=====================
BT rx2_data(16): b 20 c 0 8 0 1 0 4 2 4 0 71 0 0 0 
    L2CAP config Request: ID: 2, Dest:71, Flags:0,  Options: 0 0 0 0
      Interrupt Configuration request
L2CAP_ConfigResponse called(0b 20 12 00 0e 00 01 00 05 02 0a 00 71 00 00 00 00 00 01 02 a0 02 )

=====================
BT rx2_data(18): b 20 e 0 a 0 1 0 5 2 6 0 71 0 0 0 0 0 
    L2CAP config Response: ID: 2, Source:71, Flags:0, Result:0, Config: 0
HCI_WRITE_SCAN_ENABLE called(1a 0c 01 02 )
    control callback (bluetooth) 82

    Control callback (bluetooth): 130 : 1a c 1 2 
    tx_data(bluetooth) 82

tx_data callback (bluetooth): 0 : 1a c 1 2 e 0 1 0 5 2 a 0 71 0 0 0 0 0 1 2 a0 2 
0E 04 01 1A 0C 00 

BT rx_data(6): e 4 1 1a c 0 
    Command Completed! 
Write_Scan_enable Completed


=============================

[COLOR="#0000CD"]BT rx2_data(21): b 20 11 0 d 0 71 0 a1 3f 
A/B/x/Y/ 1-trig-but  / R
0/1/2/8/10/40/80
  +/0/H/T/-/2 trig-1/ 2R
0 8/-/10/-/4  1
Pad u/d/r/l /2
f 0/4/2/6
0 
Left joy
l-r (0-ff)
80 

0 
u-d (0-ff)
80 [/COLOR]

Any ideas?
 
Good question.

Is this one of the $55-60 variety or one of the $35+ variety? It has been awhile since I looked at any of this stuff!
 
I know me too but too good not to try. Actually it’s about $22 on Amazon :)

Did more out of curiosity. Don’t get a chance to play with again new years
 
I know me too but too good not to try. Actually it’s about $22 on Amazon :)

Did more out of curiosity. Don’t get a chance to play with again new years

If you order one from Amazon it'll be there sooner … Just Sayin' :)

Did a quick look - quite a variety of them $26+?
 
@KurtE - @defragster
Was testing the new board with Bluetooth and was having issues with the PS4. With the Bluetooth pair constructor it will see a joystick the hangs at this point:
Code:
*** Device Bluet a12:1 - connected ***
  product: CSR8510 A10
  BDADDR: ba:22:9:30:3:33
    control callback (bluetooth) 1

0E 04 01 03 0C 00 
    control callback (bluetooth) 3

0E 04 01 24 0C 00 
    control callback (bluetooth) 4

0E 0A 01 09 10 00 28 2B F6 83 15 00 
    control callback (bluetooth) 4

0E 0C 01 01 10 00 06 BB 22 06 0A 00 BB 22 
    control callback (bluetooth) 6

0E 04 01 45 0C 00 
    control callback (bluetooth) 7

0E 04 01 01 0C 00 
    control callback (bluetooth) 8

0F 04 00 01 01 04 
22 0F 01 0A F0 F0 7F 3C 00 01 02 04 04 20 EE 6E 
CE 
2F FF 01 EA 94 9B E2 1F 00 01 02 08 25 00 1A 6E 
D1 05 03 24 11 00 12 14 09 57 69 72 65 6C 65 73 
73 20 43 6F 6E 74 72 6F 6C 6C 65 72 09 10 02 00 
4C 05 C4 05 00 01 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 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 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 
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 00 00 
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 
00 

BluetoothController::find_driver  driver 20006058
JoystickController::claim_bluetooth TRUE
  JoystickController::mapNameToJoystickType Wireless Controller - set to PS4
  Joystick Type: 2
    *** Claimed ***
*** BTHID Device Joystick1 0:0 - connected ***
  manufacturer: ��#hF)F F[h�GF F	�^�(D8�8�
  product: Wireless Controller
  Serial: �0
    control callback (bluetooth) 64

0E 04 01 02 04 00 
    control callback (bluetooth) 65

0F 04 00 01 05 04 

03 0B 04 00 00 EA 94 9B E2 1F 00 01 00 
    control callback (bluetooth) 6E

0F 04 02 01 11 04
With the non-pair constructor it doesn't get past the claiming of the dongle after I hit the pair on the PS4.

I'm using the USBHost_t36 version that is packaged with teensyduino
 
@KurtE - @defragster

Ok just tried linking the JAMSWALL Nintendo Switch BT controller again and after it sees the dongle stops:
Code:
*** Device Bluet a5c:21e8 - connected ***
  manufacturer: Broadcom Corp
  product: BCM20702A0
  Serial: 001986000EE0
  BDADDR: e0:e:0:86:19:0
2F FF 01 25 63 34 25 73 44 01 00 08 25 00 F2 75 
B4 05 03 24 11 00 12 0F 09 50 72 6F 20 43 6F 6E 
74 72 6F 6C 6C 65 72 09 10 02 00 7E 05 09 20 00 
01 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 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 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 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 00 00 00 00 00 00 00 
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 
00 

BluetoothController::find_driver  driver 20006058
JoystickController::claim_bluetooth TRUE
  JoystickController::mapNameToJoystickType Pro Controller - Unknown
  Joystick Type: 0
    *** Claimed ***
*** BTHID Device Joystick1 0:0 - connected ***
  manufacturer: ��#hF)F F[h�GF F	�^�(D8�8�
  product: Pro Controller
  Serial: �0
    control callback (bluetooth) 64

0E 04 01 02 04 00 

    control callback (bluetooth) 65

0F 04 00 01 05 04 

03 0B 00 0B 00 25 63 34 25 73 44 01 00 

    control callback (bluetooth) 6E

0F 04 00 01 11 04 

17 06 25 63 34 25 73 44 

    control callback (bluetooth) 78

0E 0A 01 0C 04 00 25 63 34 25 73 44 

16 06 25 63 34 25 73 44 

    control callback (bluetooth) 82

0E 0A 01 0D 04 00 25 63 34 25 73 44 

1B 03 0B 00 05 

06 03 06 0B 00 

    tx_data(bluetooth) 82

    tx_data(bluetooth) 82

    tx_data(bluetooth) 82

13 05 01 0B 00 02 00 

    tx_data(bluetooth) 82

    tx_data(bluetooth) 82

13 05 01 0B 00 02 00 

    tx_data(bluetooth) 82

    tx_data(bluetooth) 82

13 05 01 0B 00 02 00 

    control callback (bluetooth) 82

0E 04 01 1A 0C 00 

  JoystickController::connectionComplete 20006040 joystick type 0
13 05 01 0B 00 01 0
 
almost 2 hours and not fixed yet? Is there something off about the device where this shouldn't be the case? Good I didn't buy one?
 
Don’t think so since I am having issues connecting with a ps4 controller as well. Too late for me to do serious debugging and pulling out my other controllers. Was also thinking about trying the dev branch instead of what comes with teensyduino.

EDIT: Something really strange is going on with Bluetooth. Swapped out the Broadcom dongle with a CSR dongle and finally got the PS4 to connect and dump about a second of values then when I hit anything on the controller it would loose BT connection.
 
Last edited:
:) - cool - I did see the PS4 notes :( I tried to open the USB/ethernet and not sure where my tried and true working example is - what I found yelled at me and broke compile? We may have been lax in testing USB stuff with other changes?
 
Think something is off with USBHost. I know PS4 wired worked but not BT. Have to dig out of storage all my other devices and retest. :(
 
Ok - doesn't look like anything wrong with USBHost for BT. Why.

I charged my PS4 and then the data started streaming without a problem so the issue was just low battery on the PS4. Now for Switch Pro controller, it seems to get this far the stalls so more investigation is needed:

Code:
*** Device Bluet a12:1 - connected ***
  product: CSR8510 A10
  BDADDR: 11:71:da:7d:1a:0
BT rx_data(16): 2f ff 1 25 63 34 25 73 44 1 2 8 25 0 c9 b 
BT rx_data(16): ca 5 3 24 11 0 12 f 9 50 72 6f 20 43 6f 6e 
BT rx_data(16): 74 72 6f 6c 6c 65 72 9 10 2 0 7e 5 9 20 0 
BT rx_data(16): 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
BT rx_data(16): 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
BT rx_data(16): 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
BT rx_data(16): 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
BT rx_data(16): 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
BT rx_data(16): 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
BT rx_data(16): 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
BT rx_data(16): 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
BT rx_data(16): 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
BT rx_data(16): 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
BT rx_data(16): 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
BT rx_data(16): 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
BT rx_data(16): 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
BT rx_data(1): 0 
    Extended Inquiry Result - Count: 1
      BD:25:63:34:25:73:44, PS:1, class: 2508
      Local Name: Pro Controller
      Peripheral device
        Gamepad
BluetoothController::find_driver  driver 20005918
JoystickController::claim_bluetooth TRUE
  JoystickController::mapNameToJoystickType Pro Controller - Unknown
  Joystick Type: 0
    *** Claimed ***
HCI_INQUIRY_CANCEL called (02 04 00 )
    Control callback (bluetooth): 100 : 2 4 0 
BT rx_data(6): e 4 1 2 4 0 
    Command Completed! 
HCI_CREATE_CONNECTION called (05 04 0d 25 63 34 25 73 44 18 cc 01 00 00 00 00 )
    Control callback (bluetooth): 101 : 5 4 d 25 63 34 25 73 44 18 cc 1 0 0 0 0 
BT rx_data(6): f 4 0 1 5 4 
    Command 405 Status 0
BT rx_data(13): 3 b 0 48 0 25 63 34 25 73 44 1 0 
    Connection Complete - ST:0 LH:48
HCI_AUTH_REQUESTED called (11 04 02 48 00 )
    Control callback (bluetooth): 110 : 11 4 2 48 0 
BT rx_data(6): f 4 0 0 11 4 
    Command 411 Status 0
BT rx_data(5): 1b 3 48 0 5 
BT rx_data(8): 17 6 25 63 34 25 73 44 
    Event: Link Key Request 25:63:34:25:73:44
HCI_LINK_KEY_NEG_REPLY called (0c 04 06 25 63 34 25 73 44 )
BT rx_data(6): f 4 0 1 0 0 
    Command 0 Status 0
    Control callback (bluetooth): 120 : c 4 6 25 63 34 25 73 44 
BT rx_data(12): e a 1 c 4 0 25 63 34 25 73 44 
    Command Completed! 
BT rx_data(8): 16 6 25 63 34 25 73 44 
    Event: Pin Code Request 25:63:34:25:73:44
HCI_PIN_CODE_REPLY called (0d 04 17 25 63 34 25 73 44 04 30 30 30 30 00 00 00 00 00 00 00 00 00 00 00 00 )
    Control callback (bluetooth): 130 : d 4 17 25 63 34 25 73 44 4 30 30 30 30 0 0 0 0 0 0 0 0 0 0 0 0 
BT rx_data(12): e a 1 d 4 0 25 63 34 25 73 44 
    Command Completed! 
BT rx_data(5): 6 3 6 48 0 
    Event: HCI Authentication complete(6): handle: 48
ConnectionRequest called(48 20 0c 00 08 00 01 00 02 00 04 00 11 00 70 00 )
tx_data callback (bluetooth): 0 : 48 20 c 0 8 0 1 0 2 0 4 0 11 0 70 0 

=====================
BT rx2_data(20): 48 20 10 0 c 0 1 0 3 0 8 0 40 0 70 0 0 0 0 0 
    L2CAP Connection Response: ID: 0, Dest:40, Source:70, Result:0, Status: 0
      Control Response
L2CAP_ConfigRequest called(48 20 10 00 0c 00 01 00 04 00 08 00 40 00 00 00 01 02 ff ff )
BT rx_data(7): 13 5 1 48 0 1 0 
tx_data callback (bluetooth): 0 : 48 20 10 0 c 0 1 0 4 0 8 0 40 0 0 0 1 2 ff ff 

=====================
BT rx2_data(20): 48 20 10 0 c 0 1 0 4 3 8 0 70 0 0 0 1 2 48 0 
    L2CAP config Request: ID: 3, Dest:70, Flags:0,  Options: 1 2 48 0
      Control Configuration request
L2CAP_ConfigResponse called(48 20 12 00 0e 00 01 00 05 03 0a 00 40 00 00 00 00 00 01 02 a0 02 )
tx_data callback (bluetooth): 0 : 48 20 12 0 e 0 1 0 5 3 a 0 40 0 0 0 0 0 1 2 a0 2 
BT rx_data(7): 13 5 1 48 0 1 0 

=====================
BT rx2_data(18): 48 20 e 0 a 0 1 0 5 0 6 0 70 0 0 0 0 0 
    L2CAP config Response: ID: 0, Source:70, Flags:0, Result:0, Config: 48
Set HID Protocol 0 (48 20 05 00 01 00 40 00 70 )
BT rx_data(7): 13 5 1 48 0 1 0 
tx_data callback (bluetooth): 200 : 48 20 5 0 1 0 40 0 70 
ConnectionRequest called(48 20 0c 00 08 00 01 00 02 01 04 00 13 00 71 00 )
BT rx_data(7): 13 5 1 48 0 1 0 
tx_data callback (bluetooth): 0 : 48 20 c 0 8 0 1 0 2 1 4 0 13 0 71 0 

=====================
BT rx2_data(20): 48 20 10 0 c 0 1 0 3 1 8 0 41 0 71 0 0 0 0 0 
    L2CAP Connection Response: ID: 1, Dest:41, Source:71, Result:0, Status: 0
      Interrupt Response
L2CAP_ConfigRequest called(48 20 10 00 0c 00 01 00 04 02 08 00 41 00 00 00 01 02 ff ff )
BT rx_data(7): 13 5 1 48 0 1 0 
tx_data callback (bluetooth): 0 : 48 20 10 0 c 0 1 0 4 2 8 0 41 0 0 0 1 2 ff ff 

=====================
BT rx2_data(20): 48 20 10 0 c 0 1 0 4 4 8 0 71 0 0 0 1 2 48 0 
    L2CAP config Request: ID: 4, Dest:71, Flags:0,  Options: 1 2 48 0
      Interrupt Configuration request
L2CAP_ConfigResponse called(48 20 12 00 0e 00 01 00 05 04 0a 00 41 00 00 00 00 00 01 02 a0 02 )
tx_data callback (bluetooth): 0 : 48 20 12 0 e 0 1 0 5 4 a 0 41 0 0 0 0 0 1 2 a0 2 
BT rx_data(7): 13 5 1 48 0 1 0 

=====================
BT rx2_data(18): 48 20 e 0 a 0 1 0 5 2 6 0 71 0 0 0 0 0 
    L2CAP config Response: ID: 2, Source:71, Flags:0, Result:0, Config: 48
HCI_WRITE_SCAN_ENABLE called(1a 0c 01 02 )
BT rx_data(7): 13 5 1 48 0 1 0 
    Control callback (bluetooth): 130 : 1a c 1 2 
BT rx_data(6): e 4 1 1a c 0 
    Command Completed! 
Write_Scan_enable Completed
  JoystickController::connectionComplete 20005900 joystick type 0
BT rx_data(6): 5 4 0 48 0 13 
    Event: HCI Disconnect complete(0): handle: 48, reason:13
But I think we have seen that before.
 
It has been a bit since I've closely followed this....
thought that I would ask how things are going at being able to read from 2 different PS3 controllers.

Looks like things have been pretty quiet on that front - with one of the comments from Kurt being "Running into some issues, that I need to fix"
thought that I would ask if there are still known issues, and what they are
 
@KurtE

I'm curious what the state of this branch is? I am trying it out with two PS3 Navigation Controllers for use in the R2D2 I am building. I can connect to two just fine and I see in the HID debug data button presses, but as soon as I start to use both Joystick objects (for example by calling getButtons) everything seems to lock up solid, all debug output stops. Best guess is maybe something is corrupting the Joystick object?
 
It has been awhile since I looked at that branch, probably since sometime last year. Hopefully at some point will get a chance (and motivation) to do another round with it.

At one point I wondered if we should work on refactoring some of this stuff. Currently it sort of started off I think like the Arduino Host shield code, where you would turn on options for doing binding or not and rebuild, but I think we should work more toward allowing users to do something like press a logical button on their screen to start of a binding process, maybe allowing for prompts... Sort of like how it is with phones, or cars... But never got around to it.
 
Back
Top