Skip to content

Nano 33 BLE + USBMouse: need to manually reset the board after reboot #327

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

Closed
hjeldin opened this issue Sep 21, 2021 · 3 comments
Closed

Comments

@hjeldin
Copy link

hjeldin commented Sep 21, 2021

Hey all,
we're using Arduino 1.8.15 + Arduino Mbed Nano Boards 2.4.1.
We're uploading a simple sketch:

#include "PluggableUSBHID.h"
#include "USBMouse.h"
#include <Arduino_LSM9DS1.h>

USBMouse mouse;

void setup() {
  Serial.begin(9600);
  IMU.begin();
  pinMode(LED_BUILTIN,OUTPUT);
}

void loop() {
  float x;
  float xi, yi;
  int elapsed;
  elapsed = millis();
  if(elapsed % 500 <= 250)
  {
    digitalWrite(LED_BUILTIN, 1);
  } else {
    digitalWrite(LED_BUILTIN, 0);
  }

  if (IMU.gyroscopeAvailable()) {
    IMU.readGyroscope(x, xi, yi);
    mouse.move(round(-yi/8.0f), round(-xi/8.0f));
    Serial.println("data");
  }
}

Everything works as expected when first uploaded on the board (and subsequent board resets):

  1. The led turns on and off every 250ms
  2. Data can be read from the serial port
  3. The board is correctly recognized as a HID and actually moves the mouse when tilting it.

As soon as we reboot (or we do a complete shutdown+start) on Windows with the device plugged in weird stuff happens:

  1. The led blinks an indefinite amount of times before stopping (in whatever state it was last). My explaination is that the bios tries to figure out what kind of device it is, manages to exchange some data and then gives the control to the boot manager. As soon as the boot manager is reached (both GRUB or Windows Boot Manager), the led stops blinking.
  2. We can't read data from the serial port, but the port exists and can be read. I assume this would mean that the serial port is opened but no data is being written by the board.
  3. Most importantly: no usb exchange is happening. We can see the device under Device Manager, so it would appear connected, but the mouse stays still. I even installed USBPcap + wireshark to check what was happening, but it refused to inspect the device (probably because something is wrong).

The only way to circumvent this issue is by resetting the board or unplugging it and plugging it again (only after Windows has started). We tested this issue on multiple PCs and multiple Nano 33 BLE boards, so i'd exclude hardware issues.

I assume something wrong is happening while power cycling the board and the initialization of usb communication, but i lack the knowledge required to proficiently debug it.

We tried checking previous issues here, specifically #107, without much luck (meaning even uninstalling the drivers for the device or changing the VID code, the issue persists). We even tried uploading this code via arduino and the issue persists (which makes me think that maybe the issue lies in mbed-os rather than here)

Can anybody help?

Thanks!

@facchinm
Copy link
Member

Hi @hjeldin,
the BootHID protocols are always a big PITA since the BIOS/UEFI is not always implementing the full stack. My suggestion is to add a watchdog (or a thread, since I think the code is not entirely crashed when windows comes up) that recognizes the board being stuck on USB enumeration and resets it.

@hjeldin
Copy link
Author

hjeldin commented Sep 23, 2021

Hi @facchinm,
we followed your advice and set up a proof of concept with a watchdog that awaits for the communication thread to reset an integer.

For reference, this is the code:

#include "mbed.h"
#include "PluggableUSBHID.h"
#include "USBMouse.h"
#include <Arduino_LSM9DS1.h>
using namespace mbed;
using namespace rtos;

Thread t1;
Thread t2;

USBMouse mouse;

int watchdog;
bool ledStatus;

void watchdogThread() {
  while(true) {
    watchdog = watchdog+1;
    Serial.println(watchdog);
    if(watchdog > 5){
      NVIC_SystemReset();
    }
    ledStatus = !ledStatus;
    digitalWrite(LED_BUILTIN, ledStatus);
    wait_us(1000000);
  }
}

void moveMouse() {
  while(true){
    float x;
    float xi, yi;
  
    if (IMU.gyroscopeAvailable()) {
      IMU.readGyroscope(x, xi, yi);
      mouse.move(round(-yi/8.0f), round(-xi/8.0f));
    }

    watchdog = 0;
    
    wait_us(10000);
  }
}

void setup() {
  Serial.begin(9600);
  IMU.begin();
  pinMode(LED_BUILTIN,OUTPUT);
  t1.start(watchdogThread);
  t2.start(moveMouse);
}

void loop() {
  
}

It works flawlessly, even in the bios.

Thanks!

PS: for those who'll use this code i'd suggest to wrap the access to the watchdog variable with a mutex.

@facchinm
Copy link
Member

@hjeldin thank you very very much for getting back with such a wonderful and complete explanation! It will be very useful for future readers 😍

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

2 participants