Skip to content
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

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

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

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

AloyseTech opened this issue Jan 26, 2016 · 13 comments

Comments

@AloyseTech
Copy link

@AloyseTech AloyseTech commented Jan 26, 2016

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

This comment has been minimized.

Copy link
Member

@sandeepmistry sandeepmistry commented Mar 3, 2016

@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

This comment has been minimized.

Copy link
Author

@AloyseTech AloyseTech commented Mar 3, 2016

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

This comment has been minimized.

Copy link

@casundra casundra commented Mar 28, 2016

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

This comment has been minimized.

Copy link
Author

@AloyseTech AloyseTech commented Mar 28, 2016

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

This comment has been minimized.

Copy link

@casundra casundra commented Mar 28, 2016

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

This comment has been minimized.

Copy link
Author

@AloyseTech AloyseTech commented May 27, 2016

Hi,

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

@casundra

This comment has been minimized.

Copy link

@casundra 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.

@PTS93

This comment has been minimized.

Copy link

@PTS93 PTS93 commented Apr 17, 2018

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

@rocketscream

This comment has been minimized.

Copy link

@rocketscream rocketscream commented Sep 23, 2018

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

This comment has been minimized.

Copy link
Member

@facchinm 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

This comment has been minimized.

Copy link

@rocketscream rocketscream commented Oct 1, 2018

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

@facchinm

This comment has been minimized.

Copy link
Member

@facchinm 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

This comment has been minimized.

Copy link

@rocketscream rocketscream commented Oct 1, 2018

@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!

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

Successfully merging a pull request may close this issue.

None yet
6 participants
You can’t perform that action at this time.