Re: R4 WiFi with USB Host Shield -> Native Host Mode

the MCU on Uno R4 is capable of doing USB host. but on Uno R4 WiFi USB is set off in boards.txt

Arduino UNO R4 doesn't have an AVR processor. The library you try to use obviously dosen't support Arduino UNO R4 (like so many other libraries). Be patient.

1 Like

That was my intention. If you don't appreciate my response, I have to live with it.

That's what made me answer. I apologize for not having checked your background before answering, else I would have been more cautious.

I did something similar here: https://forum.arduino.cc/t/support-mcufriend-uno-tft-shield-on-uno-r4/1151857

USB host shield for Uno R4 in a work in progress.

There is a PR on github Updated for Arduino Uno R4 maxima and wifi by mjs513 · Pull Request #779 · felis/USB_Host_Shield_2.0 · GitHub

1 Like

Here is the link to my repository with the changes: mjs513/USB_Host_Shield_2.0: Revision 2.0 of USB Host Library for Arduino. (github.com). Just download and replace what you currently have. Note: I only tested the xbox controller on wifi so let me know if it works

Mike

1 Like

@Delta_G I have (almost) no cue.
In boards.txt there is -DNO_USB, but it looks like it only disables SerialUSB.

the core has tinyusb and that has usb host support.

USB C OTG

Adafruit has an Arduino library over tinyusb, but it doesn't support host hid yet
https://github.com/adafruit/Adafruit_TinyUSB_Arduino

what i like is that a solution will work for all Arduinos with tinyusb (RP2040, esp32 s3, Adfruit cores)

sorry. yes. it includes tinyusb. I thought it is only a wrapper. but it should work with cores with tinyusb
https://github.com/adafruit/Adafruit_TinyUSB_Arduino#cores-with-built-in-support

the NO_USB is only for the SerialUSB as Serial. you don't need SerialUSB, the connection to Serial Monitor over the S3 is better than directly connected native USB which stops at restart and crash.
For SerialUSB to work the MCU would need the connection to USB connector (pin 40) all the time.

I guess developing with USB would be a little simpler with Uno R4 Minima where the MCU is always connected to USB connector.

how to make UnoR4 WiFi permanently behave on USB like R4 Minima (in IDE then it must be selected as Minima). some changes in variant would be required to use the WiFiS3.
from https://docs.arduino.cc/tutorials/uno-r4-wifi/cheat-sheet#usb-bridge

I have been looking at how the USB device mode Mouse, Keyboard, and HID classes work on Uno R4 WiFi. The HID class switches the USB mux switch so tinyUSB is used in USB device mode on the RA4M1. I have no idea how to make USB host mode work.

Notice when a sketch is uploaded that uses HID class such as KeyboardSerial.ino, the USB VID and PID change from "2341:1002 Arduino SA UNO WiFi R4 CMSIS-DAP" to "2341:006d Arduino SA UNO R4 WiFi". This indicates the USB mux switched to the RA4M1.

I found the incantation for USB mux switching. configure_usb_mux is called from USB.cpp.

In hardware/renesas_uno/1.0.2/variants/UNOWIFIR4/variant.cpp

#define BSP_PRV_PRCR_KEY                (0xA500U)
#define BSP_PRV_PRCR_PRC1_UNLOCK        ((BSP_PRV_PRCR_KEY) | 0x2U)
#define BSP_PRV_PRCR_LOCK               ((BSP_PRV_PRCR_KEY) | 0x0U)
// if _USBStart is called, this will swap the USB port over the ESP one
void configure_usb_mux() {
  R_SYSTEM->PRCR = (uint16_t) BSP_PRV_PRCR_PRC1_UNLOCK;
  (*((volatile uint32_t *) &R_SYSTEM->VBTBKR[1])) = 40;
  R_SYSTEM->PRCR = (uint16_t) BSP_PRV_PRCR_LOCK;

  pinMode(21, OUTPUT);
  digitalWrite(21, HIGH);
}

switchusb.ino

/* WARNING: The Uno R4 WiFi may appear to be dead after this sketch runs.
 * I was able to recover by double clicking the reset button. The
 * timing is tricky (not too fast and not too slow) so don't give up.
 */

// See hardware/renesas_uno/1.0.2/variants/UNOWIFIR4/variant.cpp for the source
// code.
__attribute__((weak)) void configure_usb_mux() {}

void setup() {
#if 0
  // This has no effect on USB.
  pinMode(40, OUTPUT);
  digitalWrite(40, HIGH);
#else
  // USB does not work because the USB mux switched but the tinyusb stack
  // is not initialized. To recover, double click the reset button to
  // get the ESP32-S3 bootloader.
  configure_usb_mux();
  // This may be the time to init tinyUSB in host mode
#endif
}

void loop() {
}
2 Likes

When the RA4M1 USB controller is in device mode and the USB mux is in the correct position, it shows up on the PC USB host port. But if the controller is in host mode it will not show anything on the PC. The USB bus cannot have two hosts. Be careful if connecting USB host to host because USB hosts output power on VUSB. But perhaps I do not understand how you have connected things.

If the RA4M1 USB controller is really in host mode, it should be connected to something like a USB mouse or keyboard. I wonder if when using host mode, Serial output go to a UART port instead.

The other concern is how will the USB device be powered. A USB host port is supposed to provide 5V up to 500 mA. I do not recall if the circuitry is present on the Uno R4 USB connector to detect if the port is in host or device mode. In host mode, VUSB is a power output. In device mode, VUSB is a power input. If the Uno R4 is not designed to output power on VUSB, the USB device must be powered separately. The last time I was concerned about this issue USB OTG used a micro USB connector. I am not sure how type C connectors handle this.

Arduino Due has a USB OTG port which switches between host and device modes. I recall it is able to switch VUSB between input and output determined by the cable plugged into the port. Due also has a second USB port with (I think) a 16u2 connected to a UART port so it is possible to use the UART port for upload and Serial debug (Programming port) even when the USB OTG port (Native port) is in host mode.

This thread talks about controlling the USB mux and whether the uno r4 schematic is correct.

Edit 1: Fix typos.

2 Likes

Your hardware configuration looks good. I do not know what is required to run tinyusb in host mode.

Looking at __USBStart() in USB.cpp. Doesn't the sketch have to have code like the following before calling tuh_init()? Perhaps your sketch does not need to setup interrupts because it will call tuh_task() in loop().

__attribute__((weak)) void configure_usb_mux() {}
    ...
    configure_usb_mux();

    /* 
     * ENABLE USB
     */
    R_SYSTEM->PRCR = (uint16_t) BSP_PRV_PRCR_PRC1_UNLOCK;
    R_MSTP->MSTPCRB &= ~(1U << 11U);
    R_MSTP->MSTPCRB &= ~(1U << 12U);
    R_SYSTEM->PRCR = (uint16_t) BSP_PRV_PRCR_LOCK;

    /*
     * CONFIGURE USB INTERRUPTS
     */
     ...
    /* 
     * INIT Tiny USB in host mode
     */
    tuh_init(BOARD_TUH_RHPORT);
#endif
1 Like

maybe you could modify the OTG adapter by adding a jumper wire to 5 V pin of the Uno?

Well, this is way over my head. I have never dug in so deep on USB hardware/software interface.

Have you considered bluepad32 which supports a variety of gamepads over Bluetooth (BT) Classic and BLE using ESP32? This will not help if you really need USB.

Bluepad32 even supports flashing the NINA (ESP32) module with Bluepad32. There is no indication of support for Uno R4. Bluepad32 supports the Arduino Uno WiFi Rev2 which has a NINA module, Uno form factor, and ATmega4809 thus 5V logic levels if that is needed.

Bluepad32 looks like a cheaper alternative to USB host shield + USB BT gadget. Uno R4 uses ESP32-S3 which only supports BLE so that includes Xbox One controllers but excludes Playstation and Nintendo (BT Classic) controllers.

1 Like

It should also work, when plugged into a Teensy 3.6 or 4.x if you hook up a USB host adapter.

Teensy® 4.1 (pjrc.com)

PJRC Store

Although lately I mostly use my own board with the Micromod Teensy:


A bit dusty... But been playing with it to be able to use the ArduinoBLE library with using the USBHost_t36 library, to try to do BLE... In this case trying to see if I can get that rather common CSR V4.0 dongle to work. Currently the initialization fails and then faults.
(Raised issue in BLE library)... It does work with some other dongles.

But sorry I know this is sort of off topic.

Using pin 40?

1 Like