Teensy 4.1 12MBit / 480MBit serial USB speed toggle

AlexRH

Member
Hello,
I have managed to select 12MBit speed of the serial USB with editing core file usb.c

Code:
USB1_PORTSC1 |= USB_PORTSC1_PFSC; // force 12 Mbit/sec

My question, is it possible to do the same from the Arduino sketch? I would like to set USB serial speed during sketch compile instead of editing teesyduino core file each time. If yes, can you please give me the code example?
 
Testing with this in sketch:
Code:
void setup() {
  USB1_PORTSC1 |= USB_PORTSC1_PFSC; // force 12 Mbit/sec
...

It APPEARS to work, that is Viewing the USB Device info goes from HIGH to FULL, with that done.

That code line is the LAST in usb_init() - then the device connects and setup() is called after a wait - so this is done some 100 or 300 ms after that completes and may have some unseen issues.

It does NOT work using that code in startup_middle_hook(), called before usb_init(), because the USB device is not yet active.
 
Cool, post back with observed results after more usage ...

@PaulStoffregen might see and comment if this is good/safe solution.

Given his understanding and involvement in the USB protocol this might be a usably clean solution, if USB allows the device to assert that 'limitation' during ongoing transfers after connection is established.
 
I still have some misunderstanding of the serial USB topic, hope you can make it more clear for me.
In my hardware I use Serial.begin(115200) initialization in sketch void setup and I use additional digital pin just to detect if the USB cable is physically plugged. Where in my code should I add the line?
1-st variant:
Code:
void setup() {
  USB1_PORTSC1 |= USB_PORTSC1_PFSC; // force 12 Mbit/sec
  Serial.begin(115200);
...

or 2-nd variant
Code:
void setup() {
  Serial.begin(115200);
...

void loop(){
if (PIN==HIGH) {delay(300); USB1_PORTSC1 |= USB_PORTSC1_PFSC;}  // switch to 12MBit only when cable is plugged

}
 
Just checked and in real use this doesn't work as post#2 versus editing directly in usb.c and building.
> at least on this Win 10 machine, last test was on Win 11

Using the code from: PaulStoffregen/USB-Serial-Print-Speed-Test
It will run over 500K lines, which is normal best speed for T_4.1

Going into CORES and making the edit and it runs at a more sedate 34K lines per second.

For ref Serial.begin() is not needed - it will sit and wait some 2 secs to see if USB comes online before returning, if called. If not it will still start ASAP.

If there is a chance this p#2 solves the issue it should be as provided - early in setup().
 
To make this work, you'll probably need to completely turn off the USB port, at leave it off long enough for your PC to recognize as a USB disconnect. Maybe like this?

Code:
        USB1_USBCMD = 0; // turn off USB controller
        USB1_USBCMD = 2; // begin USB controller reset
        delay(250);

Then to turn it on again, you'll need to replicate most of the code from usb_init(), but of course add the 12 MBit line. Or maybe you could just call usb_init() and then set the USB_PORTSC1_PFSC bit immediately after.
 
To make this work, you'll probably need to completely turn off the USB port, at leave it off long enough for your PC to recognize as a USB disconnect. Maybe like this?

Code:
        USB1_USBCMD = 0; // turn off USB controller
        USB1_USBCMD = 2; // begin USB controller reset
        delay(250);

Then to turn it on again, you'll need to replicate most of the code from usb_init(), but of course add the 12 MBit line. Or maybe you could just call usb_init() and then set the USB_PORTSC1_PFSC bit immediately after.

When the edit is made in cores\...\usb.c the Serial Lines Per Second changes immediately on upload restart - on this Win 10 machine.

With the line commented in usb.c and added to setup() {as in p#2} the LPS speed stays high, even on longer unplug.

However doing this seems to set and work - here on Win 10 - to get 34K LPS instead of 500K LPS:
Code:
extern "C" void usb_init();
void setup() {
#if 1
  USB1_PORTSC1 |= USB_PORTSC1_PFSC;  // force 12 Mbit/sec
  usb_init();
  USB1_PORTSC1 |= USB_PORTSC1_PFSC;  // force 12 Mbit/sec
#endif
Changing the #if 1 to #if 0 and rebuilding is showing that.

Did that as it seems that was done in MSC/MTP testing by @KurtE to get Windows to rescan the device.
 
Last edited:
Back
Top