Skip to content

Turn off USB functionnality / SerialUSB.end() not implemented #103

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
AloyseTech opened this issue Jan 26, 2016 · 16 comments
Open

Turn off USB functionnality / SerialUSB.end() not implemented #103

AloyseTech opened this issue Jan 26, 2016 · 16 comments

Comments

@AloyseTech
Copy link

SerialUSB.end() function in cores/arduino/USB/CDC.cpp is not implemented.

When trying to jump from an application to an other (using this function http://pastebin.com/FyjkXJR2), the new application doesn't start if the USB cable is plugged in. I tried to do a SerialUSB.end() rigth before jumpApplication(), but the function is not implemented. I think something should be done to be able to stop all USB activity. Maybe it is not the aim of this function. If so, please point me to the right one 😃

Thanks!

@sandeepmistry
Copy link
Contributor

@AloyseTech good question!

I think USBDevice.detach() is the API you want to use. Take a look at USB/USBAPI.h or USB/USBCore.cpp for more details.

@AloyseTech
Copy link
Author

Actually it doesn't solve the issue... I've experimented a bit but none of the experiment I tried was succesfull... I talked to @aethaniel about this issue, but I'm not sure to understand what the real issue is.

Here's some snippet I tried :

//USB->DEVICE.CTRLA.bit.ENABLE = 0;
//USB->DEVICE.CTRLB.bit.DETACH = 1;
//USB->DEVICE.INTFLAG.bit.SUSPEND = 1;
USBDevice.detach();
USB->DEVICE.CTRLA.bit.SWRST = 1;
//while (USB->DEVICE.SYNCBUSY.bit.ENABLE == 1);
while (USB->DEVICE.CTRLA.bit.SWRST == 1);

@sandeepmistry sandeepmistry reopened this Mar 3, 2016
@casundra
Copy link

I believe I'm having the same issue of releasing the native Serial/USB port. I'm having trouble waking from from standby sleep mode with an open Serial Monitor connection. I did a SerialUSB.end before sleep, but it doesn't seem to release the USB port. It then hangs at the SerialUSB.begin command when waking up. (Verified that it does wake up, interrupts still function).

I'm about to dig into the Arduino USB core and the datasheet, but would love to hear if you've come up with a solution @AloyseTech .

@AloyseTech
Copy link
Author

No I haven't found any solution at the moment. I'm not sure we're facing the same issue : the bug I have also appear when no Serial monitor connection has been or is opened...
By the way, like I said in the first post, the SerialUSB.end() function is not implemented.
You could try this code code :
USBDevice.detach();

Or maybe experiment like I posted with those lines of code :

//this disable USB and wait for sync
//USB->DEVICE.CTRLA.bit.ENABLE = 0;
USB->DEVICE.CTRLB.bit.DETACH = 1;
USB->DEVICE.INTFLAG.bit.SUSPEND = 1;
while (USB->DEVICE.SYNCBUSY.bit.ENABLE == 1);

//This is the Arduino core version
USBDevice.detach();

//this should reset the hardware USB
USB->DEVICE.CTRLA.bit.SWRST = 1;
while (USB->DEVICE.CTRLA.bit.SWRST == 1);

@casundra
Copy link

Thanks for the advice, @AloyseTech . I first tried detaching & disabling before sleep and enabling & attaching after. The port disappeared and re-enumerated as it should, but Serial commands still hung my program. This was my implementation:

  USB->DEVICE.CTRLB.bit.DETACH = 1;
  USB->DEVICE.CTRLA.bit.ENABLE = 0;
  while (USB->DEVICE.SYNCBUSY.bit.ENABLE == 1);

  // Sets Sleep Mode to Standby and enters Sleep
  SCB->SCR |= SCB_SCR_SLEEPDEEP_Msk;
  __DSB();
  __WFI();

  // Resume from Wake-up
  USB->DEVICE.CTRLA.bit.ENABLE = 1;
  while (USB->DEVICE.SYNCBUSY.bit.ENABLE == 1);
  USB->DEVICE.CTRLB.bit.DETACH = 0;
  SerialUSB.println("Waking!");

Next, I tried a complete USB hardware reset and re-initialization. This worked, Serial commands now function normally.

  USB->DEVICE.CTRLA.bit.SWRST = 1;
  while (USB->DEVICE.SYNCBUSY.bit.SWRST | USB->DEVICE.CTRLA.bit.SWRST == 1);

  // Sets Sleep Mode to Standby and enters Sleep
  SCB->SCR |= SCB_SCR_SLEEPDEEP_Msk;
  __DSB();
  __WFI();

  // Resume from Wake-up
  USBDevice.init();
  USBDevice.attach();
  SerialUSB.println("Waking!");

I never see "Waking!" because it's not buffered and takes time to re-establish the Serial Monitor link. But subsequent serial outputs show up normally.

Yes, I see what you mean about the SerialUSB.end. I also see that the SerialUSB.begin function isn't implemented either, as it's taken care of elsewhere in the CDC setup. This is the first time I've looked through these functions, so I'm still getting familiar with it all. I'd like to figure out the precise cause of the sleep hang-up with Serial functions, but the hardware reset is an OK bandaid for now. Eventually it would be nice to get the USB suspend mode and wake-up interrupts working.

@AloyseTech
Copy link
Author

Hi,

Has anyone succeeded to turn off and then back on Native USB? I'm still having trouble with this issue...

@casundra
Copy link

casundra commented May 28, 2016

Edit: Ah, I see I was ahead of myself. Forgot I already reported back on this a few months ago!

Not using SerialUSB or attach/detach. I was only able to do it by commanding a software reset on the usb module, then re-initializing. I'm on the road now but can attach my code next week if it helps. I think I did a direct write to the software reset bit in the USB register to shut everything down, then used the arduino usb functions to re-initialize.

-Carrie

Sent from my telephone.

@timonsku
Copy link

I would be very much interested in this. Could any one of you share their solution?

@rocketscream
Copy link

Hi guys,

  USBDevice.detach();

  // Sets Sleep Mode to Standby and enters Sleep
  SCB->SCR |= SCB_SCR_SLEEPDEEP_Msk;
  __DSB();
  __WFI();

  // Resume from Wake-up
  USBDevice.init();
  USBDevice.attach();
  while (!SerialUSB);
  SerialUSB.println("Waking!");

That would work somehow if delay(5000) is added before the SerialUSB.println("Waking!");
So, somehow the while (!SerialUSB); is not waiting for the port to be open. But, it can transmit but it cannot receive any character. If I were to write a simple code of:

  if (SerialUSB.available())
  {
    if (SerialUSB.read() == 'a')
    {
      if (SerialUSB.find("\r\n")) SerialUSB.println("Gotcha");
    }
  }

which expects the character a with CRLF. Nothing is received.

@facchinm
Copy link
Member

facchinm commented Oct 1, 2018

Hi @rocketscream ,
while (!SerialUSB); returns immediately since _usbLineInfo structure is not cleared anywhere. I'm preparing a PR to properly add end() and fix arduino-libraries/ArduinoLowPower#7

@facchinm facchinm self-assigned this Oct 1, 2018
@rocketscream
Copy link

@facchinm but will this solve the incapability to receive after waking up too? If not, I will open another issue.

@facchinm
Copy link
Member

facchinm commented Oct 1, 2018

@rocketscream It should; sample code:

Serial.end();
LowPower.sleep(5000);
Serial.begin(115200);
while (!Serial) {}

with sleep() defined as https://github.com/arduino-libraries/ArduinoLowPower/blob/8b7e548d58b4aa96347108a900c35443d2cb9b92/src/samd/ArduinoLowPower.cpp#L18

On my PC the call to sleep detaches the serial port completely. If I leave the serial monitor open, the port will change name on resume (default behaviour in Linux since the monitor il locking the other port). Selecting the right name and opening the monitor again unlocks !Serial check and the board can both send and receive as usual.

@rocketscream
Copy link

@facchinm thank you very much for fixing this. I will try this. And yes, I'm on Linux machine so I expecting the same behavior as yours. Will report back!

@geet80
Copy link

geet80 commented Apr 3, 2020

Hi I am using Window10 with Feather M0 board, not able to ger serial intialized after awake, please suggest
code is
/*
Simple RTC Alarm for Adafruit Feather M0 modified
with repeated serial output each time the board wakes
By: CaveMoa
Date: 30/12/15
*/
//#define Serial SerialUSB
#include <RTCZero.h>

/* Create an rtc object */
RTCZero rtc;
int AlarmTime;

void setup()
{
rtc.begin();
Serial.begin(9600);
while (! Serial); // Wait until Serial is ready
Serial.println("Ready!");
Serial.end();
}

void loop()
{

AlarmTime = rtc.getSeconds()+10; // Adds 10 seconds to alarm time
AlarmTime = AlarmTime % 60; // checks for roll over 60 seconds and corrects
Serial.print("Next Alarm Time:");
Serial.println(AlarmTime);

rtc.setAlarmSeconds(AlarmTime); // Wakes at next alarm time
rtc.enableAlarm(rtc.MATCH_SS); // Match seconds only
rtc.attachInterrupt(alarmMatch);

Serial.end();
USBDevice.detach(); // Safely detach the USB prior to sleeping
rtc.standbyMode(); // Sleep until next alarm match
USBDevice.init();
USBDevice.attach(); // Re-attach the USB, audible sound on windows machines

// Simple indication of being awake
digitalWrite(13, HIGH); // turn the LED on
delay(100);
digitalWrite(13, LOW); // turn the LED off
delay(100);
digitalWrite(13, HIGH); // turn the LED on
delay(100);
digitalWrite(13, LOW); // turn the LED off

delay(1000); // Delay added to make serial more reliable

Serial.begin(9600);
while (! Serial); // Wait until Serial is ready
delay(1000);
Serial.println("Awake");
}

void alarmMatch() // Do something when interrupt called
{

}

@geet80
Copy link

geet80 commented Apr 9, 2020

Edit: Ah, I see I was ahead of myself. Forgot I already reported back on this a few months ago!

Not using SerialUSB or attach/detach. I was only able to do it by commanding a software reset on the usb module, then re-initializing. I'm on the road now but can attach my code next week if it helps. I think I did a direct write to the software reset bit in the USB register to shut everything down, then used the arduino usb functions to re-initialize.

-Carrie

Sent from my telephone.

Can I have your code ? Is it working?

boseji pushed a commit to go-ut/combined-ArduinoCore-samd that referenced this issue May 30, 2020
@nekuneko
Copy link

This is related to the Not working on SAMD#5 issue from @arduino-libraries ArduinoLowPower library.
arduino-libraries/ArduinoLowPower#5

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

8 participants