Forum Rule: Always post complete source code & details to reproduce any issue!
Results 1 to 3 of 3

Thread: How to create a new USB device type with a Teensy 3.2

Hybrid View

  1. #1
    Member Etienne's Avatar
    Join Date
    Mar 2016
    Location
    Ardeche, France
    Posts
    50

    How to create a new USB device type with a Teensy 3.2

    Hi,

    I'm trying to create a new USB device type with a Teensy 3.2, which will present a Joystick hid and a virtual serial interface. It is working but as I would like to include FFB feature to the joystick (and raw Hid as well later), I need another endpoint and a different descriptor. I have a working FFB descriptor from another project, but as I would like to avoid breaking the Joystick that is already available, I would like to have a new type of interface.

    To have the Joystick+Emulated Serial, I did this :

    I modified the usb_desc.h file in the teensy3 core, and added a new type that I've called "USB_FFB_RAWHID" with the following definitions :

    Code:
    	#elif defined(USB_FFB_RAWHID)
    		#define VENDOR_ID		0x16C0
    		#define PRODUCT_ID		0x048A
    		#define MANUFACTURER_NAME		{'A','i','-','W','a','v','e'}
    		#define MANUFACTURER_NAME_LEN	7
    		#define PRODUCT_NAME			{'E','S','P',' ','W','h','e','e','l'}
    		#define PRODUCT_NAME_LEN		9
    		#define EP0_SIZE				64
    
    		#define NUM_ENDPOINTS			3
    		#define NUM_USB_BUFFERS	 	24
    		#define NUM_INTERFACE			2
    
    		#define JOYSTICK_INTERFACE		0// Joystick
    		#define JOYSTICK_ENDPOINT	        3
    		#define JOYSTICK_SIZE		        16
    		#define JOYSTICK_INTERVAL	        2
    
    	        #define SEREMU_INTERFACE      1	// Serial emulation
    		#define SEREMU_TX_ENDPOINT    1
    		#define SEREMU_TX_SIZE        64
    		#define SEREMU_TX_INTERVAL    1
    		#define SEREMU_RX_ENDPOINT    2
    		#define SEREMU_RX_SIZE        32
    		#define SEREMU_RX_INTERVAL    2
    
    		#define ENDPOINT1_CONFIG	ENDPOINT_TRANSIMIT_ONLY
    		#define ENDPOINT2_CONFIG	ENDPOINT_RECEIVE_ONLY
    		#define ENDPOINT3_CONFIG	ENDPOINT_TRANSIMIT_ONLY
    I also modified the boards.txt that you find in the "arduino-1.6.7\hardware\teensy\avr folder", I added the following lines just after "teensy31.menu.usb.rawhid.fake_serial=teensy_gatew ay":

    Code:
    teensy31.menu.usb.ffb_hid=Joystick
    teensy31.menu.usb.ffb_hid.build.usbtype=USB_FFB_RAWHID
    teensy31.menu.usb.ffb_hid.fake_serial=teensy_gateway
    If I select "Joystick" in the "Arduino/Tools/Usb Type" menu, it is working as expected, which is pretty cool.

    Now I want to add FFB support, so I replaced the all the JOYSTICK_xxx defines with "FFB_JOYSTICK_xxx" defines, which results in usb_desc.h is :

    Code:
    		#elif defined(USB_FFB_RAWHID)
    		#define VENDOR_ID		0x16C0
    		#define PRODUCT_ID		0x048A
    		#define MANUFACTURER_NAME		{'A','i','-','W','a','v','e'}
    		#define MANUFACTURER_NAME_LEN	7
    		#define PRODUCT_NAME			{'E','S','P',' ','W','h','e','e','l'}
    		#define PRODUCT_NAME_LEN		9
    		#define EP0_SIZE				64
    
    		#define NUM_ENDPOINTS			3
    		#define NUM_USB_BUFFERS			24
    		#define NUM_INTERFACE			2
    
    		#define FFB_JOYSTICK_INTERFACE		0// Joystick
    		#define FFB_JOYSTICK_TX_ENDPOINT	3
    		#define FFB_JOYSTICK_TX_SIZE		16
    		#define FFB_JOYSTICK_TX_INTERVAL	1
    
    	        #define SEREMU_INTERFACE      1	// Serial emulation
    		#define SEREMU_TX_ENDPOINT    1
    		#define SEREMU_TX_SIZE        64
    		#define SEREMU_TX_INTERVAL    1
    		#define SEREMU_RX_ENDPOINT    2
    		#define SEREMU_RX_SIZE        32
    		#define SEREMU_RX_INTERVAL    2
    
    		#define ENDPOINT1_CONFIG	ENDPOINT_TRANSIMIT_ONLY
    		#define ENDPOINT2_CONFIG	ENDPOINT_RECEIVE_ONLY
    		#define ENDPOINT3_CONFIG	ENDPOINT_TRANSIMIT_ONLY
    I also duplicated all the code in usb_desc.c where I have "#ifdef JOYSTICK_INTERFACE" and have replaced with "#ifdef FFB_JOYSTICK_INTERFACE" :

    Code:
    #ifdef FFB_JOYSTICK_INTERFACE
    static uint8_t ffb_joystick_report_desc[] = {
    	0x05, 0x01,                     // Usage Page (Generic Desktop)
    	0x09, 0x04,                     // Usage (Joystick)
    	0xA1, 0x01,                     // Collection (Application)
    	0x15, 0x00,                     // Logical Minimum (0)
    	0x25, 0x01,                     // Logical Maximum (1)
    	0x75, 0x01,                     // Report Size (1)
    	0x95, 0x20,                     // Report Count (32)
    	0x05, 0x09,                     // Usage Page (Button)
    	0x19, 0x01,                     // Usage Minimum (Button #1)
    	0x29, 0x20,                     // Usage Maximum (Button #32)
    	0x81, 0x02,                     // Input (variable,absolute)
    	0x15, 0x00,                     // Logical Minimum (0)
    	0x25, 0x07,                     // Logical Maximum (7)
    	0x35, 0x00,                     // Physical Minimum (0)
    	0x46, 0x3B, 0x01,               // Physical Maximum (315)
    	0x75, 0x04,                     // Report Size (4)
    	0x95, 0x01,                     // Report Count (1)
    	0x65, 0x14,                     // Unit (20)
    	0x05, 0x01,                     // Usage Page (Generic Desktop)
    	0x09, 0x39,                     // Usage (Hat switch)
    	0x81, 0x42,                     // Input (variable,absolute,null_state)
    	0x05, 0x01,                     // Usage Page (Generic Desktop)
    	0x09, 0x01,                     // Usage (Pointer)
    	0xA1, 0x00,                     // Collection ()
    	0x15, 0x00,                     //   Logical Minimum (0)
    	0x26, 0xFF, 0x03,               //   Logical Maximum (1023)
    	0x75, 0x0A,                     //   Report Size (10)
    	0x95, 0x04,                     //   Report Count (4)
    	0x09, 0x30,                     //   Usage (X)
    	0x09, 0x31,                     //   Usage (Y)
    	0x09, 0x32,                     //   Usage (Z)
    	0x09, 0x35,                     //   Usage (Rz)
    	0x81, 0x02,                     //   Input (variable,absolute)
    	0xC0,                           // End Collection
    	0x15, 0x00,                     // Logical Minimum (0)
    	0x26, 0xFF, 0x03,               // Logical Maximum (1023)
    	0x75, 0x0A,                     // Report Size (10)
    	0x95, 0x02,                     // Report Count (2)
    	0x09, 0x36,                     // Usage (Slider)
    	0x09, 0x36,                     // Usage (Slider)
    	0x81, 0x02,                     // Input (variable,absolute)
    	0xC0                            // End Collection
    };
    Code:
    #define FFB_JOYSTICK_INTERFACE_DESC_POS	JOYSTICK_INTERFACE_DESC_POS+JOYSTICK_INTERFACE_DESC_SIZE
    #ifdef  FFB_JOYSTICK_INTERFACE
    #define FFB_JOYSTICK_INTERFACE_DESC_SIZE	9+9+7
    #define FFB_JOYSTICK_HID_DESC_OFFSET	FFB_JOYSTICK_INTERFACE_DESC_POS+9
    #else
    #define FFB_JOYSTICK_INTERFACE_DESC_SIZE	0
    #endif
    I also modified the line related to the MTP device :

    Code:
    #define MTP_INTERFACE_DESC_POS		FFB_JOYSTICK_INTERFACE_DESC_POS+FFB_JOYSTICK_INTERFACE_DESC_SIZE
    Added also

    Code:
    #ifdef FFB_JOYSTICK_INTERFACE
    		// interface descriptor, USB spec 9.6.5, page 267-269, Table 9-12
    		9,                                      // bLength
    		4,                                      // bDescriptorType
    		FFB_JOYSTICK_INTERFACE,                     // bInterfaceNumber
    		0,                                      // bAlternateSetting
    		1,                                      // bNumEndpoints
    		0x03,                                   // bInterfaceClass (0x03 = HID)
    		0x00,                                   // bInterfaceSubClass
    		0x00,                                   // bInterfaceProtocol
    		0,                                      // iInterface
    		// HID interface descriptor, HID 1.11 spec, section 6.2.1
    		9,                                      // bLength
    		0x21,                                   // bDescriptorType
    		0x11, 0x01,                             // bcdHID
    		0,                                      // bCountryCode
    		1,                                      // bNumDescriptors
    		0x22,                                   // bDescriptorType
    		LSB(sizeof(ffb_joystick_report_desc)),      // wDescriptorLength
    		MSB(sizeof(ffb_joystick_report_desc)),
    		// endpoint descriptor, USB spec 9.6.6, page 269-271, Table 9-13
    		7,                                      // bLength
    		5,                                      // bDescriptorType
    		FFB_JOYSTICK_TX_ENDPOINT | 0x80,        // bEndpointAddress
    		0x03,                                   // bmAttributes (0x03=intr)
    		FFB_JOYSTICK_TX_SIZE, 0,                // wMaxPacketSize
    		FFB_JOYSTICK_TX_INTERVAL,               // bInterval
    #endif // FFB_JOYSTICK_INTERFACE
    and finally :
    Code:
    #ifdef FFB_JOYSTICK_INTERFACE
    	{ 0x2200, FFB_JOYSTICK_INTERFACE, ffb_joystick_report_desc, sizeof(ffb_joystick_report_desc) },
    	{ 0x2100, FFB_JOYSTICK_INTERFACE, config_descriptor + FFB_JOYSTICK_HID_DESC_OFFSET, 9 },
    #endif
    After these changes, the device is still recognised under windows but it doesn't behave as before (axis are not moving anymore).

    I tried to create a new folder called "usb_ffb_hid" by duplicating the folder "usb_hid" at the same level as the "teensy3" core folder, but when I change the code in "usb.c" of this folder, it doesn't seem to be taken into account.

    So my question is : these folders (usb_disk,usb_flightsim,usb_hid, etc...) that you find near teensy3, are they used with the teensy 3.2 board ?
    I don't know where to look for in order to have my new interface type working like the first type I did, and also where to look for to add the code dealing with FFB, anyone having any idea ?

    Thanks

    Edit : I got it working as the initial joystick I did, it was the code I modified in joystick.cpp that was wrong. Now the axis are moving again. But to go further (adding FFB), my questions about the folders remain (usb_disk,usb_flightsim,usb_hid, etc...).
    Last edited by Etienne; 04-06-2016 at 03:03 PM.

  2. #2
    Senior Member PaulStoffregen's Avatar
    Join Date
    Nov 2012
    Posts
    22,649
    Quote Originally Posted by Etienne View Post
    So my question is : these folders (usb_disk,usb_flightsim,usb_hid, etc...) that you find near teensy3, are they used with the teensy 3.2 board ?
    No, those are all for Teensy 2.0 & Teensy++ 2.0.

    My earlier USB code for Teensy 2.0 wasn't designed to be flexible, so more device types were added by making more copies.

  3. #3
    Member Etienne's Avatar
    Join Date
    Mar 2016
    Location
    Ardeche, France
    Posts
    50
    Ok thank you very much for the quick reply.
    So I guess that everything happens in usb_dev.c if I want to deal with force feedback reports ?

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •