Teensy 4 Usb Keyboard & Midi Contoller problem

Status
Not open for further replies.

philjynx

Member
Yes, I know there is a similar thread but it appears to go unnnoticed.

Here is my code:
Code:
#define EP0_SIZE 64
#define NUM_ENDPOINTS 7
#define NUM_USB_BUFFERS 16
#define NUM_INTERFACE 2

#define SEREMU_INTERFACE 1 // Serial emulation
#define SEREMU_TX_ENDPOINT 1
#define SEREMU_TX_SIZE 64
#define SEREMU_TX_INTERVAL 1 // TODO: is this ok for 480 Mbit speed
#define SEREMU_RX_ENDPOINT 2
#define SEREMU_RX_SIZE 32
#define SEREMU_RX_INTERVAL 2 // TODO: is this ok for 480 Mbit speed
#define ENDPOINT1_CONFIG ENDPOINT_TRANSMIT_ONLY // serial tx
#define ENDPOINT2_CONFIG ENDPOINT_RECEIVE_ONLY  // serial rx

/*#define KEYBOARD_INTERFACE 2 // Keyboard
#define KEYBOARD_ENDPOINT 3
#define KEYBOARD_SIZE 8
#define KEYBOARD_INTERVAL 1 // TODO: is this ok for 480 Mbit speed
#define ENDPOINT3_CONFIG ENDPOINT_RECEIVE_UNUSED + ENDPOINT_TRANSMIT_INTERRUPT //keyboard

#define KEYMEDIA_INTERFACE 3 // Keyboard Media Keys
#define KEYMEDIA_ENDPOINT 4
#define KEYMEDIA_SIZE 8
#define KEYMEDIA_INTERVAL 4 // TODO: is this ok for 480 Mbit speed
#define ENDPOINT4_CONFIG ENDPOINT_RECEIVE_UNUSED + ENDPOINT_TRANSMIT_INTERRUPT // keymedia 
*/
#define MIDI_INTERFACE 4 // MIDI
#define MIDI_NUM_CABLES 1
#define MIDI_TX_ENDPOINT 5
#define MIDI_TX_SIZE_12 64
#define MIDI_TX_SIZE_480 512
#define MIDI_RX_ENDPOINT 6
#define MIDI_RX_SIZE_12 64
#define MIDI_RX_SIZE_480 512
#define ENDPOINT5_CONFIG	ENDPOINT_RECEIVE_INTERRUPT + ENDPOINT_TRANSMIT_INTERRUPT
#define ENDPOINT6_CONFIG	ENDPOINT_RECEIVE_BULK + ENDPOINT_TRANSMIT_BULK

As shown it creates a useable Teensy 4 serial+midi unit.
If I comment out the midi block and enable the keyboard and key media blocks (adjusting the number of interfaces to 3) I get a usable serial+keyboard unit.
If I enable ALL of the sections (adjusting the number of interfaces to 4) I get a usable serial+keyboard but the midi part gets a warning against it in device manager on Windows (10).
There's evidently some conflict here, but I cannot for the life of me see it.
Help!

Edit:
Immediately after upload all is well. It's actually when 'hot plugging' that the problem occurs
HotPlug.jpg
 
Try changing NUM_INTERFACE to 4, since you have 4 interfaces. Also, try numbering the interfaces 0, 1, 2, 3 rather than 1, 2, 3, 4.

Does that make any difference?
 
Also, on Teensy 4.x endpoint #1 is reserved, so you shouldn't use it for SEREMU_TX_ENDPOINT. Recommend changing that to endpoint 2. It's fine to both transmit and receive on the same endpoint (except on the oldest Teensy 2.0 which has very limited hardware).
 
Thanks Paul,
I've tried your suggestions, I did say in my post that I was adjusting the number of interfaces to four when all sections of code were enabled.

I've just done another test - renumbering both the interfaces and the endpoints (still keeping two separate endpoints for the serial).

Same outcome:

When I upload the firmware, control panel shows keyboard and MIDI interfaces working.
If I unplug the usb lead and then reconnect, the MIDI part shows as before as won't start.

I did a further test, rebooted the windows PC with the teensy connected - devices all show a green light (figuratively speaking).
I'm going to reconnect the teensy to the embeded windows machine that it lives with and see what happens when powering up that 'machine' (it has a teensy, a nano an RPi and a windows PC in it).
 
The following is hotpluggable on windows 10, I can plug the teensy in and unplug it to my heart's content and it is imediately recognisable in device manager as soon as it is plugged in, my looping software (Circular Labs Mobius Looper) can see it too.

As soon as I try to have this as a keyboard as well (by setting interfaces to 4 and uncommenting the keyboard code) I have a unit that fails.

If I comment out the midi code and enable the keyboard code (again with the correct number of interfaces defined) I get a hot swappable keyboard.

I'm using PlatformIO NOT arduino, this has me baffled.


Code:
#elif defined(USB_KEYBOARD_MIDI) // ADDED BY PJC 20200821
#define VENDOR_ID 0x16C0
#define PRODUCT_ID 0x0485

#define MANUFACTURER_NAME                                                \
  {                                                                      \
    'P', 'h', 'i', 'l', 's', ' ', 'W', 'o', 'r', 'k', 's', 'h', 'o', 'p' \
  }
#define MANUFACTURER_NAME_LEN 14
#define PRODUCT_NAME                  \
  {                                   \
    'J', 'y', 'n', 'x', 'I', 'I', 'I' \
  }
#define PRODUCT_NAME_LEN 7
#define EP0_SIZE 64
#define NUM_ENDPOINTS 8
#define NUM_USB_BUFFERS 16
#define NUM_INTERFACE 2 // because I currently have keyboard and keymedia disable by commenting

#define SEREMU_INTERFACE 0 // Serial emulation
#define SEREMU_TX_ENDPOINT 2
#define SEREMU_TX_SIZE 64
#define SEREMU_TX_INTERVAL 1 // TODO: is this ok for 480 Mbit speed
#define SEREMU_RX_ENDPOINT 3
#define SEREMU_RX_SIZE 32
#define SEREMU_RX_INTERVAL 2 // TODO: is this ok for 480 Mbit speed
#define ENDPOINT2_CONFIG ENDPOINT_TRANSMIT_ONLY // serial tx
#define ENDPOINT3_CONFIG ENDPOINT_RECEIVE_ONLY  // serial rx

/* #define KEYBOARD_INTERFACE 1 // Keyboard
#define KEYBOARD_ENDPOINT 4
#define KEYBOARD_SIZE 8
#define KEYBOARD_INTERVAL 1 // TODO: is this ok for 480 Mbit speed
#define ENDPOINT4_CONFIG ENDPOINT_RECEIVE_UNUSED + ENDPOINT_TRANSMIT_INTERRUPT //keyboard

#define KEYMEDIA_INTERFACE 2 // Keyboard Media Keys
#define KEYMEDIA_ENDPOINT 5
#define KEYMEDIA_SIZE 8
#define KEYMEDIA_INTERVAL 4 // TODO: is this ok for 480 Mbit speed
#define ENDPOINT5_CONFIG ENDPOINT_RECEIVE_UNUSED + ENDPOINT_TRANSMIT_INTERRUPT // keymedia 
 */
#define MIDI_INTERFACE 3 // MIDI
#define MIDI_NUM_CABLES 1
#define MIDI_TX_ENDPOINT 6
#define MIDI_TX_SIZE_12 64
#define MIDI_TX_SIZE_480 512
#define MIDI_RX_ENDPOINT 7
#define MIDI_RX_SIZE_12 64
#define MIDI_RX_SIZE_480 512
#define ENDPOINT6_CONFIG	ENDPOINT_RECEIVE_INTERRUPT + ENDPOINT_TRANSMIT_INTERRUPT
#define ENDPOINT7_CONFIG	ENDPOINT_RECEIVE_BULK + ENDPOINT_TRANSMIT_BULK

#elif defined(USB_KEYBOARD_MIDI_SERIAL)         // ADDED BY PJC 20200821
 
in usb_desc.h we have:-
SEREMU_TX_INTERVAL 1 // TODO: is this ok for 480 Mbit speed
SEREMU_RX_INTERVAL 2 // TODO: is this ok for 480 Mbit speed
KEYBOARD_INTERVAL 1 // TODO: is this ok for 480 Mbit speed
and
KEYMEDIA_INTERVAL 4 // TODO: is this ok for 480 Mbit speed
in usb_desc.c we have:-
midi bInterval hard coded as 0 (does that mean "give me as much time as you can?")

Is it possible that the polling for the keyboard is using too much processing for this combination to be successful?

One other (related point).
I have this test code:
Code:
if (doit > 1)
  { // dawdle for a bit
    
    delay(300);
//  now type something into notepad
    Keyboard.println("B1 release test");
    delay(50);
    Keyboard.println("fred");
    delay(50);
    Keyboard.println("so is that it then?");
    delay(50);
    
    doit--;
    if (doit == 1)
    {
      Keyboard.println("Finished test");
    }


When the keyboard actually works, the first iteration of that loop results in repeated and or missed characters, it then settles down and types the expected characters. I have tried it with a 5 second delay, it made no difference.

I've looked all over the place in the internet and found next to no examples of code to use the usb keyboard functionality.

I'm also curious about
TODO: is this ok for 480 Mbit speed
, is it ok? is this where the problem lies?
 
Status
Not open for further replies.
Back
Top