T3.6 USB Host - Bluetooth

Right now, I have:

Code:
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 <= 0x132) { //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;
			}
			digiAxes[usage & 0xf] = value;
		} else if (usage >= 0x910 && usage <= 0x91f) {
			if (value == 0) {
				buttons &= ~(1 << (usage - 0x910));
			} else {
				buttons |= (1 << (usage - 0x910));
			}
		}
	}
}

So far I am not sure what the two button on pen do... still investigating... But I do now have the 4 buttons on the table showing up as button presses.

Also the Wheel value does not appear to do anything, but the WheelH I am guessing is how far the pen is above the tablet, for a value up to maybe 63...

At times wondering if it would be nice to make test app, that allows you to connect a Mouse, or Tablet or Joystick and have an ILI9341 display and have some of the key values shown...
Instead of all of the data scrolling on by on the debug terminal. Could make use of the new fancy number output functions :D
 
@KurtE

Glad you got yours working - the test app does sound nice - almost like the test app in windows :)

Could make use of the new fancy number output functions
At least they would be coming in handy for something. :)
 
@KurtE

Here is a simple function just to display the axes and button values on a ILI9341 display - can get fancier but not right now - its a start.
Code:
void TFT_display(uint32_t buttons, int x, int y, int z)
{
    tft.drawString("BUTTONS",10,0);
    if(buttons == 0){
      tft.drawString("...............",10,20);
    } else {
      tft.drawNumber(buttons,10,20);
    }
    tft.drawString("X: ",120,100);
    if(x == x_old){
      tft.drawString(".........",160,100);
      tft.drawNumber(x_old,160,100);
    } else {
      tft.drawNumber(x,160,100);
    }
    
    y_old=y;
    tft.drawString("Y: ",120,120);
    if(y == y_old){
      tft.drawString(".........",160,120);
      tft.drawNumber(y_old,160,120);
    } else {
      tft.drawNumber(y,160,120);
    }
    
    z_old=z;;
    tft.drawString("Z: ",120,140);
    if(z == z_old){
      tft.drawString(".........",160,140);
      tft.drawNumber(z_old,160,140);
    } else {
      tft.drawNumber(z,160,140);
    }
    z_old=z;
}
 
Hi @mjs513 and ...

I am currently playing with a version of code:
Code:
// Simple test of USB Host Mouse/Joystick
//
// This example is in the public domain
#include "USBHost_t36.h"
#include <ili9341_t3n_font_Arial.h>

// Connection konfiguration of ILI9341 LCD TFT
#if defined(__MK66FX1M0__) 
#define TFT_RST 8
#define TFT_DC 9
#define TFT_CS 10
#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
#else
#error "This example App will only work with Teensy 3.6 or Teensy 4."
#endif
ILI9341_t3n tft = ILI9341_t3n(TFT_CS, TFT_DC, TFT_RST);


// Save away values for buttons, x, y, wheel, wheelh
int buttons_cur = 0;
int x_cur = 0;
int y_cur = 0;
int wheel_cur = 0;
int wheelH_cur = 0;

USBHost myusb;
USBHub hub1(myusb);
USBHub hub2(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
int user_axis[64];
uint8_t digi_axis[64];
uint32_t buttons_prev = 0;

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

// Lets also look at HID Input devices
USBHIDInput *hiddrivers[] = {&tablet, &joystick, &mouse};
#define CNT_HIDDEVICES (sizeof(hiddrivers)/sizeof(hiddrivers[0]))
const char * hid_driver_names[CNT_HIDDEVICES] = {"tablet", "joystick", "mouse"};
bool hid_driver_active[CNT_HIDDEVICES] = {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()
{
  Serial1.begin(2000000);
  while (!Serial && millis() < 3000) ; // wait for Arduino Serial Monitor
  Serial.println("\n\nUSB Host Testing");
  myusb.begin();
  tft.begin();
  delay(100);
  tft.setRotation(3); // 180
  delay(100);
  tft.fillScreen(ILI9341_BLACK);
  tft.setTextColor(ILI9341_YELLOW);
  tft.setTextSize(2);
  tft.println("Waiting for Mouse or Joystick...");
}


void loop()
{
  myusb.Task();

  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;
        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 - connected\n", hid_driver_names[i], hiddrivers[i]->idVendor(), hiddrivers[i]->idProduct());

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

  if (tablet.available()) {
    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;
    }
    if (something_changed) {
      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);
      
    }
    tablet.digitizerDataClear();
  }

#if 0
  if (joystick.available()) {
    uint64_t axis_mask = joystick.axisMask();
    uint64_t axis_changed_mask = joystick.axisChangedMask();
    Serial.print("Joystick: buttons = ");
    uint32_t 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));
        }
      }
    }
    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();
    joystick.joystickDataClear();
  }
#endif    
}
There are several issues with the code, I am looking at... First off if I just press a button, it simply updates the text of the screen at bottom with issues of writing transparent text over transparent text... But if I move the Pen over the display it redraws the entire screen, so memory is getting corrupted as this should only happen if it thinks it is a new HID device...

Then the text not overwriting old text, I will probably blank out the line first then draw new text... However before that I will probably move the text up on the display (so show maybe last 5 values...)... Note: I could convert over to using the opaque font code that I have in the library and it should properly overwrite the previous text... however it will draw in the background text the whole area for the line spacing below it... Which can be issues... If so can set clip rectangle...

Edit: Fixed memory corruption: tried to save up to 15 digiAxes in a 10 element array ;)
 
Then the text not overwriting old text, I will probably blank out the line first then draw new text... However before that I will probably move the text up on the display (so show maybe last 5 values...)... Note: I could convert over to using the opaque font code that I have in the library and it should properly overwrite the previous text... however it will draw in the background text the whole area for the line spacing below it... Which can be issues... If so can set clip rectangle...

Edit: Fixed memory corruption: tried to save up to 15 digiAxes in a 10 element array

@KurtE

Had the same problem with trying to draw and redraw text, that's why I did the way I did. Going to give your version a try. Unfortunately I can't seem to be able to use the T4 it keeps hanging on me for some strange reason - I don't know - guess I will have to wait for the 1062.

as for the axes :) been there and got the T-shirt a couple of times.
 
@KurtE
Since my mouse data seems to be returned as raw hid I changed you sketch as follows:
Code:
// Simple test of USB Host Mouse/Joystick
//
// This example is in the public domain
#include "USBHost_t36.h"
#include <ili9341_t3n_font_Arial.h>

// Connection konfiguration of ILI9341 LCD TFT
#if defined(__MK66FX1M0__) 
#define TFT_RST 8
#define TFT_DC 9
#define TFT_CS 10
#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
#else
#error "This example App will only work with Teensy 3.6 or Teensy 4."
#endif
ILI9341_t3n tft = ILI9341_t3n(TFT_CS, TFT_DC, TFT_RST);


// Save away values for buttons, x, y, wheel, wheelh
int buttons_cur = 0;
int x_cur = 0;
int y_cur = 0;
int wheel_cur = 0;
int wheelH_cur = 0;

USBHost myusb;
USBHub hub1(myusb);
USBHub hub2(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);

int user_axis[64];
uint8_t digi_axis[64];
uint32_t buttons_prev = 0;

USBDriver *drivers[] = {&hub1, &hub2, &joystick, &bluet, &hid1, &hid2, &hid3, &hid4, &hid5};
#define CNT_DEVICES (sizeof(drivers)/sizeof(drivers[0]))
const char * driver_names[CNT_DEVICES] = {"Hub1", "Hub2", "Joystick(device)", "Bluet", "HID1" , "HID2", "HID3", "HID4", "HID5"};
bool driver_active[CNT_DEVICES] = {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};
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 && millis() < 3000) ; // wait for Arduino Serial Monitor
  Serial.println("\n\nUSB Host Testing");
  myusb.begin();
  rawhid2.attachReceive(OnReceiveHidData);

  
  tft.begin();
  delay(100);
  tft.setRotation(3); // 180
  delay(100);
  tft.fillScreen(ILI9341_BLACK);
  tft.setTextColor(ILI9341_YELLOW);
  tft.setTextSize(2);
  tft.println("Waiting for Mouse or Joystick...");
}


void loop()
{
  myusb.Task();

  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;
        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 - connected\n", hid_driver_names[i], hiddrivers[i]->idVendor(), hiddrivers[i]->idProduct());

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

  if (tablet.available()) {
    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;
    }
    if (something_changed) {
      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);
    }
    tablet.digitizerDataClear();
  }

#if 0
  if (joystick.available()) {
    uint64_t axis_mask = joystick.axisMask();
    uint64_t axis_changed_mask = joystick.axisChangedMask();
    Serial.print("Joystick: buttons = ");
    uint32_t 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));
        }
      }
    }
    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();
    joystick.joystickDataClear();
  }
#endif    
}

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();

    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);
    }
  return true;
}
 
Hi @mjs513 - been playing around with some other stuff, will get back to it in the morning... I did play around some this afternoon, but mainly changed a few of the output things like:


Code:
    if (something_changed) {
      tft.setTextColor(ILI9341_WHITE, ILI9341_BLACK);
      tft.setTextDatum(BR_DATUM);
      tft.drawNumber(buttons_cur, 50, 235);
      tft.drawNumber(x_cur, 100, 235);
      tft.drawNumber(y_cur, 150, 235);
      tft.drawNumber(wheel_cur, 200, 235);
      tft.drawNumber(wheelH_cur, 250, 235);
    }
    tablet.digitizerDataClear();
  }
Put the text output in Opaque mode (two colors on set text color) Also set the datum to BR...
This took care of the text output, I was then starting to play with trying to scroll the text, but then other things happened...

Next up was to maybe put up titles. Then maybe handle Your data, mouse, and Joystick...

But now thinking about how to get half duplex support into the hardware Serial of the OpenCM 9.04 board...

Edit: Note: pushed up new keywords.txt file for ili9341_t3n for new functions and keywords...
 
Last edited:
Morning @KurtE

Cool that you updated the Keywords:)

Oh - I added joystick display this morning, you can do you magic on the function :)
Code:
// Simple test of USB Host Mouse/Joystick
//
// This example is in the public domain
#include "USBHost_t36.h"
#include <ili9341_t3n_font_Arial.h>

// Connection konfiguration of ILI9341 LCD TFT
#if defined(__MK66FX1M0__) 
#define TFT_RST 8
#define TFT_DC 9
#define TFT_CS 10
#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
#else
#error "This example App will only work with Teensy 3.6 or Teensy 4."
#endif
ILI9341_t3n tft = ILI9341_t3n(TFT_CS, TFT_DC, TFT_RST);


// 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;
int wheel_cur = 0;
int wheelH_cur = 0;

USBHost myusb;
USBHub hub1(myusb);
USBHub hub2(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);

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

USBDriver *drivers[] = {&hub1, &hub2, &joystick, &bluet, &hid1, &hid2, &hid3, &hid4, &hid5};
#define CNT_DEVICES (sizeof(drivers)/sizeof(drivers[0]))
const char * driver_names[CNT_DEVICES] = {"Hub1", "Hub2", "Joystick(device)", "Bluet", "HID1" , "HID2", "HID3", "HID4", "HID5"};
bool driver_active[CNT_DEVICES] = {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};
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 && millis() < 3000) ; // wait for Arduino Serial Monitor
  Serial.println("\n\nUSB Host Testing");
  myusb.begin();
  rawhid2.attachReceive(OnReceiveHidData);

  
  tft.begin();
  delay(100);
  tft.setRotation(3); // 180
  delay(100);
  tft.fillScreen(ILI9341_BLACK);
  tft.setTextColor(ILI9341_YELLOW);
  tft.setTextSize(2);
  tft.println("Waiting for Mouse or Joystick...");
}


void loop()
{
  myusb.Task();

  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;
        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 - connected\n", hid_driver_names[i], hiddrivers[i]->idVendor(), hiddrivers[i]->idProduct());

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

  if (tablet.available()) {
    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;
    }
    if (something_changed) {
      tft.setTextColor(ILI9341_WHITE, ILI9341_BLACK);
      tft.setTextDatum(BR_DATUM);
      tft.drawNumber(buttons_cur, 50, 235);
      tft.drawNumber(x_cur, 100, 235);
      tft.drawNumber(y_cur, 150, 235);
      tft.drawNumber(wheel_cur, 200, 235);
      tft.drawNumber(wheelH_cur, 250, 235);
    }
    tablet.digitizerDataClear();
  }

  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_joystick();
    joystick.joystickDataClear();
  }

   
}

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();

    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);
    }
  return true;
}

void TFT_joystick()
{
    tft.setTextColor(ILI9341_WHITE, ILI9341_BLACK);
    tft.drawString("BUTTONS",100,80);
    if(buttons == 0){
      tft.drawString(".........",180,80);
      tft.drawNumber(buttons_prev,180,80);
    } else {
      tft.drawNumber(buttons,180,80);
    }

    tft.drawString("X: ",60,100);
    if(user_axis[0] == x_cur){
      tft.drawString(".........",80,100);
      tft.drawNumber(x_cur,80,100);
    } else {
      tft.drawNumber(user_axis[0],80,100);
    }
    x_cur = user_axis[0];
    
    tft.drawString("Y: ",60,120);
    if(user_axis[1] == y_cur){
      tft.drawString(".........",80,120);
      tft.drawNumber(y_cur,80,120);
    } else {
      tft.drawNumber(user_axis[1],80,120);
    }
    y_cur=user_axis[1];
    
    tft.drawString("Hat: ",40,160);
    if(user_axis[9] == wheel_cur){
      tft.drawString(".........",80,160);
      tft.drawNumber(wheel_cur,80,160);
    } else {
      tft.drawNumber(user_axis[9],80,160);
    }
    wheel_cur=user_axis[9];

    //Gamepads
    tft.drawString("X2: ",160,100);
    if(user_axis[2] == x_cur){
      tft.drawString(".........",190,100);
      tft.drawNumber(x_cur,190,100);
    } else {
      tft.drawNumber(user_axis[2],190,100);
    }
    x2_cur = user_axis[2];
    
    tft.drawString("Y2: ",160,120);
    if(user_axis[5] == y2_cur){
      tft.drawString(".........",190,120);
      tft.drawNumber(y2_cur,190,120);
    } else {
      tft.drawNumber(user_axis[5],190,120);
    }
    y2_cur=user_axis[5];
    
    switch (joystick.joystickType()) {
      default:
        tft.drawString("Z: ",60,140);
        if(user_axis[5] == z_cur){
          tft.drawString(".........",80,140);
          tft.drawNumber(z_cur,80,140);
        } else {
          tft.drawNumber(user_axis[5],80,140);
        }
        z_cur=user_axis[5];
        break;
      case JoystickController::PS4:
        break;
      case JoystickController::PS3:
        break;
      case JoystickController::XBOXONE:
      case JoystickController::XBOX360:
        break;
    }

}
 
Added this for mouse:
Code:
  if (mouse.available()) {
    Serial.print("Mouse: buttons = ");
    Serial.print(mouse.getButtons());
    Serial.print(",  mouseX = ");
    Serial.print(mouse.getMouseX());
    Serial.print(",  mouseY = ");
    Serial.print(mouse.getMouseY());
    Serial.print(",  wheel = ");
    Serial.print(mouse.getWheel());
    Serial.print(",  wheelH = ");
    Serial.print(mouse.getWheelH());
    Serial.println();

    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 (tablet.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) {
      tft.setTextColor(ILI9341_WHITE, ILI9341_BLACK);
      tft.setTextDatum(BR_DATUM);
      tft.drawNumber(buttons_cur, 50, 235);
      tft.drawNumber(x_cur, 100, 235);
      tft.drawNumber(y_cur, 150, 235);
      tft.drawNumber(wheel_cur, 200, 235);
      tft.drawNumber(wheelH_cur, 250, 235);
    }
    
    mouse.mouseDataClear();
  }
 
@KurtE/@defragster

Guess after we get done with this is adding a mass storage as Tim mentioned?
 
@mjs513 and @defragster...

Will play around with your version (maybe you should post your whole current version).

And Yes mass storage would be great. Maybe beyond my pay grade :D Probably would need a new thread as I have not tried out any mass storage Bluetooth devices ;)
 
@KurtE and @defragster

Well, here we go again with my T4. Had it up and running for a while without the display attached. Attached the display and it ran fine for a couple of iterations and then I made a change to the sketch and it hung again - but this time I had Serial4 attached:
Code:
Fault irq 3
 stacked_r0 ::  20002E14
 stacked_r1 ::  00000055
 stacked_r2 ::  00000010
 stacked_r3 ::  B1134B04
 stacked_r12 ::  20007784
 stacked_lr ::  0000B38F
 stacked_pc ::  0000B192
 stacked_psr ::  41000000
 _CFSR ::  00000082
 _HFSR ::  40000000
 _DFSR ::  00000000
 _AFSR ::  00000000
 _BFAR ::  B1134B04
 _MMAR ::  B1134B04
need to switch to alternate clock during reconfigure of ARM PLL
USB PLL is running, so we can use 120 MHz
Freq: 12 MHz * 75 / 3 / 1
ARM PLL=80002064
ARM PLL needs reconfigure
ARM PLL=8000204B
New Frequency: ARM=300000000, IPG=150000000
Decreasing voltage to 1150 mV
It looks like the fault was for IRQ3 - DMA channel3???????


Do you want just the sketch?

Yeah - a little above my paygrade as well - no clue - i looked at it and not really sure how the massstorage.h file ties into USB but like you said another thread - unless we a bluetooth device :)
 
@KurtE and @defragster
Here is the whole sketch:
Code:
// Simple test of USB Host Mouse/Joystick
//
// This example is in the public domain
#include "USBHost_t36.h"
#include <ili9341_t3n_font_Arial.h>

// Connection konfiguration of ILI9341 LCD TFT
#if defined(__MK66FX1M0__) 
#define TFT_RST 8
#define TFT_DC 9
#define TFT_CS 10
#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
#else
#error "This example App will only work with Teensy 3.6 or Teensy 4."
#endif
ILI9341_t3n tft = ILI9341_t3n(TFT_CS, TFT_DC, TFT_RST);


// 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;
int wheel_cur = 0;
int wheelH_cur = 0;

USBHost myusb;
USBHub hub1(myusb);
USBHub hub2(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);

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

USBDriver *drivers[] = {&hub1, &hub2, &joystick, &bluet, &hid1, &hid2, &hid3, &hid4, &hid5};
#define CNT_DEVICES (sizeof(drivers)/sizeof(drivers[0]))
const char * driver_names[CNT_DEVICES] = {"Hub1", "Hub2", "Joystick(device)", "Bluet", "HID1" , "HID2", "HID3", "HID4", "HID5"};
bool driver_active[CNT_DEVICES] = {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};
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 && millis() < 3000) ; // wait for Arduino Serial Monitor
  Serial.println("\n\nUSB Host Testing");
  myusb.begin();
  rawhid2.attachReceive(OnReceiveHidData);

  
  tft.begin();
  delay(100);
  tft.setRotation(3); // 180
  delay(100);
  tft.fillScreen(ILI9341_BLACK);
  tft.setTextColor(ILI9341_YELLOW);
  tft.setTextSize(2);
  tft.println("Waiting for Mouse or Joystick...");
}


void loop()
{
  myusb.Task();

  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;
        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 - connected\n", hid_driver_names[i], hiddrivers[i]->idVendor(), hiddrivers[i]->idProduct());

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

  if (tablet.available()) {
    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;
    }
    if (something_changed) {
      tft.setTextColor(ILI9341_WHITE, ILI9341_BLACK);
      tft.setTextDatum(BR_DATUM);
      tft.drawNumber(buttons_cur, 50, 235);
      tft.drawNumber(x_cur, 100, 235);
      tft.drawNumber(y_cur, 150, 235);
      tft.drawNumber(wheel_cur, 200, 235);
      tft.drawNumber(wheelH_cur, 250, 235);
    }
    tablet.digitizerDataClear();
  }

  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_joystick();
    joystick.joystickDataClear();
  }

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

    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 (tablet.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) {
      tft.setTextColor(ILI9341_WHITE, ILI9341_BLACK);
      tft.setTextDatum(BR_DATUM);
      tft.drawNumber(buttons_cur, 50, 235);
      tft.drawNumber(x_cur, 100, 235);
      tft.drawNumber(y_cur, 150, 235);
      tft.drawNumber(wheel_cur, 200, 235);
      tft.drawNumber(wheelH_cur, 250, 235);
    }
    
    mouse.mouseDataClear();
  }
}

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();

    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);
    }
  return true;
}

void TFT_joystick()
{
    tft.setTextColor(ILI9341_WHITE, ILI9341_BLACK);
    tft.drawString("BUTTONS",100,80);
    if(buttons == 0){
      tft.drawString(".........",180,80);
      tft.drawNumber(buttons_prev,180,80);
    } else {
      tft.drawNumber(buttons,180,80);
    }

    tft.drawString("X: ",60,100);
    if(user_axis[0] == x_cur){
      tft.drawString(".........",80,100);
      tft.drawNumber(x_cur,80,100);
    } else {
      tft.drawNumber(user_axis[0],80,100);
    }
    x_cur = user_axis[0];
    
    tft.drawString("Y: ",60,120);
    if(user_axis[1] == y_cur){
      tft.drawString(".........",80,120);
      tft.drawNumber(y_cur,80,120);
    } else {
      tft.drawNumber(user_axis[1],80,120);
    }
    y_cur=user_axis[1];
    
    tft.drawString("Hat: ",40,160);
    if(user_axis[9] == wheel_cur){
      tft.drawString(".........",80,160);
      tft.drawNumber(wheel_cur,80,160);
    } else {
      tft.drawNumber(user_axis[9],80,160);
    }
    wheel_cur=user_axis[9];

    //Gamepads
    tft.drawString("X2: ",160,100);
    if(user_axis[2] == x_cur){
      tft.drawString(".........",190,100);
      tft.drawNumber(x_cur,190,100);
    } else {
      tft.drawNumber(user_axis[2],190,100);
    }
    x2_cur = user_axis[2];
    
   
    switch (joystick.joystickType()) {
      default:
        tft.drawString("Z: ",60,140);
        if(user_axis[5] == z_cur){
          tft.drawString(".........",80,140);
          tft.drawNumber(z_cur,80,140);
        } else {
          tft.drawNumber(user_axis[5],80,140);
        }
        z_cur=user_axis[5];
        break;
      case JoystickController::PS4:
        tft.drawString("Y2: ",160,120);
        if(user_axis[5] == y2_cur){
          tft.drawString(".........",190,120);
          tft.drawNumber(y2_cur,190,120);
        } else {
          tft.drawNumber(user_axis[5],190,120);
        }
        y2_cur=user_axis[5];
        break;
      case JoystickController::PS3:
        tft.drawString("Y2: ",160,120);
        if(user_axis[5] == y2_cur){
          tft.drawString(".........",190,120);
          tft.drawNumber(y2_cur,190,120);
        } else {
          tft.drawNumber(user_axis[5],190,120);
        }
        y2_cur=user_axis[5];
        break;
      case JoystickController::XBOXONE:
      case JoystickController::XBOX360:
        tft.drawString("Y2: ",160,120);
        if(user_axis[5] == y2_cur){
          tft.drawString(".........",190,120);
          tft.drawNumber(y2_cur,190,120);
        } else {
          tft.drawNumber(user_axis[5],190,120);
        }
        y2_cur=user_axis[5];
        break;
    }
}
 
irq 3 is the common entry point value posted AFAIK / IIRC.

That shows the fault handler code I referred to put in place with labels works! Combined with dropping F_CPU.

The actual fault source indication is embedded in those _??SR values. It seems I had a grand idea of looking at that - perhaps printed pages a couple layers down on my desktop.

Indeed mass storage would not be Bt - but reading the SDHC post on T4b thread showed SDHC is a firehose and 512Byte feeding buffer is a straw … where ideal transfer is some multiple KB not 0.5 KB :( I was just wondering if the flash drive interface had onboard controller that would be more forgiving or amenable to streaming data.
 
defragster said:
That shows the fault handler code I referred to put in place with labels works! Combined with dropping F_CPU.
At least I showed that it works and it has to happen right away after startup.

The actual fault source indication is embedded in those _??SR values. It seems I had a grand idea of looking at that - perhaps printed pages a couple layers down on my desktop.
Would be nice to know what causes it. The way I get it to work again is to load and run the sketch without power to the display. Unplug and attach the display and then it works fine.

Indeed mass storage would not be Bt - but reading the SDHC post on T4b thread showed SDHC is a firehose and 512Byte feeding buffer is a straw … where ideal transfer is some multiple KB not 0.5 KB I was just wondering if the flash drive interface had onboard controller that would be more forgiving or amenable to streaming data.
Was looking at it more today but its way beyond me. :(
 
There is something odd - have you reseated the POGO board? When I was trying to do debug_tt stuff - and other times it seems - that might have been a factor.

Seems:: I would have working code ( IIRC ) - change something and then fault on start.

This is the DOC I found and printed … 2 months back :: keil.com/appnotes_apnt209.pdf :: Using Cortex-M3/M4/M7 Fault Exceptions
Mike: If you dig into that and codify a scheme to pull apart those registers I'll put it in debug_tt … as noted I got that doc to do it myself 2 months back and … life/distractions

Fault exception numbers and priority
Each exception has an associated exception number and an associated priority number. To simplify the software layer, the CMSIS only uses IRQ numbers and therefore uses negative values for exceptions other than interrupts. The table lists fault exceptions ordered by their priority. Exception Exception Number Priority IRQ Number Activation
HardFault
3 -1 -13 -

MemManage fault
4 Configurable -12 Synchronous
BusFault
5 Configurable -11 Synchronous when precise, asynchronous when imprecise.
UsageFault
6 Configurable -10 Synchronous

I thought -1 priority was fun - means no other interrupts are possible … though USB output was working - nothing else did … like Serial#

I should have just buckled down and wrote manual xmit for one/all uart Serial - initially I wanted to keep debug_tt code as tiny as possible to avoid adding or moving trouble … more code takes more space … of course that went out the window when I added Trace code to my basic log and interface code ...
 
@defragster

Thank Tim for the reference doc. Made it easy to see the fault from looking at CFSR register: basically a memory fault - tried accessing a protected address identified in the bfar and mmar address. Will take a look at how to incorporate it.

EDIT: Don't think the pogo pins are the problem. Reloaded the sketch without touching the board but with the display attached and it ran. Then when I plugged the display pwr back in the sketch ran fine.
 
@mjs513 - Wondering if maybe your display is causing a brownout? Or maybe causing the power ramp to be a little different? Sounds like something @paul might have ideas on...

Maybe ask in the T$ thread.

As for the display test app, I am thinking of hacking the heck out of it! Interestingly it did not work with a plug in mouse... Might need to figure out why and if the main Mouse code is working...

It is displaying PS3 data..

I am wondering if what I was thinking of doing was to scroll data so you can see the last 5 or so Tablet events is making for to complex of a test app, and maybe do like Joystick which just shows one value? With titles...
 
@mjs513 - Wondering if maybe your display is causing a brownout? Or maybe causing the power ramp to be a little different? Sounds like something @paul might have ideas on...

Maybe ask in the T$ thread.
It could be, was thinking about that awhile ago but then it would start working again. Will probably post on the T$ thread as you suggested

As for the display test app, I am thinking of hacking the heck out of it! Interestingly it did not work with a plug in mouse... Might need to figure out why and if the main Mouse code is working...

It is displaying PS3 data..
Hmm - that's interesting, I tested it with a Bluetooth mouse so just assumed it would work?

I am wondering if what I was thinking of doing was to scroll data so you can see the last 5 or so Tablet events is making for to complex of a test app, and maybe do like Joystick which just shows one value? With titles...
When it comes to displaying data I using do it and check to see what it looks like - usually its not like I think and have to adjust.

Interesting that you mentioned scrolling - was trying to figure out how that worked but just punted for now :)
 
Currently hacking on the code, breaking up the loop code into parts, where I am in the process of having
separate functions for displaying device info, display table data, display mouse data, display Joystick data...

As for scrolling, currently it is a pain in the arch... Two different approaches:
a) Keep the top level data (what got displayed where) and then display it again a row up...
b) what I was going to do: scroll the pixels:

Assume Arial_12 font
Lets say we have the Y region of the display of 100-235... We can compute the number of lines we can display by:
count_lines = (235-100)/Arial_12.line_space;

Then top y would probably be 235-(count_lines * Arial_12.line_space);

Then to do an abrupt scroll, could do a something like:
tft.readRect(0, top_y -Arial_12.line_space, 320, (count_lines-1) * Arial_12.line_space, pixel_data);
tft.writeRect(0, top_y, 320, (count_lines-1) * Arial_12.line_space, pixel_data);
<Maybe fill rect for the bottom line and output data >
...

Now we could get fancy and do it a pixel line at a time...
 
@defragster

Thank Tim for the reference doc. Made it easy to see the fault from looking at CFSR register: basically a memory fault - tried accessing a protected address identified in the bfar and mmar address. Will take a look at how to incorporate it.
...

Good to know they mapped out - Mem Fault sounds reasonable for something dumb happening.

Maybe I'll start SMALL and go decode those values to dump useful text, Paul noted once he intended to present something better - then I found that named dump snippet and it is there for now. Thought that might be useful - but Faults didn't seem to come up as much as I figured this new beast might provoke.

Maybe a small base add to current fault handler will be reasonable to leave in - even a way to enable it at compile time.

<edit: Good fine on triggering hardware scroll Kurt - that would be faster and hopefully smoother to read
 
@KurtE and @defragster
Think that this may work better, by better maybe easier to implement:
Code:
// A fun MATRIX-like screen demo of scrolling
// Screen will flicker initially until fully drawn
// then scroll smoothly
#include <ili9341_t3n_font_Arial.h>
#include <SPI.h>
    #define CS_L digitalWrite(10, LOW)
    #define CS_H digitalWrite(10, HIGH)
    #define DC_C digitalWrite(9, LOW)
  #define DC_D digitalWrite(9, HIGH)
#define ILI9341_VSCRDEF 0x33
  
// These are the pins used for the UNO
// for Due/Mega/Leonardo use the hardware SPI pins (which are different)
#define TFT_RST 23
#define TFT_DC 9
#define TFT_CS 10

#define TEXT_HEIGHT 10 // Height of text to be printed and scrolled
#define BOT_FIXED_AREA 40  // Number of lines in bottom fixed area (lines counted from bottom of screen)
#define TOP_FIXED_AREA 50 // Number of lines in top fixed area (lines counted from top of screen)

// Must use hardware SPI for speed
ILI9341_t3n tft = ILI9341_t3n(TFT_CS, TFT_DC, TFT_RST);

int16_t yStart = TOP_FIXED_AREA;
int16_t yArea = 320 - TOP_FIXED_AREA - BOT_FIXED_AREA;
int16_t yDraw = 320 - BOT_FIXED_AREA - TEXT_HEIGHT;
byte pos[42];
int16_t xPos = 0;

void setup() {
  Serial.begin(115200);
  tft.begin();
  tft.setRotation(0);
  tft.fillScreen(ILI9341_BLACK);
  setupScrollArea(TOP_FIXED_AREA, BOT_FIXED_AREA);
}

void loop(void) {
  // First fill the screen with randomt streaks of characters
  for (int j = 0; j < 400; j += TEXT_HEIGHT) {
    for (int i = 0; i < 40; i++) {
      if (pos[i] > 20) pos[i] -= 3; // Rapid fade initially brightness values
      if (pos[i] > 0) pos[i] -= 1; // Slow fade later
      if (random(20) == 1) pos[i] = 63; // ~1 in 20 probability of a new character
      tft.setTextColor(pos[i] << 5, ILI9341_BLACK); // Set the character brightness
      if (pos[i] == 63) tft.setTextColor(ILI9341_WHITE, ILI9341_BLACK); // Draw white character
      tft.drawChar(xPos, yDraw, random(32,128),ILI9341_WHITE,ILI9341_BLACK, 1); // Draw the character
      xPos += tft.getCursorX();
    }
    yDraw = scroll_slow(TEXT_HEIGHT, 14); // Scroll, 14ms per pixel line
    xPos = 0;
  }

  //tft.setRotation(2);
  //tft.setTextColor(63 << 5, ILI9341_BLACK);
  //tft.drawCentreString("MATRIX",120,60,4);
  //tft.setRotation(0);

  // Now scroll smoothly forever
  while (1) yDraw = scroll_slow(320,8); // Scroll 320 (arbitrary number!) lines, 10ms per line

}

void setupScrollArea(uint16_t TFA, uint16_t BFA) {
  writecommand(ILI9341_VSCRDEF); // Vertical scroll definition
  writedata(TFA >> 8);
  writedata(TFA);
  writedata((320 - TFA - BFA) >> 8);
  writedata(320 - TFA - BFA);
  writedata(BFA >> 8);
  writedata(BFA);
}

int scroll_slow(int lines, int wait) {
  int yTemp = yStart;
  for (int i = 0; i < lines; i++) {
    yStart++;
    if (yStart == 320 - BOT_FIXED_AREA) yStart = TOP_FIXED_AREA;
    scrollAddress(yStart);
    delay(wait);
  }
  return  yTemp;
}

void scrollAddress(uint16_t VSP) {
  writecommand(ILI9341_VSCRSADD); // Vertical scrolling start address
  writedata(VSP >> 8);
  writedata(VSP);
}

/***************************************************************************************
** Function name:           writecommand
** Description:             Send an 8 bit command to the TFT
***************************************************************************************/
void writecommand(uint8_t c)
{
  DC_C;
  CS_L;
  SPI.transfer(c);
  CS_H;
  DC_D;
}

/***************************************************************************************
** Function name:           writedata
** Description:             Send a 8 bit data value to the TFT
***************************************************************************************/
void writedata(uint8_t c)
{
  CS_L;
  SPI.transfer(c);
  CS_H;
}
Kind of kludged just as a proof of concept
 
Hi @mjs513 and @defragster...

I have done one pass through the code we have been playing with. I am thinking of removing most if not all Serial.print like calls and only output to TFT...

See what you think: I have not updated the Joystick data yet.

Code:
//=============================================================================
// Simple test of USB Host Mouse/Tablet/Joystick viewer 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>

//=============================================================================
// Connection configuration of ILI9341 LCD TFT
//=============================================================================
#if defined(__MK66FX1M0__)
#define TFT_RST 8
#define TFT_DC 9
#define TFT_CS 10
#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
#else
#error "This example App will only work with Teensy 3.6 or Teensy 4."
#endif
ILI9341_t3n tft = ILI9341_t3n(TFT_CS, TFT_DC, TFT_RST);

//=============================================================================
// USB Host Ojbects
//=============================================================================
USBHost myusb;
USBHub hub1(myusb);
USBHub hub2(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[] = {&joystick};
#define CNT_DEVICES (sizeof(drivers)/sizeof(drivers[0]))
const char * driver_names[CNT_DEVICES] = {"Joystick(device)"};
bool driver_active[CNT_DEVICES] = {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};

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;
int wheel_cur = 0;
int wheelH_cur = 0;


int user_axis[64];
uint8_t digi_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);


  tft.begin();
  delay(100);
  tft.setRotation(3); // 180
  delay(100);
  tft.fillScreen(ILI9341_BLACK);
  tft.setTextColor(ILI9341_YELLOW);
  tft.setTextSize(2);
  tft.println("Waiting for Mouse or Joystick...");
}


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

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

//=============================================================================
// 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:");
      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;
    }
    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;tft.setCursor(TABLET_DATA_X, y);tft.print(x_cur, DEC); tft.getCursor(&x, &y2);tft.fillRect(x, y, 320, line_space, ILI9341_BLACK);
      y+= line_space;tft.setCursor(TABLET_DATA_X, y);tft.print(y_cur, DEC); tft.getCursor(&x, &y2);tft.fillRect(x, y, 320, line_space, ILI9341_BLACK);
      y+= line_space;tft.setCursor(TABLET_DATA_X, y);tft.print(wheel_cur, DEC); tft.getCursor(&x, &y2);tft.fillRect(x, y, 320, line_space, ILI9341_BLACK);
      y+= line_space;tft.setCursor(TABLET_DATA_X, y);tft.print(wheelH_cur, DEC); tft.getCursor(&x, &y2);tft.fillRect(x, y, 320, line_space, ILI9341_BLACK);
       

      /*tft.drawNumber(buttons_cur, 50, 235);
      tft.drawNumber(x_cur, 100, 235);
      tft.drawNumber(y_cur, 150, 235);
      tft.drawNumber(wheel_cur, 200, 235);
      tft.drawNumber(wheelH_cur, 250, 235);
      */
    }
    tablet.digitizerDataClear();
  }
}

//=============================================================================
// 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;tft.setCursor(MOUSE_DATA_X, y);tft.print(x_cur, DEC); tft.getCursor(&x, &y2);tft.fillRect(x, y, 320, line_space, ILI9341_BLACK);
      y+= line_space;tft.setCursor(MOUSE_DATA_X, y);tft.print(y_cur, DEC); tft.getCursor(&x, &y2);tft.fillRect(x, y, 320, line_space, ILI9341_BLACK);
      y+= line_space;tft.setCursor(MOUSE_DATA_X, y);tft.print(wheel_cur, DEC); tft.getCursor(&x, &y2);tft.fillRect(x, y, 320, line_space, ILI9341_BLACK);
      y+= line_space;tft.setCursor(MOUSE_DATA_X, y);tft.print(wheelH_cur, DEC); tft.getCursor(&x, &y2);tft.fillRect(x, y, 320, line_space, ILI9341_BLACK);
    }

    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_joystick();
    joystick.joystickDataClear();
  }
}


//=============================================================================
// TFT_joystick 
//=============================================================================
void TFT_joystick()
{
  tft.setTextColor(ILI9341_WHITE, ILI9341_BLACK);
  tft.drawString("BUTTONS", 100, 100);
  if (buttons == 0) {
    tft.drawString(".........", 180, 100);
    tft.drawNumber(buttons_prev, 180, 100);
  } else {
    tft.drawNumber(buttons, 180, 100);
  }

  tft.drawString("X: ", 60, 120);
  if (user_axis[0] == x_cur) {
    tft.drawString(".........", 80, 120);
    tft.drawNumber(x_cur, 80, 120);
  } else {
    tft.drawNumber(user_axis[0], 80, 120);
  }
  x_cur = user_axis[0];

  tft.drawString("Y: ", 60, 140);
  if (user_axis[1] == y_cur) {
    tft.drawString(".........", 80, 140);
    tft.drawNumber(y_cur, 80, 140);
  } else {
    tft.drawNumber(user_axis[1], 80, 140);
  }
  y_cur = user_axis[1];

  tft.drawString("Hat: ", 40, 180);
  if (user_axis[9] == wheel_cur) {
    tft.drawString(".........", 80, 180);
    tft.drawNumber(wheel_cur, 80, 180);
  } else {
    tft.drawNumber(user_axis[9], 80, 180);
  }
  wheel_cur = user_axis[9];

  //Gamepads
  tft.drawString("X2: ", 160, 120);
  if (user_axis[2] == x_cur) {
    tft.drawString(".........", 190, 120);
    tft.drawNumber(x_cur, 190, 120);
  } else {
    tft.drawNumber(user_axis[2], 190, 120);
  }
  x2_cur = user_axis[2];


  switch (joystick.joystickType()) {
    default:
      tft.drawString("Z: ", 60, 160);
      if (user_axis[5] == z_cur) {
        tft.drawString(".........", 80, 160);
        tft.drawNumber(z_cur, 80, 140);
      } else {
        tft.drawNumber(user_axis[5], 80, 160);
      }
      z_cur = user_axis[5];
      break;
    case JoystickController::PS4:
      tft.drawString("Y2: ", 160, 140);
      if (user_axis[5] == y2_cur) {
        tft.drawString(".........", 190, 140);
        tft.drawNumber(y2_cur, 190, 120);
      } else {
        tft.drawNumber(user_axis[5], 190, 140);
      }
      y2_cur = user_axis[5];
      break;
    case JoystickController::PS3:
      tft.drawString("Y2: ", 160, 140);
      if (user_axis[5] == y2_cur) {
        tft.drawString(".........", 190, 140);
        tft.drawNumber(y2_cur, 190, 140);
      } else {
        tft.drawNumber(user_axis[5], 190, 140);
      }
      y2_cur = user_axis[5];
      break;
    case JoystickController::XBOXONE:
    case JoystickController::XBOX360:
      tft.drawString("Y2: ", 160, 160);
      if (user_axis[5] == y2_cur) {
        tft.drawString(".........", 190, 160);
        tft.drawNumber(y2_cur, 190, 160);
      } else {
        tft.drawNumber(user_axis[5], 190, 160);
      }
      y2_cur = user_axis[5];
      break;
  }
}

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

  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);
  }
  return true;
}
 
Back
Top