Skip to content

Add support for TinyUSB Arduino Library #5333

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
wants to merge 15 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
62 changes: 54 additions & 8 deletions boards.txt
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ menu.LORAWAN_REGION=LoRaWan Region
menu.LoRaWanDebugLevel=LoRaWan Debug Level
menu.LoopCore=Arduino Runs On
menu.EventsCore=Events Run On
menu.USBStack=USB Stack

##############################################################
### DO NOT PUT BOARDS ABOVE THE OFFICIAL ESPRESSIF BOARDS! ###
Expand Down Expand Up @@ -295,6 +296,11 @@ esp32s2.menu.DebugLevel.debug.build.code_debug=4
esp32s2.menu.DebugLevel.verbose=Verbose
esp32s2.menu.DebugLevel.verbose.build.code_debug=5

esp32s2.menu.USBStack.idf=ESP-IDF
esp32s2.menu.USBStack.idf.build.usbstack_flags=
esp32s2.menu.USBStack.tinyusb=Adafruit TinyUSB
esp32s2.menu.USBStack.tinyusb.build.usbstack_flags=-DUSE_TINYUSB "-I{runtime.platform.path}/libraries/Adafruit_TinyUSB_Arduino/src/arduino"

##############################################################

esp32.name=ESP32 Dev Module
Expand Down Expand Up @@ -960,6 +966,11 @@ feathers2.menu.DebugLevel.debug.build.code_debug=4
feathers2.menu.DebugLevel.verbose=Verbose
feathers2.menu.DebugLevel.verbose.build.code_debug=5

feathers2.menu.USBStack.idf=ESP-IDF
feathers2.menu.USBStack.idf.build.usbstack_flags=
feathers2.menu.USBStack.tinyusb=Adafruit TinyUSB
feathers2.menu.USBStack.tinyusb.build.usbstack_flags=-DUSE_TINYUSB "-I{runtime.platform.path}/libraries/Adafruit_TinyUSB_Arduino/src/arduino"

##############################################################

tinys2.name=UM TinyS2
Expand Down Expand Up @@ -1075,6 +1086,11 @@ tinys2.menu.DebugLevel.debug.build.code_debug=4
tinys2.menu.DebugLevel.verbose=Verbose
tinys2.menu.DebugLevel.verbose.build.code_debug=5

tinys2.menu.USBStack.idf=ESP-IDF
tinys2.menu.USBStack.idf.build.usbstack_flags=
tinys2.menu.USBStack.tinyusb=Adafruit TinyUSB
tinys2.menu.USBStack.tinyusb.build.usbstack_flags=-DUSE_TINYUSB "-I{runtime.platform.path}/libraries/Adafruit_TinyUSB_Arduino/src/arduino"

##############################################################
S_ODI_Ultra.name=S.ODI Ultra v1

Expand Down Expand Up @@ -1261,6 +1277,11 @@ micros2.menu.DebugLevel.debug.build.code_debug=4
micros2.menu.DebugLevel.verbose=Verbose
micros2.menu.DebugLevel.verbose.build.code_debug=5

micros2.menu.USBStack.idf=ESP-IDF
micros2.menu.USBStack.idf.build.usbstack_flags=
micros2.menu.USBStack.tinyusb=Adafruit TinyUSB
micros2.menu.USBStack.tinyusb.build.usbstack_flags=-DUSE_TINYUSB "-I{runtime.platform.path}/libraries/Adafruit_TinyUSB_Arduino/src/arduino"

##############################################################
magicbit.name=MagicBit

Expand Down Expand Up @@ -2140,6 +2161,11 @@ sparkfun_esp32s2_thing_plus.menu.DebugLevel.debug.build.code_debug=4
sparkfun_esp32s2_thing_plus.menu.DebugLevel.verbose=Verbose
sparkfun_esp32s2_thing_plus.menu.DebugLevel.verbose.build.code_debug=5

sparkfun_esp32s2_thing_plus.menu.USBStack.idf=ESP-IDF
sparkfun_esp32s2_thing_plus.menu.USBStack.idf.build.usbstack_flags=
sparkfun_esp32s2_thing_plus.menu.USBStack.tinyusb=Adafruit TinyUSB
sparkfun_esp32s2_thing_plus.menu.USBStack.tinyusb.build.usbstack_flags=-DUSE_TINYUSB "-I{runtime.platform.path}/libraries/Adafruit_TinyUSB_Arduino/src/arduino"

##############################################################

sparkfun_lora_gateway_1-channel.name=SparkFun LoRa Gateway 1-Channel
Expand Down Expand Up @@ -3326,7 +3352,7 @@ adafruit_metro_esp32s2.build.core=esp32
adafruit_metro_esp32s2.build.variant=adafruit_metro_esp32s2
adafruit_metro_esp32s2.build.board=METRO_ESP32S2

adafruit_metro_esp32s2.build.serial=0
adafruit_metro_esp32s2.build.serial=1
adafruit_metro_esp32s2.build.f_cpu=240000000L
adafruit_metro_esp32s2.build.flash_size=4MB
adafruit_metro_esp32s2.build.flash_freq=80m
Expand Down Expand Up @@ -3449,16 +3475,21 @@ adafruit_metro_esp32s2.menu.DebugLevel.debug.build.code_debug=4
adafruit_metro_esp32s2.menu.DebugLevel.verbose=Verbose
adafruit_metro_esp32s2.menu.DebugLevel.verbose.build.code_debug=5

adafruit_metro_esp32s2.menu.USBStack.idf=ESP-IDF
adafruit_metro_esp32s2.menu.USBStack.idf.build.usbstack_flags=
adafruit_metro_esp32s2.menu.USBStack.tinyusb=Adafruit TinyUSB
adafruit_metro_esp32s2.menu.USBStack.tinyusb.build.usbstack_flags=-DUSE_TINYUSB "-I{runtime.platform.path}/libraries/Adafruit_TinyUSB_Arduino/src/arduino"


##############################################################

adafruit_magtag29_esp32s2.name=Adafruit MagTag 2.9"
adafruit_magtag29_esp32s2.vid.0=0x239A
adafruit_magtag29_esp32s2.pid.0=0x80DF
adafruit_magtag29_esp32s2.pid.0=0x80E5
adafruit_magtag29_esp32s2.vid.1=0x239A
adafruit_magtag29_esp32s2.pid.1=0x00DF
adafruit_magtag29_esp32s2.pid.1=0x00E5
adafruit_magtag29_esp32s2.vid.1=0x239A
adafruit_magtag29_esp32s2.pid.1=0x80E0
adafruit_magtag29_esp32s2.pid.1=0x80E6

adafruit_magtag29_esp32s2.upload.tool=esptool_py
adafruit_magtag29_esp32s2.upload.maximum_size=1310720
Expand All @@ -3479,7 +3510,7 @@ adafruit_magtag29_esp32s2.build.core=esp32
adafruit_magtag29_esp32s2.build.variant=adafruit_magtag29_esp32s2
adafruit_magtag29_esp32s2.build.board=MAGTAG29_ESP32S2

adafruit_magtag29_esp32s2.build.serial=0
adafruit_magtag29_esp32s2.build.serial=1
adafruit_magtag29_esp32s2.build.f_cpu=240000000L
adafruit_magtag29_esp32s2.build.flash_size=4MB
adafruit_magtag29_esp32s2.build.flash_freq=80m
Expand Down Expand Up @@ -3602,6 +3633,11 @@ adafruit_magtag29_esp32s2.menu.DebugLevel.debug.build.code_debug=4
adafruit_magtag29_esp32s2.menu.DebugLevel.verbose=Verbose
adafruit_magtag29_esp32s2.menu.DebugLevel.verbose.build.code_debug=5

adafruit_magtag29_esp32s2.menu.USBStack.idf=ESP-IDF
adafruit_magtag29_esp32s2.menu.USBStack.idf.build.usbstack_flags=
adafruit_magtag29_esp32s2.menu.USBStack.tinyusb=Adafruit TinyUSB
adafruit_magtag29_esp32s2.menu.USBStack.tinyusb.build.usbstack_flags=-DUSE_TINYUSB "-I{runtime.platform.path}/libraries/Adafruit_TinyUSB_Arduino/src/arduino"


##############################################################

Expand Down Expand Up @@ -3632,7 +3668,7 @@ adafruit_funhouse_esp32s2.build.core=esp32
adafruit_funhouse_esp32s2.build.variant=adafruit_funhouse_esp32s2
adafruit_funhouse_esp32s2.build.board=FUNHOUSE_ESP32S2

adafruit_funhouse_esp32s2.build.serial=0
adafruit_funhouse_esp32s2.build.serial=1
adafruit_funhouse_esp32s2.build.f_cpu=240000000L
adafruit_funhouse_esp32s2.build.flash_size=4MB
adafruit_funhouse_esp32s2.build.flash_freq=80m
Expand Down Expand Up @@ -3755,6 +3791,11 @@ adafruit_funhouse_esp32s2.menu.DebugLevel.debug.build.code_debug=4
adafruit_funhouse_esp32s2.menu.DebugLevel.verbose=Verbose
adafruit_funhouse_esp32s2.menu.DebugLevel.verbose.build.code_debug=5

adafruit_funhouse_esp32s2.menu.USBStack.idf=ESP-IDF
adafruit_funhouse_esp32s2.menu.USBStack.idf.build.usbstack_flags=
adafruit_funhouse_esp32s2.menu.USBStack.tinyusb=Adafruit TinyUSB
adafruit_funhouse_esp32s2.menu.USBStack.tinyusb.build.usbstack_flags=-DUSE_TINYUSB "-I{runtime.platform.path}/libraries/Adafruit_TinyUSB_Arduino/src/arduino"


##############################################################

Expand Down Expand Up @@ -3785,7 +3826,7 @@ adafruit_feather_esp32s2_nopsram.build.core=esp32
adafruit_feather_esp32s2_nopsram.build.variant=adafruit_feather_esp32s2
adafruit_feather_esp32s2_nopsram.build.board=ADAFRUIT_FEATHER_ESP32S2_NOPSRAM

adafruit_feather_esp32s2_nopsram.build.serial=0
adafruit_feather_esp32s2_nopsram.build.serial=1
adafruit_feather_esp32s2_nopsram.build.f_cpu=240000000L
adafruit_feather_esp32s2_nopsram.build.flash_size=4MB
adafruit_feather_esp32s2_nopsram.build.flash_freq=80m
Expand Down Expand Up @@ -3908,6 +3949,11 @@ adafruit_feather_esp32s2_nopsram.menu.DebugLevel.debug.build.code_debug=4
adafruit_feather_esp32s2_nopsram.menu.DebugLevel.verbose=Verbose
adafruit_feather_esp32s2_nopsram.menu.DebugLevel.verbose.build.code_debug=5

adafruit_feather_esp32s2_nopsram.menu.USBStack.idf=ESP-IDF
adafruit_feather_esp32s2_nopsram.menu.USBStack.idf.build.usbstack_flags=
adafruit_feather_esp32s2_nopsram.menu.USBStack.tinyusb=Adafruit TinyUSB
adafruit_feather_esp32s2_nopsram.menu.USBStack.tinyusb.build.usbstack_flags=-DUSE_TINYUSB "-I{runtime.platform.path}/libraries/Adafruit_TinyUSB_Arduino/src/arduino"


##############################################################

Expand Down Expand Up @@ -8851,4 +8897,4 @@ esp32-trueverit-iot-driver-mkii.menu.DebugLevel.debug.build.code_debug=4
esp32-trueverit-iot-driver-mkii.menu.DebugLevel.verbose=Verbose
esp32-trueverit-iot-driver-mkii.menu.DebugLevel.verbose.build.code_debug=5

##############################################################
##############################################################
2 changes: 1 addition & 1 deletion cores/esp32/USB.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
#include "esp32-hal.h"
#include "esp32-hal-tinyusb.h"
#include "USB.h"
#if CONFIG_TINYUSB_ENABLED
#if CONFIG_TINYUSB_ENABLED && !defined(USE_TINYUSB)

#ifndef USB_VID
#define USB_VID USB_ESPRESSIF_VID
Expand Down
7 changes: 6 additions & 1 deletion cores/esp32/USB.h
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,12 @@
#pragma once

#include "sdkconfig.h"
#if CONFIG_TINYUSB_ENABLED

#ifdef USE_TINYUSB // Adafruit TinyUSB is selected in menu

#include "Adafruit_TinyUSB_API.h"

#elif CONFIG_TINYUSB_ENABLED

#include "Arduino.h"
#include "USBCDC.h"
Expand Down
2 changes: 1 addition & 1 deletion cores/esp32/USBCDC.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
#include "esp32-hal-tinyusb.h"
#include "USB.h"
#include "USBCDC.h"
#if CONFIG_TINYUSB_ENABLED
#if CONFIG_TINYUSB_ENABLED && !defined(USE_TINYUSB)

ESP_EVENT_DEFINE_BASE(ARDUINO_USB_CDC_EVENTS);
esp_err_t arduino_usb_event_post(esp_event_base_t event_base, int32_t event_id, void *event_data, size_t event_data_size, TickType_t ticks_to_wait);
Expand Down
8 changes: 7 additions & 1 deletion cores/esp32/USBCDC.h
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,13 @@

#include "Stream.h"
#include "esp32-hal.h"
#if CONFIG_TINYUSB_CDC_ENABLED

#ifdef USE_TINYUSB

// Adafruit TinyUSB is selected in menu
#include "Adafruit_USBD_CDC.h"

#elif CONFIG_TINYUSB_CDC_ENABLED

#include "esp_event.h"

Expand Down
4 changes: 2 additions & 2 deletions cores/esp32/esp32-hal-tinyusb.c
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@

#include "sdkconfig.h"
#if CONFIG_TINYUSB_ENABLED
#if CONFIG_TINYUSB_ENABLED && !defined(USE_TINYUSB)
#include <stdlib.h>
#include <stdbool.h>

Expand Down Expand Up @@ -140,7 +140,7 @@ static tusb_desc_device_t tinyusb_device_descriptor = {
static uint32_t tinyusb_string_descriptor_len = 4;
static char * tinyusb_string_descriptor[MAX_STRING_DESCRIPTORS] = {
// array of pointer to string descriptors
"\x09\x04", // 0: is supported language is English (0x0409)
(char*) "\x09\x04", // 0: is supported language is English (0x0409)
USB_DEVICE_MANUFACTURER,// 1: Manufacturer
USB_DEVICE_PRODUCT, // 2: Product
USB_DEVICE_SERIAL, // 3: Serials, should use chip ID
Expand Down
2 changes: 1 addition & 1 deletion cores/esp32/esp32-hal-tinyusb.h
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
#include "esp32-hal.h"

#if CONFIG_IDF_TARGET_ESP32S2
#if CONFIG_TINYUSB_ENABLED
#if CONFIG_TINYUSB_ENABLED && !defined(USE_TINYUSB)

#ifdef __cplusplus
extern "C" {
Expand Down
5 changes: 5 additions & 0 deletions cores/esp32/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,12 @@ void loopTask(void *pvParameters)
extern "C" void app_main()
{
#if ARDUINO_SERIAL_PORT //Serial used for USB CDC
#ifdef USE_TINYUSB
// Adafruit TinyUSB is selected in menu
TinyUSB_Device_Init(0);
#else
USB.begin();
#endif
#endif
loopTaskWDTEnabled = false;
initArduino();
Expand Down
21 changes: 21 additions & 0 deletions libraries/Adafruit_TinyUSB_Arduino/LICENSE
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
The MIT License (MIT)

Copyright (c) 2019 Ha Thach for Adafruit Industries

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
46 changes: 46 additions & 0 deletions libraries/Adafruit_TinyUSB_Arduino/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
# Adafruit TinyUSB Library for Arduino

[![Build Status](https://github.com/adafruit/Adafruit_TinyUSB_Arduino/workflows/Build/badge.svg)](https://github.com/adafruit/Adafruit_TinyUSB_Arduino/actions) [![License](https://img.shields.io/badge/license-MIT-brightgreen.svg)](https://opensource.org/licenses/MIT)

This library is a Arduino-friendly version of [TinyUSB](https://github.com/hathach/tinyusb) stack. It is designed with structure and APIs that are easily integrated to existing or new Arduino Core. Supported platform including:

- [Adafruit_nRF52_Arduino](https://github.com/adafruit/Adafruit_nRF52_Arduino)
- [Adafruit/ArduinoCore-samd](https://github.com/adafruit/ArduinoCore-samd) selectable via menu`Tools->USB Stack->TinyUSB`
- [earlephilhower/arduino-pico](https://github.com/earlephilhower/arduino-pico) selectable via menu `Tools->USB Stack->Adafruit TinyUSB`

Current class drivers supported are

- Communication (CDC): which is used to implement `Serial` monitor
- Human Interface Device (HID): Generic (In & Out), Keyboard, Mouse, Gamepad etc ...
- Mass Storage Class (MSC): with multiple LUNs
- Musical Instrument Digital Interface (MIDI)
- WebUSB with vendor specific class

For supported ArduinoCore, to use this library, you only need to have `<Adafruit_TinyUSB.h>` in your sketch. If your ArduinoCore does not support TinyUSB library yet, it is rather simple to port.

## Class Driver API

More document to write ...

## Porting Guide

It is rather easy if you want to integrate TinyUSB lib to your ArduinoCore.

### ArduinoCore Changes

1. Add this repo as submodule (or have local copy) at your ArduioCore/libraries/Adafruit_TinyUSB_Arduino (much like SPI).
2. Since Serial as CDC is considered as part of the core, we need to have `#include "Adafruit_USBD_CDC.h"` within your `Arduino.h`. For this to work, your `platform.txt` include path need to have `"-I{runtime.platform.path}/libraries/Adafruit_TinyUSB_Arduino/src/arduino"`.
3. In your `main.cpp` before setup() invoke the `TinyUSB_Device_Init(rhport)`. This will initialize usb device hardware and tinyusb stack and also include Serial as an instance of CDC class.
4. `TinyUSB_Device_Task()` must be called whenever there is new USB event. Depending on your core and MCU with or without RTOS. There are many ways to run the task. For example:
- Use USB IRQn to set flag then invoke function later on after exiting IRQ.
- Just invoke function after the loop(), within yield(), and delay()
5. `TinyUSB_Device_FlushCDC()` should also be called often to send out Serial data as well.
6. Note: For low power platform that make use of WFI()/WFE(), extra care is required before mcu go into low power mode. Check out my PR to circuipython for reference https://github.com/adafruit/circuitpython/pull/2956

### Library Changes

In addition to core changes, library need to be ported to your platform. Don't worry, tinyusb stack has already done most of heavy-lifting. You only need to write a few APIs

1. `TinyUSB_Port_InitDevice()` hardware specific (clock, phy) to enable usb hardware then call tud_init(). This API is called as part of TinyUSB_Device_Init() invocation.
2. `TinyUSB_Port_EnterDFU()` which is called when device need to enter DFU mode, usually by touch1200 feature
3. `TinyUSB_Port_GetSerialNumber()` which is called to get unique MCU Serial ID to used as Serial string descriptor.
Loading