Compare commits

...

215 commits

Author SHA1 Message Date
Tyeth Gundry
737dfb2115
Update library.json - 3.7.1 2025-07-17 11:49:41 +01:00
Tyeth Gundry
766d8cca00
Update library.properties - 3.7.1 2025-07-17 11:49:27 +01:00
Ha Thach
d3cc12070a
Merge pull request #540 from adafruit/update-bug-template
Update bug_report.yml
2025-07-15 10:37:45 +07:00
Ha Thach
86dfc05234
Merge pull request #539 from valeros/patch-1
Remove redundant USE_TINYUSB macro from PlatformIO library manifest
2025-07-15 10:30:04 +07:00
Ha Thach
8f13cb8bca
Update bug_report.yml 2025-07-15 10:19:48 +07:00
Valerii Koval
fb9763423c
Remove redundant USE_TINYUSB macro 2025-07-14 16:36:00 +03:00
Tyeth Gundry
7b30ff9e14
Update library.properties - bump version to 3.7.0 2025-06-17 19:36:00 +01:00
Tyeth Gundry
0e054b598b
Update library.json - bump version to 3.7.0 2025-06-17 19:35:40 +01:00
Ha Thach
5ab76b7931
Merge pull request #536 from adafruit/update-example
Update example
2025-06-10 17:14:19 +07:00
hathach
028629e93e
add fruitjam sdfat pinout support 2025-06-10 16:18:49 +07:00
hathach
8c615b6519
update pio-usb host requirement to only multiple of 12Mhz (previously 120Mhz) 2025-06-10 16:18:16 +07:00
Tyeth Gundry
d4071f5abe
Update library.json - bump version to 3.6.1 2025-06-03 18:53:58 +01:00
Tyeth Gundry
4daede3744
Update library.properties - bump version to 3.6.1 2025-06-03 18:53:46 +01:00
Ha Thach
44053c45df
Merge pull request #533 from adafruit/fix-metro-rp2040-msc-sdfat-macos-conflict 2025-05-31 11:03:15 +07:00
hathach
eaa9bfdaa5
update msc_sdfat.ino and msc_external_flash_sdcard.ino to
- use SDIO (pio) for rp2040/rp2350
- remove printing flash/sdcard contents to Serial since it conflict with host, which can cause conflict in spi/sdio transport and/or correupt cache,sector
2025-05-30 19:59:27 +07:00
Tyeth Gundry
9806375c60
Update library.properties - bump version to 3.6.0 2025-05-28 15:40:58 +01:00
Tyeth Gundry
e896107698
Update library.json - bump version to 3.6.0 2025-05-28 15:40:44 +01:00
Ha Thach
805aa2d41a
Merge pull request #530 from adafruit/test-metro-rp2040-sd
update msc sdcad example to work with metro rp2040
2025-05-22 22:42:50 +07:00
hathach
fee8a5e6bc
update msc sdcad example to work with metro rp2040 2025-05-22 15:58:03 +07:00
Ha Thach
59d4393012
Merge pull request #529 from adafruit/add-set-maxpower
add setConfigurationMaxPower() and setConfigurationAttribute
2025-05-22 11:48:06 +07:00
hathach
60fb663caa
add Adafruit_USBD_Device::setConfigurationMaxPower() and setConfigurationAttribute 2025-05-22 11:07:31 +07:00
Ha Thach
cdc07c1d96
Merge pull request #505 from Props3D/master
USB Device Descriptor Max Power is not configurable #504
2025-05-22 11:02:59 +07:00
Ha Thach
794ac7f34b
bump up version to 3.5.0 2025-05-21 17:29:16 +07:00
Ha Thach
9496740134
Merge pull request #528 from adafruit/fix-esp32-max3421e
fix compiling hcd max3421e with arduino-esp32 and arduino-pico due to missing atomic_flag function
2025-05-21 17:25:39 +07:00
hathach
6fa11c4d5e
bump up tinyusb to commit e41a63c60dbebd9579698e6444bc62cfa518e15c 2025-05-21 17:03:01 +07:00
Tyeth Gundry
f05bd099c3
Update library.properties - bump version to 3.4.5 2025-05-09 21:57:55 +01:00
Tyeth Gundry
951dba38f6
Update library.json - bump version to 3.4.5 2025-05-09 21:57:43 +01:00
Ha Thach
5618d9c054
Merge pull request #525 from adafruit/fix-sigma-mouse
fix sigma mouse in adafruit store cause multiple attach connection
2025-05-06 21:43:30 +07:00
hathach
46d2c6cb49
update tinyusb to commit 809af3e74ca37495d6c385acd33a488c2984a093 2025-05-06 16:14:14 +07:00
hathach
23426ed3f6
fix sigma mouse in adafruit store cause multiple attach connection 2025-05-05 23:31:59 +07:00
Ha Thach
72cd81005b
Merge pull request #523 from adafruit/update-tinyusb-commit-1a783b357343d053eb861ae783922371ce9e1b17
update tinyusb to commit 1a783b357343d053eb861ae783922371ce9e1b17
2025-05-05 17:33:24 +07:00
hathach
fafc824f6b
update tinyusb to 1a783b3573 2025-05-05 10:00:12 +07:00
Tyeth Gundry
6b772c0ac4
Update library.properties - bump version to 3.4.4 2025-03-25 17:51:36 +00:00
Tyeth Gundry
560a21bdec
Update library.json - bump version to 3.4.4 2025-03-25 17:51:21 +00:00
Ha Thach
4b9a629a55
Merge pull request #510 from adafruit/fix-esp32-max3421e
Fix esp32 max3421e
2025-03-20 20:09:29 +07:00
hathach
55a0283b48
skip more examples 2025-03-20 10:28:09 +07:00
hathach
332b0c8e31
skip device example for feather_esp32_v2 2025-03-20 09:50:31 +07:00
hathach
f83e0ce0ff
only enable CFG_TUD_ENABLED with esp wgen CONFIG_USB_OTG_SUPPORTED = 1. Add feather_esp32_v2 to ci pool 2025-03-19 16:54:45 +07:00
Props3D - Craig
d522523fd1 USB Device Descriptor Max Power is not configurable #504
Replacing hardcoded value with define macro
2025-03-07 17:32:30 -08:00
Tyeth Gundry
76a551be81
Update library.json - bump version to 3.4.3 2025-03-07 19:18:47 +00:00
Tyeth Gundry
f4e8959828
Update library.properties - bump version to 3.4.3 2025-03-07 14:30:33 +00:00
Ha Thach
7b22bd0adf
Merge pull request #503 from adafruit/support-esp32p4
support esp32p4
2025-03-07 17:08:11 +07:00
hathach
36396f4f9e
fix esp32p4 build due to lack of LED_BUILTIN 2025-03-07 16:42:10 +07:00
hathach
cfe6da84d1
fix build with host native 2025-03-07 12:48:59 +07:00
hathach
7f7ac74899
support esp32p4 2025-03-07 12:20:53 +07:00
Ha Thach
8ef30202e5
Merge pull request #498 from adafruit/update-tinyusb-1cfc88dbcb8cff6f926aef02c5609880169ec94c
Update tinyusb to commit 334ac8072650e3b18278042c2c2b402db73c7359
2025-03-07 10:58:24 +07:00
hathach
3918606fbe
update to commit 334ac8072650e3b18278042c2c2b402db73c7359 2025-03-07 10:07:41 +07:00
hathach
1d3576a40a
enable CFG_TUH_MAX3421 and skip native host dwc2 for esp32 2025-03-06 22:42:57 +07:00
hathach
605d681c81
feat(esp32) resolve conflict with latest v3.1.3. better enforce tusb_config_esp32.h within tusb_option.h
also change CFG_TUD_MIDI_RX/TX_BUFSIZE for rp2040 to 64
2025-03-06 21:18:54 +07:00
hathach
41bde22a7c
change to "SdFat_Adafruit_Fork.h" and revert to build sdfat examples 2025-03-05 22:52:39 +07:00
hathach
411821714b
update tinyusb to commit 51cfae6e97b08e9c34a4551cfa45c85a2498a943 2025-03-04 17:30:48 +07:00
hathach
aba2328b00
skip example with SdFat for rp2040 due to conflict with builtin vs Adafruit's Fork of SdFat 2025-02-26 17:10:26 +07:00
hathach
f12e3f2886
add missing files 2025-02-26 16:04:17 +07:00
hathach
a17922159b
temp patch for rp2040 lacking atomic flags test/set 2025-02-26 15:58:14 +07:00
hathach
96ac318c19
implement tusb_time_millis_api() 2025-02-26 13:10:12 +07:00
hathach
8f2d3edd77
update tinyusb to upstream 1cfc88dbcb 2025-02-26 12:48:44 +07:00
Tyeth Gundry
c92b7fde16
Update library.properties - bump version to 3.4.2 2024-12-12 18:45:22 +00:00
Ha Thach
85476dcd8f
Merge pull request #475 from OrhanYigitDurmaz/master
Bring library.json up to date
2024-12-02 15:06:31 +07:00
Orhan Yiğit Durmaz
8077b62029 Update library.json 2024-12-01 10:45:40 -08:00
Orhan Yiğit Durmaz
c976061caa fix platformio issue 2024-12-01 10:35:18 -08:00
Tyeth Gundry
f5211f4226
Update library.properties - bump version to 3.4.1 2024-11-19 19:50:14 +00:00
Ha Thach
f8ac8130c5
Merge pull request #452 from westinpigott/patch-1
Enable multiple serial over usb for rp2040
2024-11-15 12:31:23 +07:00
Ha Thach
1798428b15
Update library.properties
bump library for release
2024-10-24 17:44:30 +07:00
Ha Thach
5920d15f73
Merge pull request #466 from adafruit/update-tinyusb-fix-esp32-build
update tinyusb to fix esp32 build with v3.0.7
2024-10-24 17:43:46 +07:00
hathach
71e2c4a4bd
fix undefined reference to `__atomic_test_and_set' with rp2040 with gcc 14.2. Temporarily modify to use native semaphore 2024-10-24 16:12:17 +07:00
hathach
f13b57a01a
update tinyusb to commit 8b1e40c3e2447de5b4a86bbcdcc0344946a4793d 2024-10-23 21:20:25 +07:00
Tyeth Gundry
a529a74e4f
Update library.properties - bump version to 3.3.4 2024-09-18 19:48:04 +01:00
Ha Thach
05686e7f97
Merge pull request #454 from adafruit/force-example-re_enum
force re-enumerate for all examples.
2024-09-05 17:33:54 +07:00
hathach
59a651cca0
force re-enumerate for all examples. For some fast chip such as esp32-s3, by the time we initialize class driver enumeration process is already done. 2024-09-05 16:15:34 +07:00
Ha Thach
2df6d2905e
Merge pull request #453 from adafruit/update-tinyusb-55951b71aea46c09f27afe1640454fe43c983eec
update tinyusb to commit 55951b71aea46c09f27afe1640454fe43c983eec
2024-09-05 15:42:50 +07:00
hathach
a7c9db3f62
update tinyusb to commit 55951b71aea46c09f27afe1640454fe43c983eec 2024-09-05 14:26:59 +07:00
Westin Pigott
0a9c3fe818
Enable multiple serial over usb for rp2040 2024-09-03 14:41:27 -04:00
Tyeth Gundry
446e0af7a9
Update library.properties - bump version to 3.3.3 2024-08-13 22:28:39 +01:00
Ha Thach
f752bc6e05
Merge pull request #448 from adafruit/more-ch32v203-update
update tinyusb to fix ch32v203 race with hub in setup
2024-08-13 20:28:35 +07:00
hathach
8587060a19
update tinyusb to fix ch32v203 race with hub in setup 2024-08-13 16:14:46 +07:00
Ha Thach
0061a40530
Merge pull request #443 from adafruit/update-tinyusb-fsdev
update tinyusb to improve fsdev driver for ch32v203
2024-08-08 22:43:54 +07:00
hathach
9aaf9b56bb
add back weak callback for tud_vendor_control_xfer_cb due to conflict with arduino esp32 2024-08-08 20:56:14 +07:00
hathach
7a32772d52
add back weak callback for tud_descriptor_bos_cb to prevent conflict issue with esp32 core 2024-08-08 18:23:07 +07:00
hathach
c748ad674a
forgot to add fsdev_type.h 2024-08-08 17:36:28 +07:00
hathach
4c6e9ce4e0
make webusb tud_vendor_control_xfer_cb() weak by default to be overwritable for user sketch 2024-08-08 16:30:31 +07:00
hathach
e92d597803
update tinyusb to https://github.com/hathach/tinyusb/pull/2750 to fix ch32v203 2024-08-08 15:46:07 +07:00
hathach
889a5d65ed
udpate tinyusb to c60934eedc 2024-07-31 21:51:26 +07:00
Tyeth Gundry
51a9de832e
Update library.properties - bump version to 3.3.2 2024-07-23 15:15:03 +01:00
Ha Thach
3bd0180973
Merge pull request #441 from adafruit/fix-feather52832-build
fix build with nrf52832
2024-07-18 17:42:41 +07:00
hathach
264556032f
fix build with nrf52832 2024-07-18 17:15:58 +07:00
Tyeth Gundry
e034538570
Update library.properties - bump version to 3.3.1 2024-06-25 16:33:46 +01:00
Ha Thach
c67266b094
Update library.properties 2024-06-20 22:03:20 +07:00
Ha Thach
c1cab3e41c
Update README.md 2024-06-20 22:02:05 +07:00
Ha Thach
1f9da4918f
bump up version to 3.3.0 2024-06-20 21:47:56 +07:00
Ha Thach
a56612b5a9
Merge pull request #429 from adafruit/ch32-core-support
Add Ch32 built-inn core support
2024-06-20 21:46:48 +07:00
Tyeth Gundry
6cc5113f35
Update library.properties - bump version to 3.2.0 2024-06-18 12:37:24 +01:00
hathach
8cb40327f1
update tinyusb core for better ch32v103 support, but not working with v103 just yet 2024-06-14 17:01:00 +07:00
hathach
468f72001e
update bulk to have 512 for highspeed usb, tested usbhs with v307 using 144mhz hse 2024-06-13 23:33:29 +07:00
hathach
1b9e433c75
update to work with ch32v307 usbfs 2024-06-13 22:59:49 +07:00
hathach
f5ad52fe7f
more update for ch32 2024-06-13 11:46:13 +07:00
hathach
d1708bc87f
move menu check to TinyUSB_API 2024-06-13 11:31:12 +07:00
hathach
f2168e439f
define Serial as SerialTinyUSB if USE_TINYUSB is defined 2024-06-13 10:31:28 +07:00
Ha Thach
69333be53d
Merge pull request #428 from adafruit/add-ch32v2-support
Add ch32v2 support
2024-06-11 17:54:57 +07:00
hathach
7ca12e3688
update build_all.py 2024-06-11 16:10:19 +07:00
hathach
efa33be67c
clean up 2024-06-11 14:17:02 +07:00
hathach
e7941194dc
skip more 2024-06-11 13:14:33 +07:00
hathach
6f0f7e6a05
skip non-compilable for ch32v2 2024-06-11 13:08:38 +07:00
hathach
1c1a65c834
add more .skip.txt 2024-06-11 12:53:32 +07:00
hathach
f2286b88a8
test skip.txt 2024-06-11 12:33:29 +07:00
hathach
4d5e4231e2
fix ci 2024-06-10 23:52:59 +07:00
hathach
ee005588d0
define SerialTinyUSB Serial for esp32 2024-06-10 17:53:13 +07:00
hathach
75fd754212
use arduino lib as escape string 2024-06-10 16:38:31 +07:00
hathach
6d6cd1788b
use env for ARDUINO_LIBS, try to build ch32 2024-06-10 16:22:38 +07:00
hathach
8f7fe509d1
- add CDC/serial_echo example using SerialTinyUSB
- call CDC flush in task() for core without tinyusb builtin support
2024-06-10 16:07:10 +07:00
hathach
2179aeb6d2
most example works with ch32: hid,msc,midi though mouse_ramdisk does not. 2024-06-07 21:04:53 +07:00
hathach
2e8f1b5c33
initial support for ch32 with usbd 2024-06-07 13:24:50 +07:00
hathach
c0e19ef533
add tinyusb driver for ch32: usbfs, stm32fsdev, usbhs 2024-06-07 12:21:01 +07:00
Tyeth Gundry
c953968c46
Update library.properties - bump version to 3.1.5 2024-06-04 17:15:23 +01:00
Ha Thach
10b35388a3
Merge pull request #423 from BadCD/patch-1 2024-05-31 18:18:34 +07:00
BadCD
28dd927214
Update cdc_multi.ino
fixed a typo
2024-05-31 10:57:21 +02:00
Ha Thach
e90e6be60f
Merge pull request #422 from adafruit/update-tinyusb-1fe86f654fdca8a4a555737f34215582a812b481
Update tinyusb to 1fe86f654fdca8a4a555737f34215582a812b481
2024-05-29 16:35:25 +07:00
hathach
f7e7028fd6
skip build test with esp32 v2 2024-05-29 16:22:25 +07:00
hathach
2682fe811b
correct esp32 v2 ci build 2024-05-29 15:07:07 +07:00
hathach
93f546aa19
specify v2.0.17 (last v2 version) 2024-05-29 12:53:05 +07:00
hathach
307e8dc52b
switch ci to ref: importable-build_platform 2024-05-29 11:23:24 +07:00
hathach
320903f0d8
update tinyusb to commit 1fe86f654fdca8a4a555737f34215582a812b481 2024-05-29 10:33:03 +07:00
Tyeth Gundry
c0ba78e110
Update library.properties - bump version to 3.1.4 2024-05-01 16:19:15 +01:00
Ha Thach
8cdf80ab42
Merge pull request #414 from adafruit/update-tinyusb-022de87
Update tinyusb 022de87
2024-04-26 15:14:11 +07:00
hathach
78f060b048
list core/lib in esp-stable 2024-04-26 14:50:57 +07:00
hathach
a3abd887a9
fix ci syntax 2024-04-26 13:49:52 +07:00
hathach
e6d15a2c3f
update ci to also build with arduino-esp32 stable 2024-04-26 13:48:06 +07:00
hathach
a8aae07ec5
update tinyusb to commit 022de87 2024-04-26 11:10:15 +07:00
Ha Thach
b1eb772117
Merge pull request #413 from adafruit/update-max3421e-sketch-for-c6
use correct pin D8, D7 for feather c6 in max3421e sketch
2024-04-26 00:36:14 +07:00
hathach
f5a27167f6
use correct pin D8, D7 for feather c6 in max3421e sketch 2024-04-26 00:27:44 +07:00
Tyeth Gundry
d629476752
Update library.properties - bump version to 3.1.3 2024-03-26 13:10:47 +00:00
Ha Thach
df1a09fe48
Merge pull request #408 from adafruit/update-tinyusb-pr2526
update tinyusb to include uvc hardfault fix
2024-03-22 21:25:31 +07:00
hathach
681746cc58
update tinyusb to include uvc hardfault fix 2024-03-21 16:29:21 +07:00
Ha Thach
040eb93e77
Merge pull request #404 from adafruit/update-tinyusb-15775727e7e29cf6b4d748f01d9457479f8f6899 2024-03-14 19:08:08 +07:00
hathach
ebe252cd5a
update tinyusb to 15775727e7 2024-03-14 16:24:28 +07:00
Ha Thach
631d192b10
Merge pull request #378 from tlyu/override-tud-cfg
allow override of TUD interface counts
2024-03-13 18:02:06 +07:00
Tyeth Gundry
f755225450
Update library.properties - bump version to 3.1.1 2024-03-11 15:45:06 +00:00
Ha Thach
1679e75595
Merge pull request #402 from earlephilhower/a123 2024-03-08 09:30:19 +07:00
Earle F. Philhower, III
2c6f60941e Remove GCC 12 warning in Vendor example 2024-03-07 11:15:32 -08:00
Ha Thach
2ebb6ab2bf
Merge pull request #393 from adafruit/hathach-bump-v3.1 2024-02-20 15:12:12 +07:00
Ha Thach
cc0babfe1b
fix typo 2024-02-20 14:29:20 +07:00
Ha Thach
c1d2eed330
Update README.md 2024-02-20 14:27:55 +07:00
Ha Thach
6dab54c855
Merge pull request #392 from adafruit/fix-config-typo
fix CFG_TUD_ENDPOINT0_SIZE typo
2024-02-20 14:17:38 +07:00
Ha Thach
2913c9cb2b
Merge pull request #391 from adafruit/update-ramdisk-with-start-stop
Update ramdisk with start stop
2024-02-20 14:13:17 +07:00
Ha Thach
16168f09dc
bump up version for 3.1 release 2024-02-20 14:09:13 +07:00
hathach
e12a2f80f8 fix CFG_TUD_ENDPOINT0_SIZE typo 2024-02-20 14:00:54 +07:00
hathach
dac1eee654 clean up 2024-02-20 13:58:52 +07:00
hathach
8bd4ee67b2 add star/stop callback to ramdisk example 2024-02-20 13:54:08 +07:00
Ha Thach
e39183c0da
Merge pull request #390 from adafruit/fix-384
Fix  undefined reference to `log_printf' when enable debug with native usb host
2024-02-20 12:51:48 +07:00
hathach
7be2c9a613 fix debug eanble with host native 2024-02-20 10:49:04 +07:00
hathach
1366ac5d50 skip all device example for native host 2024-02-19 18:17:35 +07:00
hathach
4fb7872555 skip some tests with native host 2024-02-19 18:02:51 +07:00
Ha Thach
9851a7d7b0
Merge pull request #382 from tlyu/hid-getprotocol
add Adafruit_USBD_HID::getProtocol
2024-02-19 17:44:37 +07:00
hathach
7b257c0f86 eanble ci for rp2040 tinyusb native host 2024-02-19 17:38:44 +07:00
Ha Thach
232be2f7ab
Merge pull request #388 from adafruit/fix-esp32-v2-build
fix build with esp32 v2
2024-02-19 16:57:53 +07:00
Ha Thach
e5ae023803
Merge pull request #386 from earlephilhower/gccwarn
Fix GCC 12.3 warning in USB Video core
2024-02-19 16:53:48 +07:00
hathach
fc0ecddc0d fix build with esp32 v2 2024-02-19 16:38:57 +07:00
Earle F. Philhower, III
8dc1275ede Fix GCC 12.3 warning in USB Video core
GCC 12 complains when a structure member is not initialized, so set a
sane default value.

Fixes #385
2024-02-13 10:47:29 -08:00
Taylor Yu
99736ac1ac add Adafruit_USBD_HID::getProtocol
Add a getProtocol method, allowing an application to query whether the
HID interface is currently set to Boot or Report Protocol.
2024-02-08 09:22:13 -06:00
Taylor Yu
8ee7989e42 allow override of TUD interface counts
This allows a board definition to override interface counts on the
compiler command line, instead of replacing the entire tusb_config.h
file.
2024-02-07 10:43:56 -06:00
Ha Thach
2e5fb959b5
fix typo 2024-02-06 13:26:58 +07:00
Ha Thach
756970144f
Update README.md 2024-02-06 13:24:47 +07:00
Ha Thach
56d4b611f2
Merge pull request #376 from adafruit/release-3.0
bump up release and API macros
2024-02-06 13:22:09 +07:00
hathach
29e0d60db6 bump up release and API macros 2024-02-06 13:06:56 +07:00
Ha Thach
5cd4063bb8
Merge pull request #372 from adafruit/rework-esp-config-desc-builder
Rework ESP32 configuration descriptor builder
2024-02-06 12:58:45 +07:00
hathach
1bae99a760 clean up 2024-02-06 12:45:18 +07:00
hathach
6c7624fcdc minor change config 2024-02-05 18:30:42 +07:00
hathach
2ff208bbe0 add dwc2 driver for esp32 2024-02-05 18:25:17 +07:00
hathach
55eebb98c0 more clean up, use log_pritnf for debugging tinyusb with esp32 2024-02-05 12:57:50 +07:00
hathach
9eae19b58a clean up midi 2024-02-05 12:05:03 +07:00
hathach
10e0c41466 fix clang 2024-02-05 11:44:06 +07:00
hathach
f0f92403f7 clean up webusb 2024-02-05 11:41:00 +07:00
hathach
15111810b0 clean up msc class 2024-02-05 11:30:12 +07:00
hathach
fe14079068 fix hid out endpoint generation, update all hids examples to use dynamic set instead of constructor 2024-02-02 19:42:20 +07:00
hathach
12a186b550 update HID to work with new esp32 config descriptor builder 2024-02-02 19:05:46 +07:00
hathach
6e77d5b4a5 rework esp32 configuration descriptor builder to manage our own descriptor 2024-02-02 18:17:31 +07:00
hathach
7dfc5ab324 clean up 2024-02-02 17:00:11 +07:00
Ha Thach
185692be69
bump up version 2.4.1 2024-02-01 16:10:44 +07:00
hathach
bd3fba42d4 sync tinyusb upstream 2024-02-01 13:22:55 +07:00
Ha Thach
27ae871a8b
Merge pull request #371 from adafruit/enhance-uvc
Enhance uvc
2024-02-01 13:00:23 +07:00
hathach
fb2bfc3e57 fix ci build 2024-01-31 23:18:34 +07:00
hathach
19814da37b rework video configuration builder 2024-01-31 19:40:58 +07:00
hathach
5564bbd997 update tinyusb to have lastest uvc upstream 2024-01-31 11:22:08 +07:00
Tyeth Gundry
a93bb80c6e
Update library.properties - bumlo 2024-01-30 22:37:51 +00:00
Ha Thach
766a14babd
Merge pull request #370 from adafruit/rework-config-descriptor-builder
Rework config descriptor builder
2024-01-31 01:13:05 +07:00
hathach
a9262b4c21 update to actions/setup-python@v5 2024-01-31 00:48:56 +07:00
hathach
cbfff996b3 fix warnings with esp32 2024-01-31 00:36:30 +07:00
hathach
d8e9044069 increase TINYUSB_API_VERSION to 20400 for new _strid and new configuration builder
add backward compatible with core including pre-2.4.0 version
2024-01-30 23:19:36 +07:00
hathach
b5fb020216 rename itfnum to itfnum_deprecated instead of dropping 2024-01-30 20:22:35 +07:00
hathach
9047e04cae Revert "drop itfnum in signature of Adafruit_USBD_Interface::getInterfaceDescriptor()"
This reverts commit 0df71c015f.
2024-01-30 19:33:39 +07:00
hathach
0df71c015f drop itfnum in signature of Adafruit_USBD_Interface::getInterfaceDescriptor() 2024-01-30 18:13:36 +07:00
hathach
52fca115ba rework configuration builder with new allocInterface(), allocEndpoint() 2024-01-30 18:02:52 +07:00
Ha Thach
7a926e8fb9
Merge pull request #367 from adafruit/fix-esp32-build
fix esp32 out of sync with esp core v2.0.14
2024-01-25 19:17:15 +07:00
hathach
fe5a155381 fix esp32 out of sync with esp core v2.0.14 2024-01-25 19:00:15 +07:00
Ha Thach
208f6c8e4c
Merge pull request #366 from adafruit/enable-uvc-rp2040
Add Video class support
2024-01-25 16:19:02 +07:00
hathach
70fd45a713 enable uvc for samd and nrf 2024-01-25 15:48:03 +07:00
hathach
536c8233b5 bump up frame rate to 30fps in example 2024-01-25 11:47:00 +07:00
hathach
9db1fdf435 adjust streaming interface number in VC Header, and endpoint address in VS input/output header 2024-01-25 11:36:11 +07:00
hathach
fb97586573 eanble video and video streaming, start adding usbd video class, update interface desc parsing to update IAD number 2024-01-24 17:31:51 +07:00
Tyeth Gundry
693f7d4bd5
Update library.properties - bump version to 2.3.3 2024-01-23 15:13:34 +00:00
Ha Thach
f36defbf26
Merge pull request #364 from adafruit/enable-ch340x-configure
enable CFG_TUH_CDC_CH34X config for all ports
2024-01-23 18:42:03 +07:00
hathach
8d996db507 enable CFG_TUH_CDC_CH34X config for all ports 2024-01-23 18:18:09 +07:00
Ha Thach
6481d697a7
Merge pull request #363 from adafruit/update-tinyusb-for-ch34x-host
update tinyusb for ch34x host support
2024-01-23 00:13:59 +07:00
hathach
5bbad8d1eb update tinyusb for ch34x host support 2024-01-22 23:20:14 +07:00
Tyeth Gundry
eb09bb48d7
Update library.properties - bump version to 2.3.2 2024-01-16 19:19:39 +00:00
Ha Thach
6de4a11a3b
Merge pull request #361 from adafruit/update-tinyusb-to-fix-357
update tinyusb to pr https://github.com/hathach/tinyusb/pull/2412
2024-01-12 16:22:35 +07:00
hathach
565619630e update tinyusb to pr https://github.com/hathach/tinyusb/pull/2412 2024-01-12 16:07:25 +07:00
Tyeth Gundry
ac087e4bd3
Update library.properties - bump version to 2.3.1 2023-12-27 15:34:10 +00:00
Ha Thach
541fc93a67
Merge pull request #356 from adafruit/correct-feather-esp32v2-pin
correct feather esp32 v2 with max3421e pin
2023-12-27 16:20:39 +07:00
hathach
e4e854ea2a correct feather esp32 v2 with max3421e pin 2023-12-27 15:56:22 +07:00
Ha Thach
de5353d0ca
Merge pull request #355 from adafruit/add-rp2040-max3421e-support
Add rp2040 max3421e support
2023-12-26 23:19:44 +07:00
hathach
31f1edc668 add specific example for max3421e: device_info_max3421e 2023-12-26 23:05:37 +07:00
hathach
6905192954 update tinyusb, config and add rp2040 driver for max3421e as host 2023-12-26 23:02:07 +07:00
Ha Thach
e291865233
Merge pull request #354 from adafruit/release-2.3.0
bump up version 2.3.0
2023-12-25 10:56:54 +07:00
Ha Thach
e7985fa52e
Update library.properties 2023-12-23 14:58:22 +07:00
Ha Thach
89ffd9dca5
Merge pull request #353 from adafruit/suport-pico-host-native
support rp2040 native usb host configuration
2023-12-23 14:57:15 +07:00
228 changed files with 24360 additions and 9803 deletions

View file

@ -46,7 +46,7 @@ body:
- type: input
attributes:
label: TinyUSB Library version
placeholder: "Release version or github latest"
placeholder: "Release version or commit SHA"
validations:
required: true
@ -100,3 +100,11 @@ body:
description: If applicable, add screenshots to help explain your problem.
validations:
required: false
- type: checkboxes
attributes:
label: I have checked existing issues, pr, discussion and documentation
description: You agree to check all the resources above before opening a new issue.
options:
- label: I confirm I have checked existing issues, pr, discussion and documentation.
required: true

View file

@ -3,23 +3,21 @@ name: Build
on: [pull_request, push, repository_dispatch]
concurrency:
group: ${{ github.workflow }}-${{ github.head_ref || github.run_id }}
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true
env:
ARDUINO_LIBS: "\"Adafruit SPIFlash\" \"Adafruit seesaw Library\" \"Adafruit NeoPixel\" \"Adafruit Circuit Playground\" \"Adafruit InternalFlash\" \"SdFat - Adafruit Fork\" \"SD\" \"MIDI Library\" \"Pico PIO USB\""
jobs:
pre-commit:
runs-on: ubuntu-latest
steps:
- name: Setup Python
uses: actions/setup-python@v4
with:
python-version: '3.x'
- name: Checkout code
uses: actions/checkout@v4
- name: Run pre-commit
uses: pre-commit/action@v3.0.0
uses: pre-commit/action@v3.0.1
- name: Checkout adafruit/ci-arduino
uses: actions/checkout@v4
@ -39,6 +37,9 @@ jobs:
PRETTYNAME : "Adafruit TinyUSB Library"
run: bash ci/doxy_gen_and_deploy.sh
# ---------------------------------------
# build
# ---------------------------------------
build:
runs-on: ubuntu-latest
needs: pre-commit
@ -46,24 +47,23 @@ jobs:
fail-fast: false
matrix:
arduino-platform:
# ESP32
# ESP32 ci use dev json
- 'feather_esp32_v2'
- 'feather_esp32s2'
- 'feather_esp32s3'
- 'esp32p4'
# nRF52
- 'cpb'
- 'nrf52840'
# RP2040
- 'feather_rp2040_tinyusb'
- 'pico_rp2040_tinyusb_host'
# SAMD
- 'metro_m0_tinyusb'
- 'metro_m4_tinyusb'
# Ch32v2
- 'CH32V20x_EVT'
steps:
- name: Setup Python
uses: actions/setup-python@v4
with:
python-version: '3.x'
- name: Checkout code
uses: actions/checkout@v4
@ -76,8 +76,10 @@ jobs:
- name: pre-install
run: bash ci/actions_install.sh
- name: Install Libraries for building examples
run: arduino-cli lib install "Adafruit SPIFlash" "MIDI Library" "Adafruit seesaw Library" "Adafruit NeoPixel" "SdFat - Adafruit Fork" "SD" "Adafruit Circuit Playground" "Adafruit InternalFlash" "Pico PIO USB"
- name: Install Libraries
run: |
arduino-cli lib install ${{ env.ARDUINO_LIBS }}
arduino-cli lib list
- name: test platforms
run: python3 ci/build_platform.py ${{ matrix.arduino-platform }}

View file

@ -15,15 +15,18 @@ Supported device class drivers are:
- Human Interface Device (HID): Generic (In & Out), Keyboard, Mouse, Gamepad etc ...
- Mass Storage Class (MSC): with multiple LUNs
- Musical Instrument Digital Interface (MIDI)
- Video (UVC): work in progress
- WebUSB with vendor specific class
### Host Stack
Host support is still work-in-progress but currently available with rp2040 core thanks to [Pico-PIO-USB](https://github.com/sekigon-gonnoc/Pico-PIO-USB). Supported class driver are:
Host stack is available with either addition of MAX3421E hardware (e.g [Host FeatherWing](https://www.adafruit.com/product/5858)) or rp2040 core (thanks to [Pico-PIO-USB](https://github.com/sekigon-gonnoc/Pico-PIO-USB)). Supported class driver are:
- Communication (CDC)
- Communication (CDC): including vendor usb2uart such as FTDI, CP210x, CH34x
- MassStorage class
Note: Host stack is still work-in-progress
## Supported Cores
There are 2 type of supported cores: with and without built-in support for TinyUSB. Built-in support provide seamless integration but requires extra code added to core's source code. Unfortunately it is not always easy or possible to make those modification.
@ -35,9 +38,12 @@ Following core has TinyUSB as either the primary usb stack or selectable via men
- [adafruit/Adafruit_nRF52_Arduino](https://github.com/adafruit/Adafruit_nRF52_Arduino)
- [adafruit/ArduinoCore-samd](https://github.com/adafruit/ArduinoCore-samd)
- [earlephilhower/arduino-pico](https://github.com/earlephilhower/arduino-pico)
- [espressif/arduino-esp32](https://github.com/espressif/arduino-esp32)
- [espressif/arduino-esp32](https://github.com/espressif/arduino-esp32) Host mode using MAX3421E controller should work with all chips. Device mode only support S2/S3/P4 and additional Tools menu are needed
- `USB Mode=USB-OTG (TinyUSB)` for S3 and P4
- `USB CDC On Boot=Enabled`, `USB Firmware MSC On Boot=Disabled`, `USB DFU On Boot=Disabled`
- [openwch/arduino_core_ch32](https://github.com/openwch/arduino_core_ch32)
ESP32 port relies on Espressif's [esp32-hal-tinyusb.c](https://github.com/espressif/arduino-esp32/blob/master/cores/esp32/esp32-hal-tinyusb.c) for building usb descriptors which requires all descriptors must be specified in usb objects declaration i.e constructors. Therefore all descriptor-related fields must be part of object declaration and descriptor-related API have no effect afterwards for this port.
Note: For ESP32 port, version before v3.0 requires all descriptors must be specified in usb objects declaration i.e constructors. Therefore all descriptor-related fields must be part of object declaration and descriptor-related API have no effect afterwards. This limitation is not the case for version from v3.0.
### Cores without built-in support

View file

@ -0,0 +1,8 @@
feather_esp32_v2
feather_esp32s2
feather_esp32s3
funhouse
magtag
metroesp32s2
esp32p4
pico_rp2040_tinyusb_host

View file

@ -25,11 +25,9 @@
#include <Adafruit_TinyUSB.h>
#define LED LED_BUILTIN
// Create 2nd instance of CDC Ports.
#ifdef ARDUINO_ARCH_ESP32
#error "Currnetly multiple CDCs on ESP32-Sx is not yet supported. An PR to update core/esp32/USBCDC and/or pre-built libusb are needed."
#error "Currently multiple CDCs on ESP32 is not yet supported"
// for ESP32, we need to specify instance number when declaring object
Adafruit_USBD_CDC USBSer1(1);
#else
@ -37,13 +35,17 @@
#endif
void setup() {
pinMode(LED, OUTPUT);
#ifdef LED_BUILTIN
pinMode(LED_BUILTIN, OUTPUT);
#endif
Serial.begin(115200);
// check to see if multiple CDCs are enabled
if ( CFG_TUD_CDC < 2 ) {
digitalWrite(LED, HIGH); // LED on for error indicator
#ifdef LED_BUILTIN
digitalWrite(LED_BUILTIN, HIGH); // LED on for error indicator
#endif
while(1) {
Serial.printf("CFG_TUD_CDC must be at least 2, current value is %u\n", CFG_TUD_CDC);
@ -56,6 +58,13 @@ void setup() {
// initialize 2nd CDC interface
USBSer1.begin(115200);
// If already enumerated, additional class driverr begin() e.g msc, hid, midi won't take effect until re-enumeration
if (TinyUSBDevice.mounted()) {
TinyUSBDevice.detach();
delay(10);
TinyUSBDevice.attach();
}
while (!Serial || !USBSer1) {
if (Serial) {
Serial.println("Waiting for other USB ports");
@ -89,7 +98,9 @@ void loop() {
if (delay_without_delaying(500)) {
LEDstate = !LEDstate;
digitalWrite(LED, LEDstate);
#ifdef LED_BUILTIN
digitalWrite(LED_BUILTIN, LEDstate);
#endif
}
}

View file

@ -0,0 +1,2 @@
feather_esp32_v2
pico_rp2040_tinyusb_host

View file

@ -18,19 +18,40 @@
* Note: this will cause device to loose the touch1200 and require
* user manual interaction to put device into bootloader/DFU mode.
*/
void setup() {
// Manual begin() is required on core without built-in support e.g. mbed rp2040
if (!TinyUSBDevice.isInitialized()) {
TinyUSBDevice.begin(0);
}
int led = LED_BUILTIN;
// clear configuration will remove all USB interfaces including CDC (Serial)
TinyUSBDevice.clearConfiguration();
void setup()
{
Serial.end();
pinMode(led, OUTPUT);
// If already enumerated, additional class driverr begin() e.g msc, hid, midi won't take effect until re-enumeration
if (TinyUSBDevice.mounted()) {
TinyUSBDevice.detach();
delay(10);
TinyUSBDevice.attach();
}
#ifdef LED_BUILTIN
pinMode(LED_BUILTIN, OUTPUT);
#endif
}
void loop()
{
digitalWrite(led, HIGH);
delay(1000);
digitalWrite(led, LOW);
delay(1000);
void loop() {
#ifdef TINYUSB_NEED_POLLING_TASK
// Manual call tud_task since it isn't called by Core's background
TinyUSBDevice.task();
#endif
// toggle LED
static uint32_t ms = 0;
static uint8_t led_state = 0;
if (millis() - ms > 1000) {
ms = millis();
#ifdef LED_BUILTIN
digitalWrite(LED_BUILTIN, 1-led_state);
#endif
}
}

View file

@ -0,0 +1,2 @@
feather_esp32_v2
pico_rp2040_tinyusb_host

View file

@ -0,0 +1,41 @@
/*********************************************************************
Adafruit invests time and resources providing this open source code,
please support Adafruit and open-source hardware by purchasing
products from Adafruit!
MIT license, check LICENSE for more information
Copyright (c) 2019 Ha Thach for Adafruit Industries
All text above, and the splash screen below must be included in
any redistribution
*********************************************************************/
#include "Adafruit_TinyUSB.h"
/* This sketch demonstrates USB CDC Serial echo (convert to upper case) using SerialTinyUSB which
* is available for both core with built-in USB support and without.
* Note: on core with built-in support Serial is alias to SerialTinyUSB
*/
void setup() {
// Manual begin() is required on core without built-in support e.g. mbed rp2040
if (!TinyUSBDevice.isInitialized()) {
TinyUSBDevice.begin(0);
}
}
void loop() {
#ifdef TINYUSB_NEED_POLLING_TASK
// Manual call tud_task since it isn't called by Core's background
TinyUSBDevice.task();
#endif
uint8_t buf[64];
uint32_t count = 0;
while (SerialTinyUSB.available()) {
buf[count++] = (uint8_t) toupper(SerialTinyUSB.read());
}
if (count) {
SerialTinyUSB.write(buf, count);
}
}

View file

@ -1,192 +0,0 @@
/*********************************************************************
Adafruit invests time and resources providing this open source code,
please support Adafruit and open-source hardware by purchasing
products from Adafruit!
MIT license, check LICENSE for more information
Copyright (c) 2019 Ha Thach for Adafruit Industries
All text above, and the splash screen below must be included in
any redistribution
*********************************************************************/
/* This sketch demonstrates USB Mass Storage and HID mouse (and CDC)
* - Enumerated as disk using on-board external flash
* - Press button pin will move mouse toward bottom right of monitor
*/
#include "SPI.h"
#include "SdFat.h"
#include "Adafruit_SPIFlash.h"
#include "Adafruit_TinyUSB.h"
//--------------------------------------------------------------------+
// MSC External Flash Config
//--------------------------------------------------------------------+
// Un-comment to run example with custom SPI SPI and SS e.g with FRAM breakout
// #define CUSTOM_CS A5
// #define CUSTOM_SPI SPI
#if defined(CUSTOM_CS) && defined(CUSTOM_SPI)
Adafruit_FlashTransport_SPI flashTransport(CUSTOM_CS, CUSTOM_SPI);
#elif defined(ARDUINO_ARCH_ESP32)
// ESP32 use same flash device that store code.
// Therefore there is no need to specify the SPI and SS
Adafruit_FlashTransport_ESP32 flashTransport;
#elif defined(ARDUINO_ARCH_RP2040)
// RP2040 use same flash device that store code.
// Therefore there is no need to specify the SPI and SS
// Use default (no-args) constructor to be compatible with CircuitPython partition scheme
Adafruit_FlashTransport_RP2040 flashTransport;
// For generic usage:
// Adafruit_FlashTransport_RP2040 flashTransport(start_address, size)
// If start_address and size are both 0, value that match filesystem setting in
// 'Tools->Flash Size' menu selection will be used
#else
// On-board external flash (QSPI or SPI) macros should already
// defined in your board variant if supported
// - EXTERNAL_FLASH_USE_QSPI
// - EXTERNAL_FLASH_USE_CS/EXTERNAL_FLASH_USE_SPI
#if defined(EXTERNAL_FLASH_USE_QSPI)
Adafruit_FlashTransport_QSPI flashTransport;
#elif defined(EXTERNAL_FLASH_USE_SPI)
Adafruit_FlashTransport_SPI flashTransport(EXTERNAL_FLASH_USE_CS, EXTERNAL_FLASH_USE_SPI);
#else
#error No QSPI/SPI flash are defined on your board variant.h !
#endif
#endif
Adafruit_SPIFlash flash(&flashTransport);
Adafruit_USBD_MSC usb_msc;
//--------------------------------------------------------------------+
// HID Config
//--------------------------------------------------------------------+
// HID report descriptor using TinyUSB's template
// Single Report (no ID) descriptor
uint8_t const desc_hid_report[] =
{
TUD_HID_REPORT_DESC_MOUSE()
};
// USB HID object. For ESP32 these values cannot be changed after this declaration
// desc report, desc len, protocol, interval, use out endpoint
Adafruit_USBD_HID usb_hid(desc_hid_report, sizeof(desc_hid_report), HID_ITF_PROTOCOL_NONE, 2, false);
#if defined(ARDUINO_SAMD_CIRCUITPLAYGROUND_EXPRESS) || defined(ARDUINO_NRF52840_CIRCUITPLAY)
const int pin = 4; // Left Button
bool activeState = true;
#elif defined(ARDUINO_FUNHOUSE_ESP32S2)
const int pin = BUTTON_DOWN;
bool activeState = true;
#elif defined PIN_BUTTON1
const int pin = PIN_BUTTON1;
bool activeState = false;
#else
const int pin = 12;
bool activeState = false;
#endif
// the setup function runs once when you press reset or power the board
void setup()
{
flash.begin();
pinMode(LED_BUILTIN, OUTPUT);
// Set disk vendor id, product id and revision with string up to 8, 16, 4 characters respectively
usb_msc.setID("Adafruit", "External Flash", "1.0");
// Set callback
usb_msc.setReadWriteCallback(msc_read_cb, msc_write_cb, msc_flush_cb);
// Set disk size, block size should be 512 regardless of spi flash page size
usb_msc.setCapacity(flash.size()/512, 512);
// MSC is ready for read/write
usb_msc.setUnitReady(true);
usb_msc.begin();
// Set up button
pinMode(pin, activeState ? INPUT_PULLDOWN : INPUT_PULLUP);
// Notes: following commented-out functions has no affect on ESP32
// usb_hid.setReportDescriptor(desc_hid_report, sizeof(desc_hid_report));
usb_hid.begin();
Serial.begin(115200);
//while ( !Serial ) delay(10); // wait for native usb
Serial.println("Adafruit TinyUSB Mouse + Mass Storage (external flash) example");
}
void loop()
{
// poll gpio once each 10 ms
delay(10);
// button is active low
uint32_t const btn = (digitalRead(pin) == activeState);
// Remote wakeup
if ( TinyUSBDevice.suspended() && btn )
{
// Wake up host if we are in suspend mode
// and REMOTE_WAKEUP feature is enabled by host
tud_remote_wakeup();
}
/*------------- Mouse -------------*/
if ( usb_hid.ready() )
{
if ( btn )
{
int8_t const delta = 5;
usb_hid.mouseMove(0, delta, delta); // no ID: right + down
// delay a bit before attempt to send keyboard report
delay(10);
}
}
}
// Callback invoked when received READ10 command.
// Copy disk's data to buffer (up to bufsize) and
// return number of copied bytes (must be multiple of block size)
int32_t msc_read_cb (uint32_t lba, void* buffer, uint32_t bufsize)
{
// Note: SPIFLash Bock API: readBlocks/writeBlocks/syncBlocks
// already include 4K sector caching internally. We don't need to cache it, yahhhh!!
return flash.readBlocks(lba, (uint8_t*) buffer, bufsize/512) ? bufsize : -1;
}
// Callback invoked when received WRITE10 command.
// Process data in buffer to disk's storage and
// return number of written bytes (must be multiple of block size)
int32_t msc_write_cb (uint32_t lba, uint8_t* buffer, uint32_t bufsize)
{
// Note: SPIFLash Bock API: readBlocks/writeBlocks/syncBlocks
// already include 4K sector caching internally. We don't need to cache it, yahhhh!!
return flash.writeBlocks(lba, buffer, bufsize/512) ? bufsize : -1;
}
// Callback invoked when WRITE10 command is completed (status received and accepted by host).
// used to flush any pending cache.
void msc_flush_cb (void)
{
flash.syncBlocks();
}

View file

@ -0,0 +1,2 @@
feather_esp32_v2
pico_rp2040_tinyusb_host

View file

@ -23,6 +23,7 @@
// 8KB is the smallest size that windows allow to mount
#define DISK_BLOCK_NUM 16
#define DISK_BLOCK_SIZE 512
#include "ramdisk.h"
Adafruit_USBD_MSC usb_msc;
@ -33,43 +34,51 @@ Adafruit_USBD_MSC usb_msc;
// HID report descriptor using TinyUSB's template
// Single Report (no ID) descriptor
uint8_t const desc_hid_report[] =
{
TUD_HID_REPORT_DESC_MOUSE()
uint8_t const desc_hid_report[] = {
TUD_HID_REPORT_DESC_MOUSE()
};
// USB HID object. For ESP32 these values cannot be changed after this declaration
// desc report, desc len, protocol, interval, use out endpoint
Adafruit_USBD_HID usb_hid(desc_hid_report, sizeof(desc_hid_report), HID_ITF_PROTOCOL_NONE, 2, false);
// USB HID object
Adafruit_USBD_HID usb_hid;
#if defined(ARDUINO_SAMD_CIRCUITPLAYGROUND_EXPRESS) || defined(ARDUINO_NRF52840_CIRCUITPLAY)
const int pin = 4; // Left Button
bool activeState = true;
const int pin = 4; // Left Button
bool activeState = true;
#elif defined(ARDUINO_FUNHOUSE_ESP32S2)
const int pin = BUTTON_DOWN;
bool activeState = true;
const int pin = BUTTON_DOWN;
bool activeState = true;
#elif defined PIN_BUTTON1
const int pin = PIN_BUTTON1;
bool activeState = false;
const int pin = PIN_BUTTON1;
bool activeState = false;
#elif defined(ARDUINO_ARCH_ESP32)
const int pin = 0;
bool activeState = false;
#elif defined(ARDUINO_ARCH_RP2040)
const int pin = D0;
bool activeState = false;
#else
const int pin = 12;
bool activeState = false;
const int pin = A0;
bool activeState = false;
#endif
// the setup function runs once when you press reset or power the board
void setup()
{
#if defined(ARDUINO_ARCH_MBED) && defined(ARDUINO_ARCH_RP2040)
// Manual begin() is required on core without built-in support for TinyUSB such as mbed rp2040
TinyUSB_Device_Init(0);
#endif
void setup() {
// Manual begin() is required on core without built-in support e.g. mbed rp2040
if (!TinyUSBDevice.isInitialized()) {
TinyUSBDevice.begin(0);
}
Serial.begin(115200);
// Set disk vendor id, product id and revision with string up to 8, 16, 4 characters respectively
usb_msc.setID("Adafruit", "Mass Storage", "1.0");
// Set disk size
usb_msc.setCapacity(DISK_BLOCK_NUM, DISK_BLOCK_SIZE);
@ -78,44 +87,42 @@ void setup()
// Set Lun ready (RAM disk is always ready)
usb_msc.setUnitReady(true);
usb_msc.begin();
// Set up button
pinMode(pin, activeState ? INPUT_PULLDOWN : INPUT_PULLUP);
// Notes: following commented-out functions has no affect on ESP32
// usb_hid.setReportDescriptor(desc_hid_report, sizeof(desc_hid_report));
// Set up HID
usb_hid.setReportDescriptor(desc_hid_report, sizeof(desc_hid_report));
usb_hid.setBootProtocol(HID_ITF_PROTOCOL_NONE);
usb_hid.setPollInterval(2);
usb_hid.begin();
Serial.begin(115200);
while( !TinyUSBDevice.mounted() ) delay(1); // wait for native usb
// If already enumerated, additional class driverr begin() e.g msc, hid, midi won't take effect until re-enumeration
if (TinyUSBDevice.mounted()) {
TinyUSBDevice.detach();
delay(10);
TinyUSBDevice.attach();
}
Serial.println("Adafruit TinyUSB Mouse + Mass Storage (ramdisk) example");
}
void loop()
{
// poll gpio once each 10 ms
delay(10);
void process_hid() {
// button is active low
uint32_t const btn = (digitalRead(pin) == activeState);
// Remote wakeup
if ( TinyUSBDevice.suspended() && btn )
{
if (TinyUSBDevice.suspended() && btn) {
// Wake up host if we are in suspend mode
// and REMOTE_WAKEUP feature is enabled by host
tud_remote_wakeup();
}
/*------------- Mouse -------------*/
if ( usb_hid.ready() )
{
if ( btn )
{
if (usb_hid.ready()) {
if (btn) {
int8_t const delta = 5;
usb_hid.mouseMove(0, delta, delta); // no ID: right + down
@ -125,11 +132,29 @@ void loop()
}
}
void loop() {
#ifdef TINYUSB_NEED_POLLING_TASK
// Manual call tud_task since it isn't called by Core's background
TinyUSBDevice.task();
#endif
// not enumerated()/mounted() yet: nothing to do
if (!TinyUSBDevice.mounted()) {
return;
}
// poll gpio once each 10 ms
static uint32_t ms = 0;
if (millis() - ms > 10) {
ms = millis();
process_hid();
}
}
// Callback invoked when received READ10 command.
// Copy disk's data to buffer (up to bufsize) and
// return number of copied bytes (must be multiple of block size)
int32_t msc_read_cb (uint32_t lba, void* buffer, uint32_t bufsize)
{
int32_t msc_read_cb(uint32_t lba, void* buffer, uint32_t bufsize) {
uint8_t const* addr = msc_disk[lba];
memcpy(buffer, addr, bufsize);
@ -139,8 +164,7 @@ int32_t msc_read_cb (uint32_t lba, void* buffer, uint32_t bufsize)
// Callback invoked when received WRITE10 command.
// Process data in buffer to disk's storage and
// return number of written bytes (must be multiple of block size)
int32_t msc_write_cb (uint32_t lba, uint8_t* buffer, uint32_t bufsize)
{
int32_t msc_write_cb(uint32_t lba, uint8_t* buffer, uint32_t bufsize) {
uint8_t* addr = msc_disk[lba];
memcpy(addr, buffer, bufsize);
@ -149,7 +173,6 @@ int32_t msc_write_cb (uint32_t lba, uint8_t* buffer, uint32_t bufsize)
// Callback invoked when WRITE10 command is completed (status received and accepted by host).
// used to flush any pending cache.
void msc_flush_cb (void)
{
void msc_flush_cb(void) {
// nothing to do
}

View file

@ -0,0 +1,2 @@
pico_rp2040_tinyusb_host
CH32V20x_EVT

View file

@ -40,7 +40,7 @@
#if defined(ARDUINO_METRO_ESP32S2)
Adafruit_USBH_Host USBHost(&SPI, 15, 14);
#elif defined(ARDUINO_ADAFRUIT_FEATHER_ESP32_V2)
Adafruit_USBH_Host USBHost(&SPI, 27, 33);
Adafruit_USBH_Host USBHost(&SPI, 33, 15);
#else
// Default CS and INT are pin 10, 9
Adafruit_USBH_Host USBHost(&SPI, 10, 9);
@ -59,14 +59,14 @@ static void rp2040_configure_pio_usb(void) {
//while ( !Serial ) delay(10); // wait for native usb
Serial.println("Core1 setup to run TinyUSB host with pio-usb");
// Check for CPU frequency, must be multiple of 120Mhz for bit-banging USB
// Check for CPU frequency, must be multiple of 12 Mhz for bit-banging USB
uint32_t cpu_hz = clock_get_hz(clk_sys);
if (cpu_hz != 120000000UL && cpu_hz != 240000000UL) {
if (cpu_hz % 12000000UL) {
while (!Serial) {
delay(10); // wait for native usb
}
Serial.printf("Error: CPU Clock = %lu, PIO USB require CPU clock must be multiple of 120 Mhz\r\n", cpu_hz);
Serial.printf("Change your CPU Clock to either 120 or 240 Mhz in Menu->CPU Speed \r\n");
Serial.printf("Error: CPU Clock = %lu, PIO USB require CPU clock must be multiple of 12 Mhz\r\n", cpu_hz);
Serial.printf("Change your CPU Clock to 12*n Mhz in Menu->CPU Speed \r\n");
while (1) {
delay(1);
}

View file

@ -0,0 +1,2 @@
pico_rp2040_tinyusb_host
CH32V20x_EVT

View file

@ -40,7 +40,7 @@
#if defined(ARDUINO_METRO_ESP32S2)
Adafruit_USBH_Host USBHost(&SPI, 15, 14);
#elif defined(ARDUINO_ADAFRUIT_FEATHER_ESP32_V2)
Adafruit_USBH_Host USBHost(&SPI, 27, 33);
Adafruit_USBH_Host USBHost(&SPI, 33, 15);
#else
// Default CS and INT are pin 10, 9
Adafruit_USBH_Host USBHost(&SPI, 10, 9);
@ -59,14 +59,14 @@ static void rp2040_configure_pio_usb(void) {
//while ( !Serial ) delay(10); // wait for native usb
Serial.println("Core1 setup to run TinyUSB host with pio-usb");
// Check for CPU frequency, must be multiple of 120Mhz for bit-banging USB
// Check for CPU frequency, must be multiple of 12 Mhz for bit-banging USB
uint32_t cpu_hz = clock_get_hz(clk_sys);
if (cpu_hz != 120000000UL && cpu_hz != 240000000UL) {
if (cpu_hz % 12000000UL) {
while (!Serial) {
delay(10); // wait for native usb
}
Serial.printf("Error: CPU Clock = %lu, PIO USB require CPU clock must be multiple of 120 Mhz\r\n", cpu_hz);
Serial.printf("Change your CPU Clock to either 120 or 240 Mhz in Menu->CPU Speed \r\n");
Serial.printf("Error: CPU Clock = %lu, PIO USB require CPU clock must be multiple of 12 Mhz\r\n", cpu_hz);
Serial.printf("Change your CPU Clock to 12*n Mhz in Menu->CPU Speed \r\n");
while (1) {
delay(1);
}

View file

@ -0,0 +1,3 @@
feather_esp32_v2
pico_rp2040_tinyusb_host
CH32V20x_EVT

View file

@ -42,8 +42,7 @@ uint8_t const desc_hid_report[] = {
TUD_HID_REPORT_DESC_MOUSE()
};
// USB HID object. For ESP32 these values cannot be changed after this declaration
// desc report, desc len, protocol, interval, use out endpoint
// USB HID object: desc report, desc len, protocol, interval, use out endpoint
Adafruit_USBD_HID usb_hid(desc_hid_report, sizeof(desc_hid_report), HID_ITF_PROTOCOL_MOUSE, 2, false);
/* Adjustable parameters for the log_filter() method.

View file

@ -40,7 +40,7 @@
#if defined(ARDUINO_METRO_ESP32S2)
Adafruit_USBH_Host USBHost(&SPI, 15, 14);
#elif defined(ARDUINO_ADAFRUIT_FEATHER_ESP32_V2)
Adafruit_USBH_Host USBHost(&SPI, 27, 33);
Adafruit_USBH_Host USBHost(&SPI, 33, 15);
#else
// Default CS and INT are pin 10, 9
Adafruit_USBH_Host USBHost(&SPI, 10, 9);
@ -59,14 +59,14 @@ static void rp2040_configure_pio_usb(void) {
//while ( !Serial ) delay(10); // wait for native usb
Serial.println("Core1 setup to run TinyUSB host with pio-usb");
// Check for CPU frequency, must be multiple of 120Mhz for bit-banging USB
// Check for CPU frequency, must be multiple of 12 Mhz for bit-banging USB
uint32_t cpu_hz = clock_get_hz(clk_sys);
if (cpu_hz != 120000000UL && cpu_hz != 240000000UL) {
if (cpu_hz % 12000000UL) {
while (!Serial) {
delay(10); // wait for native usb
}
Serial.printf("Error: CPU Clock = %lu, PIO USB require CPU clock must be multiple of 120 Mhz\r\n", cpu_hz);
Serial.printf("Change your CPU Clock to either 120 or 240 Mhz in Menu->CPU Speed \r\n");
Serial.printf("Error: CPU Clock = %lu, PIO USB require CPU clock must be multiple of 12 Mhz\r\n", cpu_hz);
Serial.printf("Change your CPU Clock to 12*n Mhz in Menu->CPU Speed \r\n");
while (1) {
delay(1);
}

View file

@ -0,0 +1,3 @@
feather_esp32_v2
pico_rp2040_tinyusb_host
CH32V20x_EVT

View file

@ -40,8 +40,7 @@ uint8_t const desc_hid_report[] = {
TUD_HID_REPORT_DESC_MOUSE()
};
// USB HID object. For ESP32 these values cannot be changed after this declaration
// desc report, desc len, protocol, interval, use out endpoint
// USB HID object: desc report, desc len, protocol, interval, use out endpoint
Adafruit_USBD_HID usb_hid(desc_hid_report, sizeof(desc_hid_report), HID_ITF_PROTOCOL_MOUSE, 2, false);
//------------- Low pass filter with Butterworth -------------//

View file

@ -40,7 +40,7 @@
#if defined(ARDUINO_METRO_ESP32S2)
Adafruit_USBH_Host USBHost(&SPI, 15, 14);
#elif defined(ARDUINO_ADAFRUIT_FEATHER_ESP32_V2)
Adafruit_USBH_Host USBHost(&SPI, 27, 33);
Adafruit_USBH_Host USBHost(&SPI, 33, 15);
#else
// Default CS and INT are pin 10, 9
Adafruit_USBH_Host USBHost(&SPI, 10, 9);
@ -59,14 +59,14 @@ static void rp2040_configure_pio_usb(void) {
//while ( !Serial ) delay(10); // wait for native usb
Serial.println("Core1 setup to run TinyUSB host with pio-usb");
// Check for CPU frequency, must be multiple of 120Mhz for bit-banging USB
// Check for CPU frequency, must be multiple of 12 Mhz for bit-banging USB
uint32_t cpu_hz = clock_get_hz(clk_sys);
if (cpu_hz != 120000000UL && cpu_hz != 240000000UL) {
if (cpu_hz % 12000000UL) {
while (!Serial) {
delay(10); // wait for native usb
}
Serial.printf("Error: CPU Clock = %lu, PIO USB require CPU clock must be multiple of 120 Mhz\r\n", cpu_hz);
Serial.printf("Change your CPU Clock to either 120 or 240 Mhz in Menu->CPU Speed \r\n");
Serial.printf("Error: CPU Clock = %lu, PIO USB require CPU clock must be multiple of 12 Mhz\r\n", cpu_hz);
Serial.printf("Change your CPU Clock to 12*n Mhz in Menu->CPU Speed \r\n");
while (1) {
delay(1);
}

View file

@ -0,0 +1,3 @@
feather_esp32_v2
pico_rp2040_tinyusb_host
CH32V20x_EVT

View file

@ -42,11 +42,9 @@ uint8_t const desc_hid_report[] = {
TUD_HID_REPORT_DESC_KEYBOARD()
};
// USB HID object. For ESP32 these values cannot be changed after this declaration
// desc report, desc len, protocol, interval, use out endpoint
// USB HID object: desc report, desc len, protocol, interval, use out endpoint
Adafruit_USBD_HID usb_hid(desc_hid_report, sizeof(desc_hid_report), HID_ITF_PROTOCOL_KEYBOARD, 2, false);
void setup() {
Serial.begin(115200);
usb_hid.begin();

View file

@ -40,7 +40,7 @@
#if defined(ARDUINO_METRO_ESP32S2)
Adafruit_USBH_Host USBHost(&SPI, 15, 14);
#elif defined(ARDUINO_ADAFRUIT_FEATHER_ESP32_V2)
Adafruit_USBH_Host USBHost(&SPI, 27, 33);
Adafruit_USBH_Host USBHost(&SPI, 33, 15);
#else
// Default CS and INT are pin 10, 9
Adafruit_USBH_Host USBHost(&SPI, 10, 9);
@ -59,14 +59,14 @@ static void rp2040_configure_pio_usb(void) {
//while ( !Serial ) delay(10); // wait for native usb
Serial.println("Core1 setup to run TinyUSB host with pio-usb");
// Check for CPU frequency, must be multiple of 120Mhz for bit-banging USB
// Check for CPU frequency, must be multiple of 12 Mhz for bit-banging USB
uint32_t cpu_hz = clock_get_hz(clk_sys);
if (cpu_hz != 120000000UL && cpu_hz != 240000000UL) {
if (cpu_hz % 12000000UL) {
while (!Serial) {
delay(10); // wait for native usb
}
Serial.printf("Error: CPU Clock = %lu, PIO USB require CPU clock must be multiple of 120 Mhz\r\n", cpu_hz);
Serial.printf("Change your CPU Clock to either 120 or 240 Mhz in Menu->CPU Speed \r\n");
Serial.printf("Error: CPU Clock = %lu, PIO USB require CPU clock must be multiple of 12 Mhz\r\n", cpu_hz);
Serial.printf("Change your CPU Clock to 12*n Mhz in Menu->CPU Speed \r\n");
while (1) {
delay(1);
}

View file

@ -0,0 +1,2 @@
pico_rp2040_tinyusb_host
CH32V20x_EVT

View file

@ -38,7 +38,7 @@
#endif
// SdFat is required for using Adafruit_USBH_MSC_SdFatDevice
#include "SdFat.h"
#include "SdFat_Adafruit_Fork.h"
// USBHost is defined in usbh_helper.h
#include "usbh_helper.h"
@ -73,7 +73,9 @@ void data_log(void) {
}
// Turn on LED when start writing
#ifdef LED_BUILTIN
digitalWrite(LED_BUILTIN, HIGH);
#endif
f_log = fatfs.open(LOG_FILE, O_WRITE | O_APPEND | O_CREAT);
@ -112,7 +114,9 @@ void usbhost_rtos_task(void *param) {
void setup() {
Serial.begin(115200);
#ifdef LED_BUILTIN
pinMode(LED_BUILTIN, OUTPUT);
#endif
#if defined(CFG_TUH_MAX3421) && CFG_TUH_MAX3421
// init host stack on controller (rhport) 1
@ -172,10 +176,12 @@ bool write_complete_callback(uint8_t dev_addr, tuh_msc_complete_data_t const *cb
(void) dev_addr;
(void) cb_data;
#ifdef LED_BUILTIN
// turn off LED after write is complete
// Note this only marks the usb transfer is complete, device can take longer to actual
// write data to physical flash
digitalWrite(LED_BUILTIN, LOW);
#endif
return true;
}

View file

@ -40,7 +40,7 @@
#if defined(ARDUINO_METRO_ESP32S2)
Adafruit_USBH_Host USBHost(&SPI, 15, 14);
#elif defined(ARDUINO_ADAFRUIT_FEATHER_ESP32_V2)
Adafruit_USBH_Host USBHost(&SPI, 27, 33);
Adafruit_USBH_Host USBHost(&SPI, 33, 15);
#else
// Default CS and INT are pin 10, 9
Adafruit_USBH_Host USBHost(&SPI, 10, 9);
@ -59,14 +59,14 @@ static void rp2040_configure_pio_usb(void) {
//while ( !Serial ) delay(10); // wait for native usb
Serial.println("Core1 setup to run TinyUSB host with pio-usb");
// Check for CPU frequency, must be multiple of 120Mhz for bit-banging USB
// Check for CPU frequency, must be multiple of 12 Mhz for bit-banging USB
uint32_t cpu_hz = clock_get_hz(clk_sys);
if (cpu_hz != 120000000UL && cpu_hz != 240000000UL) {
if (cpu_hz % 12000000UL) {
while (!Serial) {
delay(10); // wait for native usb
}
Serial.printf("Error: CPU Clock = %lu, PIO USB require CPU clock must be multiple of 120 Mhz\r\n", cpu_hz);
Serial.printf("Change your CPU Clock to either 120 or 240 Mhz in Menu->CPU Speed \r\n");
Serial.printf("Error: CPU Clock = %lu, PIO USB require CPU clock must be multiple of 12 Mhz\r\n", cpu_hz);
Serial.printf("Change your CPU Clock to 12*n Mhz in Menu->CPU Speed \r\n");
while (1) {
delay(1);
}

View file

@ -0,0 +1,2 @@
pico_rp2040_tinyusb_host
CH32V20x_EVT

View file

@ -27,7 +27,7 @@
*/
// SdFat is required for using Adafruit_USBH_MSC_SdFatDevice
#include "SdFat.h"
#include "SdFat_Adafruit_Fork.h"
// USBHost is defined in usbh_helper.h
#include "usbh_helper.h"

View file

@ -40,7 +40,7 @@
#if defined(ARDUINO_METRO_ESP32S2)
Adafruit_USBH_Host USBHost(&SPI, 15, 14);
#elif defined(ARDUINO_ADAFRUIT_FEATHER_ESP32_V2)
Adafruit_USBH_Host USBHost(&SPI, 27, 33);
Adafruit_USBH_Host USBHost(&SPI, 33, 15);
#else
// Default CS and INT are pin 10, 9
Adafruit_USBH_Host USBHost(&SPI, 10, 9);
@ -59,14 +59,14 @@ static void rp2040_configure_pio_usb(void) {
//while ( !Serial ) delay(10); // wait for native usb
Serial.println("Core1 setup to run TinyUSB host with pio-usb");
// Check for CPU frequency, must be multiple of 120Mhz for bit-banging USB
// Check for CPU frequency, must be multiple of 12 Mhz for bit-banging USB
uint32_t cpu_hz = clock_get_hz(clk_sys);
if (cpu_hz != 120000000UL && cpu_hz != 240000000UL) {
if (cpu_hz % 12000000UL) {
while (!Serial) {
delay(10); // wait for native usb
}
Serial.printf("Error: CPU Clock = %lu, PIO USB require CPU clock must be multiple of 120 Mhz\r\n", cpu_hz);
Serial.printf("Change your CPU Clock to either 120 or 240 Mhz in Menu->CPU Speed \r\n");
Serial.printf("Error: CPU Clock = %lu, PIO USB require CPU clock must be multiple of 12 Mhz\r\n", cpu_hz);
Serial.printf("Change your CPU Clock to 12*n Mhz in Menu->CPU Speed \r\n");
while (1) {
delay(1);
}

View file

@ -0,0 +1 @@
CH32V20x_EVT

View file

@ -40,7 +40,7 @@
#if defined(ARDUINO_METRO_ESP32S2)
Adafruit_USBH_Host USBHost(&SPI, 15, 14);
#elif defined(ARDUINO_ADAFRUIT_FEATHER_ESP32_V2)
Adafruit_USBH_Host USBHost(&SPI, 27, 33);
Adafruit_USBH_Host USBHost(&SPI, 33, 15);
#else
// Default CS and INT are pin 10, 9
Adafruit_USBH_Host USBHost(&SPI, 10, 9);
@ -59,14 +59,14 @@ static void rp2040_configure_pio_usb(void) {
//while ( !Serial ) delay(10); // wait for native usb
Serial.println("Core1 setup to run TinyUSB host with pio-usb");
// Check for CPU frequency, must be multiple of 120Mhz for bit-banging USB
// Check for CPU frequency, must be multiple of 12 Mhz for bit-banging USB
uint32_t cpu_hz = clock_get_hz(clk_sys);
if (cpu_hz != 120000000UL && cpu_hz != 240000000UL) {
if (cpu_hz % 12000000UL) {
while (!Serial) {
delay(10); // wait for native usb
}
Serial.printf("Error: CPU Clock = %lu, PIO USB require CPU clock must be multiple of 120 Mhz\r\n", cpu_hz);
Serial.printf("Change your CPU Clock to either 120 or 240 Mhz in Menu->CPU Speed \r\n");
Serial.printf("Error: CPU Clock = %lu, PIO USB require CPU clock must be multiple of 12 Mhz\r\n", cpu_hz);
Serial.printf("Change your CPU Clock to 12*n Mhz in Menu->CPU Speed \r\n");
while (1) {
delay(1);
}

View file

@ -0,0 +1,2 @@
pico_rp2040_tinyusb_host
CH32V20x_EVT

View file

@ -0,0 +1,241 @@
/*********************************************************************
Adafruit invests time and resources providing this open source code,
please support Adafruit and open-source hardware by purchasing
products from Adafruit!
MIT license, check LICENSE for more information
Copyright (c) 2019 Ha Thach for Adafruit Industries
All text above, and the splash screen below must be included in
any redistribution
*********************************************************************/
/* This example demonstrates use of both device and host, where
* - Device run on native usb controller (roothub port0)
* - Host run on MAX3421E controller (roothub port1) tested with:
* - SAMD21, SAMD51, nRF52840, ESP32S2, ESP32S3, ESP32
* - RP2040: "pio_usb.h" must not be included, otherwise pio-usb will be used as host controller
*
* Requirements:
* - SPI instance, CS pin, INT pin are correctly configured
*/
/* Host example will get device descriptors of attached devices and print it out:
* Device 1: ID 046d:c52f
Device Descriptor:
bLength 18
bDescriptorType 1
bcdUSB 0200
bDeviceClass 0
bDeviceSubClass 0
bDeviceProtocol 0
bMaxPacketSize0 8
idVendor 0x046d
idProduct 0xc52f
bcdDevice 2200
iManufacturer 1 Logitech
iProduct 2 USB Receiver
iSerialNumber 0
bNumConfigurations 1
*
*/
#include "Adafruit_TinyUSB.h"
#include "SPI.h"
// USB Host using MAX3421E: SPI, CS, INT
#if defined(ARDUINO_METRO_ESP32S2)
Adafruit_USBH_Host USBHost(&SPI, 15, 14);
#elif defined(ARDUINO_ADAFRUIT_FEATHER_ESP32_V2)
Adafruit_USBH_Host USBHost(&SPI, 33, 15);
#elif defined(ARDUINO_ADAFRUIT_FEATHER_ESP32C6)
Adafruit_USBH_Host USBHost(&SPI, 8, 7);
#elif defined(ARDUINO_ESP32C3_DEV)
Adafruit_USBH_Host USBHost(&SPI, 10, 7);
#else
// Default CS and INT are pin 10, 9
Adafruit_USBH_Host USBHost(&SPI, 10, 9);
#endif
// Language ID: English
#define LANGUAGE_ID 0x0409
typedef struct {
tusb_desc_device_t desc_device;
uint16_t manufacturer[32];
uint16_t product[48];
uint16_t serial[16];
bool mounted;
} dev_info_t;
// CFG_TUH_DEVICE_MAX is defined by tusb_config header
dev_info_t dev_info[CFG_TUH_DEVICE_MAX] = { 0 };
//--------------------------------------------------------------------+
// setup() & loop()
//--------------------------------------------------------------------+
void setup() {
Serial.begin(115200);
// init host stack on controller (rhport) 1
USBHost.begin(1);
// while ( !Serial ) delay(10); // wait for native usb
Serial.println("TinyUSB Dual: Device Info Example with MAX3421E");
}
void loop() {
USBHost.task();
Serial.flush();
}
//--------------------------------------------------------------------+
// TinyUSB Host callbacks
//--------------------------------------------------------------------+
void print_device_descriptor(tuh_xfer_t *xfer);
void utf16_to_utf8(uint16_t *temp_buf, size_t buf_len);
void print_lsusb(void) {
bool no_device = true;
for (uint8_t daddr = 1; daddr < CFG_TUH_DEVICE_MAX + 1; daddr++) {
// TODO can use tuh_mounted(daddr), but tinyusb has an bug
// use local connected flag instead
dev_info_t *dev = &dev_info[daddr - 1];
if (dev->mounted) {
Serial.printf("Device %u: ID %04x:%04x %s %s\r\n", daddr,
dev->desc_device.idVendor, dev->desc_device.idProduct,
(char *) dev->manufacturer, (char *) dev->product);
no_device = false;
}
}
if (no_device) {
Serial.println("No device connected (except hub)");
}
}
// Invoked when device is mounted (configured)
void tuh_mount_cb(uint8_t daddr) {
Serial.printf("Device attached, address = %d\r\n", daddr);
dev_info_t *dev = &dev_info[daddr - 1];
dev->mounted = true;
// Get Device Descriptor
tuh_descriptor_get_device(daddr, &dev->desc_device, 18, print_device_descriptor, 0);
}
/// Invoked when device is unmounted (bus reset/unplugged)
void tuh_umount_cb(uint8_t daddr) {
Serial.printf("Device removed, address = %d\r\n", daddr);
dev_info_t *dev = &dev_info[daddr - 1];
dev->mounted = false;
// print device summary
print_lsusb();
}
void print_device_descriptor(tuh_xfer_t *xfer) {
if (XFER_RESULT_SUCCESS != xfer->result) {
Serial.printf("Failed to get device descriptor\r\n");
return;
}
uint8_t const daddr = xfer->daddr;
dev_info_t *dev = &dev_info[daddr - 1];
tusb_desc_device_t *desc = &dev->desc_device;
Serial.printf("Device %u: ID %04x:%04x\r\n", daddr, desc->idVendor, desc->idProduct);
Serial.printf("Device Descriptor:\r\n");
Serial.printf(" bLength %u\r\n" , desc->bLength);
Serial.printf(" bDescriptorType %u\r\n" , desc->bDescriptorType);
Serial.printf(" bcdUSB %04x\r\n" , desc->bcdUSB);
Serial.printf(" bDeviceClass %u\r\n" , desc->bDeviceClass);
Serial.printf(" bDeviceSubClass %u\r\n" , desc->bDeviceSubClass);
Serial.printf(" bDeviceProtocol %u\r\n" , desc->bDeviceProtocol);
Serial.printf(" bMaxPacketSize0 %u\r\n" , desc->bMaxPacketSize0);
Serial.printf(" idVendor 0x%04x\r\n" , desc->idVendor);
Serial.printf(" idProduct 0x%04x\r\n" , desc->idProduct);
Serial.printf(" bcdDevice %04x\r\n" , desc->bcdDevice);
// Get String descriptor using Sync API
Serial.printf(" iManufacturer %u ", desc->iManufacturer);
if (XFER_RESULT_SUCCESS ==
tuh_descriptor_get_manufacturer_string_sync(daddr, LANGUAGE_ID, dev->manufacturer, sizeof(dev->manufacturer))) {
utf16_to_utf8(dev->manufacturer, sizeof(dev->manufacturer));
Serial.printf((char *) dev->manufacturer);
}
Serial.printf("\r\n");
Serial.printf(" iProduct %u ", desc->iProduct);
if (XFER_RESULT_SUCCESS ==
tuh_descriptor_get_product_string_sync(daddr, LANGUAGE_ID, dev->product, sizeof(dev->product))) {
utf16_to_utf8(dev->product, sizeof(dev->product));
Serial.printf((char *) dev->product);
}
Serial.printf("\r\n");
Serial.printf(" iSerialNumber %u ", desc->iSerialNumber);
if (XFER_RESULT_SUCCESS ==
tuh_descriptor_get_serial_string_sync(daddr, LANGUAGE_ID, dev->serial, sizeof(dev->serial))) {
utf16_to_utf8(dev->serial, sizeof(dev->serial));
Serial.printf((char *) dev->serial);
}
Serial.printf("\r\n");
Serial.printf(" bNumConfigurations %u\r\n", desc->bNumConfigurations);
// print device summary
print_lsusb();
}
//--------------------------------------------------------------------+
// String Descriptor Helper
//--------------------------------------------------------------------+
static void _convert_utf16le_to_utf8(const uint16_t *utf16, size_t utf16_len, uint8_t *utf8, size_t utf8_len) {
// TODO: Check for runover.
(void) utf8_len;
// Get the UTF-16 length out of the data itself.
for (size_t i = 0; i < utf16_len; i++) {
uint16_t chr = utf16[i];
if (chr < 0x80) {
*utf8++ = chr & 0xff;
} else if (chr < 0x800) {
*utf8++ = (uint8_t) (0xC0 | (chr >> 6 & 0x1F));
*utf8++ = (uint8_t) (0x80 | (chr >> 0 & 0x3F));
} else {
// TODO: Verify surrogate.
*utf8++ = (uint8_t) (0xE0 | (chr >> 12 & 0x0F));
*utf8++ = (uint8_t) (0x80 | (chr >> 6 & 0x3F));
*utf8++ = (uint8_t) (0x80 | (chr >> 0 & 0x3F));
}
// TODO: Handle UTF-16 code points that take two entries.
}
}
// Count how many bytes a utf-16-le encoded string will take in utf-8.
static int _count_utf8_bytes(const uint16_t *buf, size_t len) {
size_t total_bytes = 0;
for (size_t i = 0; i < len; i++) {
uint16_t chr = buf[i];
if (chr < 0x80) {
total_bytes += 1;
} else if (chr < 0x800) {
total_bytes += 2;
} else {
total_bytes += 3;
}
// TODO: Handle UTF-16 code points that take two entries.
}
return total_bytes;
}
void utf16_to_utf8(uint16_t *temp_buf, size_t buf_len) {
size_t utf16_len = ((temp_buf[0] & 0xff) - 2) / sizeof(uint16_t);
size_t utf8_len = _count_utf8_bytes(temp_buf + 1, utf16_len);
_convert_utf16le_to_utf8(temp_buf + 1, utf16_len, (uint8_t *) temp_buf, buf_len);
((uint8_t *) temp_buf)[utf8_len] = '\0';
}

View file

@ -0,0 +1,2 @@
feather_esp32_v2
pico_rp2040_tinyusb_host

View file

@ -10,93 +10,73 @@
*********************************************************************/
#include "Adafruit_TinyUSB.h"
#include <Adafruit_NeoPixel.h>
/* This sketch demonstrates USB HID keyboard.
* - PIN A0-A5 is used to send digit '0' to '5' respectively
* - PIN A0-A3 is used to send digit '0' to '3' respectively
* (On the RP2040, pins D0-D5 used)
* - LED and/or Neopixels will be used as Capslock indicator
*/
// HID report descriptor using TinyUSB's template
// Single Report (no ID) descriptor
uint8_t const desc_hid_report[] =
{
TUD_HID_REPORT_DESC_KEYBOARD()
uint8_t const desc_hid_report[] = {
TUD_HID_REPORT_DESC_KEYBOARD()
};
// USB HID object. For ESP32 these values cannot be changed after this declaration
// desc report, desc len, protocol, interval, use out endpoint
Adafruit_USBD_HID usb_hid(desc_hid_report, sizeof(desc_hid_report), HID_ITF_PROTOCOL_KEYBOARD, 2, false);
Adafruit_USBD_HID usb_hid;
//------------- Input Pins -------------//
// Array of pins and its keycode.
// Notes: these pins can be replaced by PIN_BUTTONn if defined in setup()
#ifdef ARDUINO_ARCH_RP2040
uint8_t pins[] = { D0, D1, D2, D3 };
uint8_t pins[] = { D0, D1, D2, D3 };
#else
uint8_t pins[] = { A0, A1, A2, A3 };
uint8_t pins[] = {A0, A1, A2, A3};
#endif
// number of pins
uint8_t pincount = sizeof(pins)/sizeof(pins[0]);
uint8_t pincount = sizeof(pins) / sizeof(pins[0]);
// For keycode definition check out https://github.com/hathach/tinyusb/blob/master/src/class/hid/hid.h
uint8_t hidcode[] = { HID_KEY_ARROW_RIGHT, HID_KEY_ARROW_LEFT, HID_KEY_ARROW_DOWN, HID_KEY_ARROW_UP };
uint8_t hidcode[] = {HID_KEY_0, HID_KEY_1, HID_KEY_2, HID_KEY_3};
#if defined(ARDUINO_SAMD_CIRCUITPLAYGROUND_EXPRESS) || defined(ARDUINO_NRF52840_CIRCUITPLAY) || defined(ARDUINO_FUNHOUSE_ESP32S2)
bool activeState = true;
bool activeState = true;
#else
bool activeState = false;
bool activeState = false;
#endif
//------------- Neopixel -------------//
// #define PIN_NEOPIXEL 8
#ifdef PIN_NEOPIXEL
// How many NeoPixels are attached to the Arduino?
// use on-board defined NEOPIXEL_NUM if existed
#ifndef NEOPIXEL_NUM
#define NEOPIXEL_NUM 10
#endif
Adafruit_NeoPixel pixels = Adafruit_NeoPixel(NEOPIXEL_NUM, PIN_NEOPIXEL, NEO_GRB + NEO_KHZ800);
#endif
// the setup function runs once when you press reset or power the board
void setup()
{
#if defined(ARDUINO_ARCH_MBED) && defined(ARDUINO_ARCH_RP2040)
// Manual begin() is required on core without built-in support for TinyUSB such as mbed rp2040
TinyUSB_Device_Init(0);
#endif
void setup() {
// Manual begin() is required on core without built-in support e.g. mbed rp2040
if (!TinyUSBDevice.isInitialized()) {
TinyUSBDevice.begin(0);
}
// Notes: following commented-out functions has no affect on ESP32
// usb_hid.setBootProtocol(HID_ITF_PROTOCOL_KEYBOARD);
// usb_hid.setPollInterval(2);
// usb_hid.setReportDescriptor(desc_hid_report, sizeof(desc_hid_report));
// usb_hid.setStringDescriptor("TinyUSB Keyboard");
// Setup HID
usb_hid.setBootProtocol(HID_ITF_PROTOCOL_KEYBOARD);
usb_hid.setPollInterval(2);
usb_hid.setReportDescriptor(desc_hid_report, sizeof(desc_hid_report));
usb_hid.setStringDescriptor("TinyUSB Keyboard");
// Set up output report (on control endpoint) for Capslock indicator
usb_hid.setReportCallback(NULL, hid_report_callback);
usb_hid.begin();
// If already enumerated, additional class driverr begin() e.g msc, hid, midi won't take effect until re-enumeration
if (TinyUSBDevice.mounted()) {
TinyUSBDevice.detach();
delay(10);
TinyUSBDevice.attach();
}
// led pin
#ifdef LED_BUILTIN
pinMode(LED_BUILTIN, OUTPUT);
digitalWrite(LED_BUILTIN, LOW);
// neopixel if existed
#ifdef PIN_NEOPIXEL
pixels.begin();
pixels.setBrightness(50);
#ifdef NEOPIXEL_POWER
pinMode(NEOPIXEL_POWER, OUTPUT);
digitalWrite(NEOPIXEL_POWER, NEOPIXEL_POWER_ON);
#endif
#endif
// overwrite input pin with PIN_BUTTONx
@ -117,32 +97,21 @@ void setup()
#endif
// Set up pin as input
for (uint8_t i=0; i<pincount; i++)
{
for (uint8_t i = 0; i < pincount; i++) {
pinMode(pins[i], activeState ? INPUT_PULLDOWN : INPUT_PULLUP);
}
// wait until device mounted
while( !TinyUSBDevice.mounted() ) delay(1);
}
void loop()
{
// poll gpio once each 2 ms
delay(2);
void process_hid() {
// used to avoid send multiple consecutive zero report for keyboard
static bool keyPressedPreviously = false;
uint8_t count=0;
uint8_t keycode[6] = { 0 };
uint8_t count = 0;
uint8_t keycode[6] = {0};
// scan normal key and send report
for(uint8_t i=0; i < pincount; i++)
{
if ( activeState == digitalRead(pins[i]) )
{
for (uint8_t i = 0; i < pincount; i++) {
if (activeState == digitalRead(pins[i])) {
// if pin is active (low), add its hid code to key report
keycode[count++] = hidcode[i];
@ -151,55 +120,66 @@ void loop()
}
}
if ( TinyUSBDevice.suspended() && count )
{
if (TinyUSBDevice.suspended() && count) {
// Wake up host if we are in suspend mode
// and REMOTE_WAKEUP feature is enabled by host
TinyUSBDevice.remoteWakeup();
}
// skip if hid is not ready e.g still transferring previous report
if ( !usb_hid.ready() ) return;
if (!usb_hid.ready()) return;
if ( count )
{
if (count) {
// Send report if there is key pressed
uint8_t const report_id = 0;
uint8_t const modifier = 0;
keyPressedPreviously = true;
usb_hid.keyboardReport(report_id, modifier, keycode);
}else
{
} else {
// Send All-zero report to indicate there is no keys pressed
// Most of the time, it is, though we don't need to send zero report
// every loop(), only a key is pressed in previous loop()
if ( keyPressedPreviously )
{
if (keyPressedPreviously) {
keyPressedPreviously = false;
usb_hid.keyboardRelease(0);
}
}
}
void loop() {
#ifdef TINYUSB_NEED_POLLING_TASK
// Manual call tud_task since it isn't called by Core's background
TinyUSBDevice.task();
#endif
// not enumerated()/mounted() yet: nothing to do
if (!TinyUSBDevice.mounted()) {
return;
}
// poll gpio once each 2 ms
static uint32_t ms = 0;
if (millis() - ms > 2) {
ms = millis();
process_hid();
}
}
// Output report callback for LED indicator such as Caplocks
void hid_report_callback(uint8_t report_id, hid_report_type_t report_type, uint8_t const* buffer, uint16_t bufsize)
{
void hid_report_callback(uint8_t report_id, hid_report_type_t report_type, uint8_t const* buffer, uint16_t bufsize) {
(void) report_id;
(void) bufsize;
// LED indicator is output report with only 1 byte length
if ( report_type != HID_REPORT_TYPE_OUTPUT ) return;
if (report_type != HID_REPORT_TYPE_OUTPUT) return;
// The LED bit map is as follows: (also defined by KEYBOARD_LED_* )
// Kana (4) | Compose (3) | ScrollLock (2) | CapsLock (1) | Numlock (0)
uint8_t ledIndicator = buffer[0];
#ifdef LED_BUILTIN
// turn on LED if capslock is set
digitalWrite(LED_BUILTIN, ledIndicator & KEYBOARD_LED_CAPSLOCK);
#ifdef PIN_NEOPIXEL
pixels.fill(ledIndicator & KEYBOARD_LED_CAPSLOCK ? 0xff0000 : 0x000000);
pixels.show();
#endif
}

View file

@ -0,0 +1,2 @@
feather_esp32_v2
pico_rp2040_tinyusb_host

View file

@ -19,66 +19,69 @@
* and its active state (when pressed) are different
*/
#if defined(ARDUINO_SAMD_CIRCUITPLAYGROUND_EXPRESS) || defined(ARDUINO_NRF52840_CIRCUITPLAY)
const int pin = 4; // Left Button
bool activeState = true;
const int pin = 4; // Left Button
bool activeState = true;
#elif defined(ARDUINO_FUNHOUSE_ESP32S2)
const int pin = BUTTON_DOWN;
bool activeState = true;
const int pin = BUTTON_DOWN;
bool activeState = true;
#elif defined PIN_BUTTON1
const int pin = PIN_BUTTON1;
bool activeState = false;
const int pin = PIN_BUTTON1;
bool activeState = false;
#elif defined(ARDUINO_ARCH_ESP32)
const int pin = 0;
bool activeState = false;
#elif defined(ARDUINO_ARCH_RP2040)
const int pin = D0;
bool activeState = false;
#else
const int pin = 12;
bool activeState = false;
const int pin = A0;
bool activeState = false;
#endif
// HID report descriptor using TinyUSB's template
// Single Report (no ID) descriptor
uint8_t const desc_hid_report[] =
{
TUD_HID_REPORT_DESC_MOUSE()
uint8_t const desc_hid_report[] = {
TUD_HID_REPORT_DESC_MOUSE()
};
// USB HID object. For ESP32 these values cannot be changed after this declaration
// desc report, desc len, protocol, interval, use out endpoint
Adafruit_USBD_HID usb_hid(desc_hid_report, sizeof(desc_hid_report), HID_ITF_PROTOCOL_MOUSE, 2, false);
// USB HID object
Adafruit_USBD_HID usb_hid;
// the setup function runs once when you press reset or power the board
void setup()
{
#if defined(ARDUINO_ARCH_MBED) && defined(ARDUINO_ARCH_RP2040)
// Manual begin() is required on core without built-in support for TinyUSB such as mbed rp2040
TinyUSB_Device_Init(0);
#endif
void setup() {
// Manual begin() is required on core without built-in support e.g. mbed rp2040
if (!TinyUSBDevice.isInitialized()) {
TinyUSBDevice.begin(0);
}
Serial.begin(115200);
// Set up button, pullup opposite to active state
pinMode(pin, activeState ? INPUT_PULLDOWN : INPUT_PULLUP);
// Notes: following commented-out functions has no affect on ESP32
// usb_hid.setBootProtocol(HID_ITF_PROTOCOL_MOUSE);
// usb_hid.setPollInterval(2);
// usb_hid.setReportDescriptor(desc_hid_report, sizeof(desc_hid_report));
// usb_hid.setStringDescriptor("TinyUSB Mouse");
// Set up HID
usb_hid.setBootProtocol(HID_ITF_PROTOCOL_MOUSE);
usb_hid.setPollInterval(2);
usb_hid.setReportDescriptor(desc_hid_report, sizeof(desc_hid_report));
usb_hid.setStringDescriptor("TinyUSB Mouse");
usb_hid.begin();
Serial.begin(115200);
// wait until device mounted
while( !TinyUSBDevice.mounted() ) delay(1);
// If already enumerated, additional class driverr begin() e.g msc, hid, midi won't take effect until re-enumeration
if (TinyUSBDevice.mounted()) {
TinyUSBDevice.detach();
delay(10);
TinyUSBDevice.attach();
}
Serial.println("Adafruit TinyUSB HID Mouse example");
}
void loop()
{
// poll gpio once each 10 ms
delay(10);
void process_hid() {
// Whether button is pressed
bool btn_pressed = (digitalRead(pin) == activeState);
@ -86,17 +89,34 @@ void loop()
if (!btn_pressed) return;
// Remote wakeup
if ( TinyUSBDevice.suspended() )
{
if (TinyUSBDevice.suspended()) {
// Wake up host if we are in suspend mode
// and REMOTE_WAKEUP feature is enabled by host
TinyUSBDevice.remoteWakeup();
}
if ( usb_hid.ready() )
{
if (usb_hid.ready()) {
uint8_t const report_id = 0; // no ID
int8_t const delta = 5;
usb_hid.mouseMove(report_id, delta, delta); // right + down
}
}
void loop() {
#ifdef TINYUSB_NEED_POLLING_TASK
// Manual call tud_task since it isn't called by Core's background
TinyUSBDevice.task();
#endif
// not enumerated()/mounted() yet: nothing to do
if (!TinyUSBDevice.mounted()) {
return;
}
// poll gpio once each 10 ms
static uint32_t ms = 0;
if (millis() - ms > 10) {
ms = millis();
process_hid();
}
}

View file

@ -0,0 +1,2 @@
feather_esp32_v2
pico_rp2040_tinyusb_host

View file

@ -20,83 +20,90 @@
* and its active state (when pressed) are different
*/
#if defined(ARDUINO_SAMD_CIRCUITPLAYGROUND_EXPRESS) || defined(ARDUINO_NRF52840_CIRCUITPLAY)
const int pin = 4; // Left Button
bool activeState = true;
const int pin = 4; // Left Button
bool activeState = true;
#elif defined(ARDUINO_FUNHOUSE_ESP32S2)
const int pin = BUTTON_DOWN;
bool activeState = true;
const int pin = BUTTON_DOWN;
bool activeState = true;
#elif defined PIN_BUTTON1
const int pin = PIN_BUTTON1;
bool activeState = false;
const int pin = PIN_BUTTON1;
bool activeState = false;
#elif defined(ARDUINO_ARCH_ESP32)
const int pin = 0;
bool activeState = false;
#elif defined(ARDUINO_ARCH_RP2040)
const int pin = D0;
bool activeState = false;
#else
const int pin = 12;
bool activeState = false;
const int pin = A0;
bool activeState = false;
#endif
// Report ID
enum
{
enum {
RID_KEYBOARD = 1,
RID_MOUSE,
RID_CONSUMER_CONTROL, // Media, volume etc ..
};
// HID report descriptor using TinyUSB's template
uint8_t const desc_hid_report[] =
{
TUD_HID_REPORT_DESC_KEYBOARD( HID_REPORT_ID(RID_KEYBOARD) ),
TUD_HID_REPORT_DESC_MOUSE ( HID_REPORT_ID(RID_MOUSE) ),
TUD_HID_REPORT_DESC_CONSUMER( HID_REPORT_ID(RID_CONSUMER_CONTROL) )
uint8_t const desc_hid_report[] = {
TUD_HID_REPORT_DESC_KEYBOARD(HID_REPORT_ID(RID_KEYBOARD)),
TUD_HID_REPORT_DESC_MOUSE (HID_REPORT_ID(RID_MOUSE)),
TUD_HID_REPORT_DESC_CONSUMER(HID_REPORT_ID(RID_CONSUMER_CONTROL))
};
// USB HID object. For ESP32 these values cannot be changed after this declaration
// desc report, desc len, protocol, interval, use out endpoint
Adafruit_USBD_HID usb_hid(desc_hid_report, sizeof(desc_hid_report), HID_ITF_PROTOCOL_NONE, 2, false);
// USB HID object.
Adafruit_USBD_HID usb_hid;
// the setup function runs once when you press reset or power the board
void setup()
{
// Notes: following commented-out functions has no affect on ESP32
// usb_hid.setPollInterval(2);
// usb_hid.setReportDescriptor();
// usb_hid.setStringDescriptor("TinyUSB HID Composite");
void setup() {
// Manual begin() is required on core without built-in support e.g. mbed rp2040
if (!TinyUSBDevice.isInitialized()) {
TinyUSBDevice.begin(0);
}
Serial.begin(115200);
// Set up HID
usb_hid.setPollInterval(2);
usb_hid.setReportDescriptor(desc_hid_report, sizeof(desc_hid_report));
usb_hid.setStringDescriptor("TinyUSB HID Composite");
usb_hid.begin();
// If already enumerated, additional class driverr begin() e.g msc, hid, midi won't take effect until re-enumeration
if (TinyUSBDevice.mounted()) {
TinyUSBDevice.detach();
delay(10);
TinyUSBDevice.attach();
}
// Set up button, pullup opposite to active state
pinMode(pin, activeState ? INPUT_PULLDOWN : INPUT_PULLUP);
Serial.begin(115200);
// wait until device mounted
while( !TinyUSBDevice.mounted() ) delay(1);
Serial.println("Adafruit TinyUSB HID Composite example");
}
void loop()
{
// poll gpio once each 10 ms
delay(10);
void process_hid() {
// Whether button is pressed
bool btn_pressed = (digitalRead(pin) == activeState);
// Remote wakeup
if ( TinyUSBDevice.suspended() && btn_pressed )
{
if (TinyUSBDevice.suspended() && btn_pressed) {
// Wake up host if we are in suspend mode
// and REMOTE_WAKEUP feature is enabled by host
TinyUSBDevice.remoteWakeup();
}
/*------------- Mouse -------------*/
if ( usb_hid.ready() && btn_pressed )
{
if (usb_hid.ready() && btn_pressed) {
int8_t const delta = 5;
usb_hid.mouseMove(RID_MOUSE, delta, delta); // right + down
@ -105,21 +112,18 @@ void loop()
}
/*------------- Keyboard -------------*/
if ( usb_hid.ready() )
{
if (usb_hid.ready()) {
// use to send key release report
static bool has_key = false;
if ( btn_pressed )
{
uint8_t keycode[6] = { 0 };
if (btn_pressed) {
uint8_t keycode[6] = {0};
keycode[0] = HID_KEY_A;
usb_hid.keyboardReport(RID_KEYBOARD, 0, keycode);
has_key = true;
}else
{
} else {
// send empty key report if previously has key pressed
if (has_key) usb_hid.keyboardRelease(RID_KEYBOARD);
has_key = false;
@ -130,8 +134,7 @@ void loop()
}
/*------------- Consumer Control -------------*/
if ( usb_hid.ready() )
{
if (usb_hid.ready()) {
// Consumer Control is used to control Media playback, Volume, Brightness etc ...
// Consumer report is 2-byte containing the control code of the key
// For list of control check out https://github.com/hathach/tinyusb/blob/master/src/class/hid/hid.h
@ -139,16 +142,33 @@ void loop()
// use to send consumer release report
static bool has_consumer_key = false;
if ( btn_pressed )
{
if (btn_pressed) {
// send volume down (0x00EA)
usb_hid.sendReport16(RID_CONSUMER_CONTROL, HID_USAGE_CONSUMER_VOLUME_DECREMENT);
has_consumer_key = true;
}else
{
} else {
// release the consume key by sending zero (0x0000)
if (has_consumer_key) usb_hid.sendReport16(RID_CONSUMER_CONTROL, 0);
has_consumer_key = false;
}
}
}
void loop() {
#ifdef TINYUSB_NEED_POLLING_TASK
// Manual call tud_task since it isn't called by Core's background
TinyUSBDevice.task();
#endif
// not enumerated()/mounted() yet: nothing to do
if (!TinyUSBDevice.mounted()) {
return;
}
// poll gpio once each 10 ms
static uint32_t ms = 0;
if (millis() - ms > 10) {
ms = millis();
process_hid();
}
}

View file

@ -0,0 +1,3 @@
feather_esp32_v2
pico_rp2040_tinyusb_host
CH32V20x_EVT

View file

@ -33,17 +33,15 @@ uint32_t button_mask = (1 << BUTTON_A) | (1 << BUTTON_B) |
Adafruit_seesaw ss;
// Report ID
enum
{
enum {
RID_KEYBOARD = 1,
RID_MOUSE
};
// HID report descriptor using TinyUSB's template
uint8_t const desc_hid_report[] =
{
TUD_HID_REPORT_DESC_KEYBOARD( HID_REPORT_ID(RID_KEYBOARD) ),
TUD_HID_REPORT_DESC_MOUSE ( HID_REPORT_ID(RID_MOUSE) )
uint8_t const desc_hid_report[] = {
TUD_HID_REPORT_DESC_KEYBOARD(HID_REPORT_ID(RID_KEYBOARD)),
TUD_HID_REPORT_DESC_MOUSE (HID_REPORT_ID(RID_MOUSE))
};
// USB HID object. For ESP32 these values cannot be changed after this declaration
@ -53,20 +51,30 @@ Adafruit_USBD_HID usb_hid(desc_hid_report, sizeof(desc_hid_report), HID_ITF_PROT
int last_x, last_y;
// the setup function runs once when you press reset or power the board
void setup()
{
void setup() {
// Manual begin() is required on core without built-in support e.g. mbed rp2040
if (!TinyUSBDevice.isInitialized()) {
TinyUSBDevice.begin(0);
}
Serial.begin(115200);
// Notes: following commented-out functions has no affect on ESP32
// usb_hid.setPollInterval(2);
// usb_hid.setReportDescriptor(desc_hid_report, sizeof(desc_hid_report));
usb_hid.begin();
Serial.begin(115200);
// If already enumerated, additional class driverr begin() e.g msc, hid, midi won't take effect until re-enumeration
if (TinyUSBDevice.mounted()) {
TinyUSBDevice.detach();
delay(10);
TinyUSBDevice.attach();
}
Serial.println("Adafruit TinyUSB HID Mouse with Joy FeatherWing example");
if(!ss.begin(0x49)){
if (!ss.begin(0x49)) {
Serial.println("ERROR! seesaw not found");
while(1);
while (1) {}
} else {
Serial.println("seesaw started");
Serial.print("version: ");
@ -77,16 +85,9 @@ void setup()
last_y = ss.analogRead(2);
last_x = ss.analogRead(3);
// wait until device mounted
while( !TinyUSBDevice.mounted() ) delay(1);
}
void loop()
{
// poll gpio once each 10 ms
delay(10);
void process_hid() {
// If either analog stick or any buttons is pressed
bool has_action = false;
@ -98,12 +99,10 @@ void loop()
int dx = (x - last_x) / 2;
int dy = (y - last_y) / 2;
if ( (abs(dx) > 3) || (abs(dy) > 3) )
{
if ((abs(dx) > 3) || (abs(dy) > 3)) {
has_action = true;
if ( usb_hid.ready() )
{
if (usb_hid.ready()) {
usb_hid.mouseMove(RID_MOUSE, dx, dy); // no ID: right + down
last_x = x;
@ -114,31 +113,27 @@ void loop()
}
}
/*------------- Keyboard -------------*/
// button is active low, invert read value for convenience
uint32_t buttons = ~ss.digitalReadBulk(button_mask);
if ( usb_hid.ready() )
{
if (usb_hid.ready()) {
// use to prevent sending multiple consecutive zero report
static bool has_key = false;
if ( buttons & button_mask )
{
if (buttons & button_mask) {
has_action = true;
has_key = true;
uint8_t keycode[6] = { 0 };
if ( buttons & (1 << BUTTON_A) ) keycode[0] = HID_KEY_A;
if ( buttons & (1 << BUTTON_B) ) keycode[0] = HID_KEY_B;
if ( buttons & (1 << BUTTON_X) ) keycode[0] = HID_KEY_X;
if ( buttons & (1 << BUTTON_Y) ) keycode[0] = HID_KEY_Y;
uint8_t keycode[6] = {0};
if (buttons & (1 << BUTTON_A)) keycode[0] = HID_KEY_A;
if (buttons & (1 << BUTTON_B)) keycode[0] = HID_KEY_B;
if (buttons & (1 << BUTTON_X)) keycode[0] = HID_KEY_X;
if (buttons & (1 << BUTTON_Y)) keycode[0] = HID_KEY_Y;
usb_hid.keyboardReport(RID_KEYBOARD, 0, keycode);
}else
{
} else {
// send empty key report if previously has key pressed
if (has_key) usb_hid.keyboardRelease(RID_KEYBOARD);
has_key = false;
@ -147,10 +142,28 @@ void loop()
/*------------- Remote Wakeup -------------*/
// Remote wakeup if PC is suspended and we has user interaction with joy feather wing
if ( has_action && TinyUSBDevice.suspended() )
{
if (has_action && TinyUSBDevice.suspended()) {
// Wake up only works if REMOTE_WAKEUP feature is enable by host
// Usually this is the case with Mouse/Keyboard device
TinyUSBDevice.remoteWakeup();
}
}
void loop() {
#ifdef TINYUSB_NEED_POLLING_TASK
// Manual call tud_task since it isn't called by Core's background
TinyUSBDevice.task();
#endif
// not enumerated()/mounted() yet: nothing to do
if (!TinyUSBDevice.mounted()) {
return;
}
// poll gpio once each 10 ms
static uint32_t ms = 0;
if (millis() - ms > 10) {
ms = millis();
process_hid();
}
}

View file

@ -0,0 +1,2 @@
feather_esp32_v2
pico_rp2040_tinyusb_host

View file

@ -19,105 +19,135 @@
* and its active state (when pressed) are different
*/
#if defined(ARDUINO_SAMD_CIRCUITPLAYGROUND_EXPRESS) || defined(ARDUINO_NRF52840_CIRCUITPLAY)
const int pin = 4; // Left Button
bool activeState = true;
const int pin = 4; // Left Button
bool activeState = true;
#elif defined(ARDUINO_FUNHOUSE_ESP32S2)
const int pin = BUTTON_DOWN;
bool activeState = true;
const int pin = BUTTON_DOWN;
bool activeState = true;
#elif defined PIN_BUTTON1
const int pin = PIN_BUTTON1;
bool activeState = false;
const int pin = PIN_BUTTON1;
bool activeState = false;
#elif defined PIN_BUTTON
const int pin = PIN_BUTTON;
bool activeState = false;
const int pin = PIN_BUTTON;
bool activeState = false;
#elif defined(ARDUINO_ARCH_ESP32)
const int pin = 0;
bool activeState = false;
#elif defined(ARDUINO_ARCH_RP2040)
const int pin = D0;
bool activeState = false;
#else
const int pin = 12;
bool activeState = false;
const int pin = A0;
bool activeState = false;
#endif
// HID report descriptor using TinyUSB's template
uint8_t const desc_keyboard_report[] =
{
TUD_HID_REPORT_DESC_KEYBOARD()
uint8_t const desc_keyboard_report[] = {
TUD_HID_REPORT_DESC_KEYBOARD()
};
uint8_t const desc_mouse_report[] =
{
TUD_HID_REPORT_DESC_MOUSE()
uint8_t const desc_mouse_report[] = {
TUD_HID_REPORT_DESC_MOUSE()
};
// USB HID object. For ESP32 these values cannot be changed after this declaration
// desc report, desc len, protocol, interval, use out endpoint
Adafruit_USBD_HID usb_keyboard(desc_keyboard_report, sizeof(desc_keyboard_report), HID_ITF_PROTOCOL_KEYBOARD, 2, false);
Adafruit_USBD_HID usb_mouse(desc_mouse_report, sizeof(desc_mouse_report), HID_ITF_PROTOCOL_MOUSE, 2, false);
// USB HID objects
Adafruit_USBD_HID usb_keyboard;
Adafruit_USBD_HID usb_mouse;
// the setup function runs once when you press reset or power the board
void setup()
{
// Notes: following commented-out functions has no affect on ESP32
// usb_keyboard.setPollInterval(2);
// usb_keyboard.setReportDescriptor();
// usb_keyboard.setStringDescriptor("TinyUSB HID Composite");
void setup() {
// Manual begin() is required on core without built-in support e.g. mbed rp2040
if (!TinyUSBDevice.isInitialized()) {
TinyUSBDevice.begin(0);
}
Serial.begin(115200);
// HID Keyboard
usb_keyboard.setPollInterval(2);
usb_keyboard.setBootProtocol(HID_ITF_PROTOCOL_KEYBOARD);
usb_keyboard.setReportDescriptor(desc_keyboard_report, sizeof(desc_keyboard_report));
usb_keyboard.setStringDescriptor("TinyUSB HID Keyboard");
usb_keyboard.begin();
// HID Mouse
usb_mouse.setPollInterval(2);
usb_mouse.setBootProtocol(HID_ITF_PROTOCOL_MOUSE);
usb_mouse.setReportDescriptor(desc_mouse_report, sizeof(desc_mouse_report));
usb_mouse.setStringDescriptor("TinyUSB HID Keyboard");
usb_mouse.begin();
// If already enumerated, additional class driverr begin() e.g msc, hid, midi won't take effect until re-enumeration
if (TinyUSBDevice.mounted()) {
TinyUSBDevice.detach();
delay(10);
TinyUSBDevice.attach();
}
// Set up button, pullup opposite to active state
pinMode(pin, activeState ? INPUT_PULLDOWN : INPUT_PULLUP);
Serial.begin(115200);
// wait until device mounted
//while( !TinyUSBDevice.mounted() ) delay(1);
Serial.println("Adafruit TinyUSB HID Composite example");
}
void loop()
{
// poll gpio once each 10 ms
delay(10);
void process_hid() {
// Whether button is pressed
bool btn_pressed = (digitalRead(pin) == activeState);
// Remote wakeup
if ( TinyUSBDevice.suspended() && btn_pressed )
{
if (TinyUSBDevice.suspended() && btn_pressed) {
// Wake up host if we are in suspend mode
// and REMOTE_WAKEUP feature is enabled by host
TinyUSBDevice.remoteWakeup();
}
/*------------- Mouse -------------*/
if (usb_mouse.ready() && btn_pressed )
{
if (usb_mouse.ready() && btn_pressed) {
int8_t const delta = 5;
usb_mouse.mouseMove(0, delta, delta); // right + down
}
/*------------- Keyboard -------------*/
if ( usb_keyboard.ready() )
{
if (usb_keyboard.ready()) {
// use to send key release report
static bool has_key = false;
if ( btn_pressed )
{
uint8_t keycode[6] = { 0 };
if (btn_pressed) {
uint8_t keycode[6] = {0};
keycode[0] = HID_KEY_A;
usb_keyboard.keyboardReport(0, 0, keycode);
has_key = true;
}else
{
} else {
// send empty key report if previously has key pressed
if (has_key) usb_keyboard.keyboardRelease(0);
has_key = false;
}
}
}
void loop() {
#ifdef TINYUSB_NEED_POLLING_TASK
// Manual call tud_task since it isn't called by Core's background
TinyUSBDevice.task();
#endif
// not enumerated()/mounted() yet: nothing to do
if (!TinyUSBDevice.mounted()) {
return;
}
// poll gpio once each 10 ms
static uint32_t ms = 0;
if (millis() - ms > 10) {
ms = millis();
process_hid();
}
}

View file

@ -0,0 +1,2 @@
feather_esp32_v2
pico_rp2040_tinyusb_host

View file

@ -22,43 +22,52 @@
// HID report descriptor using TinyUSB's template
// Single Report (no ID) descriptor
uint8_t const desc_hid_report[] =
{
TUD_HID_REPORT_DESC_GAMEPAD()
uint8_t const desc_hid_report[] = {
TUD_HID_REPORT_DESC_GAMEPAD()
};
// USB HID object. For ESP32 these values cannot be changed after this declaration
// desc report, desc len, protocol, interval, use out endpoint
Adafruit_USBD_HID usb_hid(desc_hid_report, sizeof(desc_hid_report), HID_ITF_PROTOCOL_NONE, 2, false);
// USB HID object
Adafruit_USBD_HID usb_hid;
// Report payload defined in src/class/hid/hid.h
// - For Gamepad Button Bit Mask see hid_gamepad_button_bm_t
// - For Gamepad Hat Bit Mask see hid_gamepad_hat_t
hid_gamepad_report_t gp;
hid_gamepad_report_t gp;
void setup()
{
#if defined(ARDUINO_ARCH_MBED) && defined(ARDUINO_ARCH_RP2040)
// Manual begin() is required on core without built-in support for TinyUSB such as mbed rp2040
TinyUSB_Device_Init(0);
#endif
void setup() {
// Manual begin() is required on core without built-in support e.g. mbed rp2040
if (!TinyUSBDevice.isInitialized()) {
TinyUSBDevice.begin(0);
}
Serial.begin(115200);
// Notes: following commented-out functions has no affect on ESP32
// usb_hid.setPollInterval(2);
// usb_hid.setReportDescriptor(desc_hid_report, sizeof(desc_hid_report));
// Setup HID
usb_hid.setPollInterval(2);
usb_hid.setReportDescriptor(desc_hid_report, sizeof(desc_hid_report));
usb_hid.begin();
// wait until device mounted
while( !TinyUSBDevice.mounted() ) delay(1);
// If already enumerated, additional class driverr begin() e.g msc, hid, midi won't take effect until re-enumeration
if (TinyUSBDevice.mounted()) {
TinyUSBDevice.detach();
delay(10);
TinyUSBDevice.attach();
}
Serial.println("Adafruit TinyUSB HID Gamepad example");
}
void loop()
{
void loop() {
#ifdef TINYUSB_NEED_POLLING_TASK
// Manual call tud_task since it isn't called by Core's background
TinyUSBDevice.task();
#endif
// not enumerated()/mounted() yet: nothing to do
if (!TinyUSBDevice.mounted()) {
return;
}
// // Remote wakeup
// if ( TinyUSBDevice.suspended() && btn )
// {
@ -67,22 +76,22 @@ void loop()
// TinyUSBDevice.remoteWakeup();
// }
if ( !usb_hid.ready() ) return;
if (!usb_hid.ready()) return;
// Reset buttons
Serial.println("No pressing buttons");
gp.x = 0;
gp.y = 0;
gp.z = 0;
gp.rz = 0;
gp.rx = 0;
gp.ry = 0;
gp.hat = 0;
gp.x = 0;
gp.y = 0;
gp.z = 0;
gp.rz = 0;
gp.rx = 0;
gp.ry = 0;
gp.hat = 0;
gp.buttons = 0;
usb_hid.sendReport(0, &gp, sizeof(gp));
delay(2000);
// Hat/DPAD UP
Serial.println("Hat/DPAD UP");
gp.hat = 1; // GAMEPAD_HAT_UP;
@ -107,12 +116,12 @@ void loop()
usb_hid.sendReport(0, &gp, sizeof(gp));
delay(2000);
// Hat/DPAD DOWN
// Hat/DPAD DOWN
Serial.println("Hat/DPAD DOWN");
gp.hat = 5; // GAMEPAD_HAT_DOWN;
usb_hid.sendReport(0, &gp, sizeof(gp));
delay(2000);
// Hat/DPAD DOWN LEFT
Serial.println("Hat/DPAD DOWN LEFT");
gp.hat = 6; // GAMEPAD_HAT_DOWN_LEFT;
@ -137,14 +146,14 @@ void loop()
usb_hid.sendReport(0, &gp, sizeof(gp));
delay(2000);
// Joystick 1 UP
Serial.println("Joystick 1 UP");
gp.x = 0;
gp.y = -127;
usb_hid.sendReport(0, &gp, sizeof(gp));
delay(2000);
// Joystick 1 DOWN
Serial.println("Joystick 1 DOWN");
gp.x = 0;
@ -158,7 +167,7 @@ void loop()
gp.y = 0;
usb_hid.sendReport(0, &gp, sizeof(gp));
delay(2000);
// Joystick 1 LEFT
Serial.println("Joystick 1 LEFT");
gp.x = -127;
@ -176,35 +185,35 @@ void loop()
// Joystick 2 UP
Serial.println("Joystick 2 UP");
gp.z = 0;
gp.z = 0;
gp.rz = 127;
usb_hid.sendReport(0, &gp, sizeof(gp));
delay(2000);
// Joystick 2 DOWN
Serial.println("Joystick 2 DOWN");
gp.z = 0;
gp.z = 0;
gp.rz = -127;
usb_hid.sendReport(0, &gp, sizeof(gp));
delay(2000);
// Joystick 2 RIGHT
Serial.println("Joystick 2 RIGHT");
gp.z = 127;
gp.z = 127;
gp.rz = 0;
usb_hid.sendReport(0, &gp, sizeof(gp));
delay(2000);
// Joystick 2 LEFT
Serial.println("Joystick 2 LEFT");
gp.z = -127;
gp.z = -127;
gp.rz = 0;
usb_hid.sendReport(0, &gp, sizeof(gp));
delay(2000);
// Joystick 2 CENTER
Serial.println("Joystick 2 CENTER");
gp.z = 0;
gp.z = 0;
gp.rz = 0;
usb_hid.sendReport(0, &gp, sizeof(gp));
delay(2000);
@ -215,7 +224,7 @@ void loop()
gp.rx = 127;
usb_hid.sendReport(0, &gp, sizeof(gp));
delay(2000);
// Analog Trigger 1 DOWN
Serial.println("Analog Trigger 1 DOWN");
gp.rx = -127;
@ -234,7 +243,7 @@ void loop()
gp.ry = 127;
usb_hid.sendReport(0, &gp, sizeof(gp));
delay(2000);
// Analog Trigger 2 DOWN
Serial.println("Analog Trigger 2 DOWN");
gp.ry = -127;
@ -247,11 +256,11 @@ void loop()
usb_hid.sendReport(0, &gp, sizeof(gp));
delay(2000);
// Test buttons (up to 32 buttons)
for (int i=0; i<32; ++i)
{
Serial.print("Pressing button "); Serial.println(i);
for (int i = 0; i < 32; ++i) {
Serial.print("Pressing button ");
Serial.println(i);
gp.buttons = (1U << i);
usb_hid.sendReport(0, &gp, sizeof(gp));
delay(1000);
@ -260,13 +269,13 @@ void loop()
// Random touch
Serial.println("Random touch");
gp.x = random(-127, 128);
gp.y = random(-127, 128);
gp.z = random(-127, 128);
gp.rz = random(-127, 128);
gp.rx = random(-127, 128);
gp.ry = random(-127, 128);
gp.hat = random(0, 9);
gp.x = random(-127, 128);
gp.y = random(-127, 128);
gp.z = random(-127, 128);
gp.rz = random(-127, 128);
gp.rx = random(-127, 128);
gp.ry = random(-127, 128);
gp.hat = random(0, 9);
gp.buttons = random(0, 0xffff);
usb_hid.sendReport(0, &gp, sizeof(gp));
delay(2000);

View file

@ -0,0 +1,2 @@
feather_esp32_v2
pico_rp2040_tinyusb_host

View file

@ -39,50 +39,51 @@
// HID report descriptor using TinyUSB's template
// Generic In Out with 64 bytes report (max)
uint8_t const desc_hid_report[] =
{
TUD_HID_REPORT_DESC_GENERIC_INOUT(64)
uint8_t const desc_hid_report[] = {
TUD_HID_REPORT_DESC_GENERIC_INOUT(64)
};
// USB HID object. For ESP32 these values cannot be changed after this declaration
// desc report, desc len, protocol, interval, use out endpoint
Adafruit_USBD_HID usb_hid(desc_hid_report, sizeof(desc_hid_report), HID_ITF_PROTOCOL_NONE, 2, true);
// USB HID object
Adafruit_USBD_HID usb_hid;
// the setup function runs once when you press reset or power the board
void setup()
{
#if defined(ARDUINO_ARCH_MBED) && defined(ARDUINO_ARCH_RP2040)
// Manual begin() is required on core without built-in support for TinyUSB such as mbed rp2040
TinyUSB_Device_Init(0);
#endif
// Notes: following commented-out functions has no affect on ESP32
// usb_hid.enableOutEndpoint(true);
// usb_hid.setPollInterval(2);
// usb_hid.setReportDescriptor(desc_hid_report, sizeof(desc_hid_report));
// usb_hid.setStringDescriptor("TinyUSB HID Generic");
usb_hid.setReportCallback(get_report_callback, set_report_callback);
usb_hid.begin();
void setup() {
// Manual begin() is required on core without built-in support e.g. mbed rp2040
if (!TinyUSBDevice.isInitialized()) {
TinyUSBDevice.begin(0);
}
Serial.begin(115200);
// wait until device mounted
while( !TinyUSBDevice.mounted() ) delay(1);
// Notes: following commented-out functions has no affect on ESP32
usb_hid.enableOutEndpoint(true);
usb_hid.setPollInterval(2);
usb_hid.setReportDescriptor(desc_hid_report, sizeof(desc_hid_report));
usb_hid.setStringDescriptor("TinyUSB HID Generic");
usb_hid.setReportCallback(get_report_callback, set_report_callback);
usb_hid.begin();
// If already enumerated, additional class driverr begin() e.g msc, hid, midi won't take effect until re-enumeration
if (TinyUSBDevice.mounted()) {
TinyUSBDevice.detach();
delay(10);
TinyUSBDevice.attach();
}
Serial.println("Adafruit TinyUSB HID Generic In Out example");
}
void loop()
{
// nothing to do
void loop() {
#ifdef TINYUSB_NEED_POLLING_TASK
// Manual call tud_task since it isn't called by Core's background
TinyUSBDevice.task();
#endif
}
// Invoked when received GET_REPORT control request
// Application must fill buffer report's content and return its length.
// Return zero will cause the stack to STALL request
uint16_t get_report_callback (uint8_t report_id, hid_report_type_t report_type, uint8_t* buffer, uint16_t reqlen)
{
uint16_t get_report_callback(uint8_t report_id, hid_report_type_t report_type, uint8_t* buffer, uint16_t reqlen) {
// not used in this example
(void) report_id;
(void) report_type;
@ -93,8 +94,7 @@ uint16_t get_report_callback (uint8_t report_id, hid_report_type_t report_type,
// Invoked when received SET_REPORT control request or
// received data on OUT endpoint ( Report ID = 0, Type = 0 )
void set_report_callback(uint8_t report_id, hid_report_type_t report_type, uint8_t const* buffer, uint16_t bufsize)
{
void set_report_callback(uint8_t report_id, hid_report_type_t report_type, uint8_t const* buffer, uint16_t bufsize) {
// This example doesn't use multiple report and report ID
(void) report_id;
(void) report_type;

View file

@ -55,6 +55,9 @@ dev_info_t dev_info[CFG_TUH_DEVICE_MAX] = { 0 };
Adafruit_USBH_Host USBHost;
//--------------------------------------------------------------------+
// setup() & loop()
//--------------------------------------------------------------------+
void setup() {
Serial1.begin(115200);
Serial1.println("TinyUSB Host: Device Info Example");
@ -63,7 +66,6 @@ void setup() {
USBHost.begin(0);
}
//------------- Core0 -------------//
void loop() {
USBHost.task();
Serial1.flush();

View file

@ -0,0 +1,2 @@
feather_esp32_v2
pico_rp2040_tinyusb_host

View file

@ -19,28 +19,43 @@
// USB MIDI object with 3 ports
Adafruit_USBD_MIDI usb_midi(3);
void setup()
{
void setup() {
#ifdef LED_BUILTIN
pinMode(LED_BUILTIN, OUTPUT);
#if defined(ARDUINO_ARCH_MBED) && defined(ARDUINO_ARCH_RP2040)
// Manual begin() is required on core without built-in support for TinyUSB such as mbed rp2040
TinyUSB_Device_Init(0);
#endif
// Manual begin() is required on core without built-in support e.g. mbed rp2040
if (!TinyUSBDevice.isInitialized()) {
TinyUSBDevice.begin(0);
}
// Set name for each cable, must be done before usb_midi.begin()
usb_midi.setCableName(1, "Keyboard");
usb_midi.setCableName(2, "Drum Pads");
usb_midi.setCableName(3, "Lights");
usb_midi.begin();
// If already enumerated, additional class driverr begin() e.g msc, hid, midi won't take effect until re-enumeration
if (TinyUSBDevice.mounted()) {
TinyUSBDevice.detach();
delay(10);
TinyUSBDevice.attach();
}
}
void loop()
{
digitalWrite(LED_BUILTIN, HIGH);
delay(1000);
void loop() {
#ifdef TINYUSB_NEED_POLLING_TASK
// Manual call tud_task since it isn't called by Core's background
TinyUSBDevice.task();
#endif
digitalWrite(LED_BUILTIN, LOW);
delay(1000);
// toggle LED
static uint32_t ms = 0;
static uint8_t led_state = 0;
if (millis() - ms > 1000) {
ms = millis();
#ifdef LED_BUILTIN
digitalWrite(LED_BUILTIN, 1-led_state);
#endif
}
}

View file

@ -0,0 +1,2 @@
feather_esp32_v2
pico_rp2040_tinyusb_host

View file

@ -31,65 +31,74 @@ uint32_t position = 0;
// Store example melody as an array of note values
byte note_sequence[] = {
74,78,81,86,90,93,98,102,57,61,66,69,73,78,81,85,88,92,97,100,97,92,88,85,81,78,
74,69,66,62,57,62,66,69,74,78,81,86,90,93,97,102,97,93,90,85,81,78,73,68,64,61,
56,61,64,68,74,78,81,86,90,93,98,102
74, 78, 81, 86, 90, 93, 98, 102, 57, 61, 66, 69, 73, 78, 81, 85, 88, 92, 97, 100, 97, 92, 88, 85, 81, 78,
74, 69, 66, 62, 57, 62, 66, 69, 74, 78, 81, 86, 90, 93, 97, 102, 97, 93, 90, 85, 81, 78, 73, 68, 64, 61,
56, 61, 64, 68, 74, 78, 81, 86, 90, 93, 98, 102
};
void setup()
{
#if defined(ARDUINO_ARCH_MBED) && defined(ARDUINO_ARCH_RP2040)
// Manual begin() is required on core without built-in support for TinyUSB such as mbed rp2040
TinyUSB_Device_Init(0);
#endif
void setup() {
// Manual begin() is required on core without built-in support e.g. mbed rp2040
if (!TinyUSBDevice.isInitialized()) {
TinyUSBDevice.begin(0);
}
pinMode(LED_BUILTIN, OUTPUT);
//usb_midi.setStringDescriptor("TinyUSB MIDI");
Serial.begin(115200);
usb_midi.setStringDescriptor("TinyUSB MIDI");
// Initialize MIDI, and listen to all MIDI channels
// This will also call usb_midi's begin()
MIDI.begin(MIDI_CHANNEL_OMNI);
// If already enumerated, additional class driverr begin() e.g msc, hid, midi won't take effect until re-enumeration
if (TinyUSBDevice.mounted()) {
TinyUSBDevice.detach();
delay(10);
TinyUSBDevice.attach();
}
// Attach the handleNoteOn function to the MIDI Library. It will
// be called whenever the Bluefruit receives MIDI Note On messages.
MIDI.setHandleNoteOn(handleNoteOn);
// Do the same for MIDI Note Off messages.
MIDI.setHandleNoteOff(handleNoteOff);
Serial.begin(115200);
// wait until device mounted
while( !TinyUSBDevice.mounted() ) delay(1);
}
void loop()
{
void loop() {
#ifdef TINYUSB_NEED_POLLING_TASK
// Manual call tud_task since it isn't called by Core's background
TinyUSBDevice.task();
#endif
// not enumerated()/mounted() yet: nothing to do
if (!TinyUSBDevice.mounted()) {
return;
}
static uint32_t start_ms = 0;
if ( millis() - start_ms > 266 )
{
if (millis() - start_ms > 266) {
start_ms += 266;
// Setup variables for the current and previous
// positions in the note sequence.
int previous = position - 1;
// If we currently are at position 0, set the
// previous position to the last note in the sequence.
if (previous < 0) {
previous = sizeof(note_sequence) - 1;
}
// Send Note On for current position at full velocity (127) on channel 1.
MIDI.sendNoteOn(note_sequence[position], 127, 1);
// Send Note Off for previous note.
MIDI.sendNoteOff(note_sequence[previous], 0, 1);
// Increment position
position++;
// If we are at the end of the sequence, start over.
if (position >= sizeof(note_sequence)) {
position = 0;
@ -97,11 +106,10 @@ void loop()
}
// read any new MIDI messages
MIDI.read();
MIDI.read();
}
void handleNoteOn(byte channel, byte pitch, byte velocity)
{
void handleNoteOn(byte channel, byte pitch, byte velocity) {
// Log when a note is pressed.
Serial.print("Note on: channel = ");
Serial.print(channel);
@ -113,8 +121,7 @@ void handleNoteOn(byte channel, byte pitch, byte velocity)
Serial.println(velocity);
}
void handleNoteOff(byte channel, byte pitch, byte velocity)
{
void handleNoteOff(byte channel, byte pitch, byte velocity) {
// Log when a note is released.
Serial.print("Note off: channel = ");
Serial.print(channel);

View file

@ -32,7 +32,7 @@
*/
#include "SPI.h"
#include "SdFat.h"
#include "SdFat_Adafruit_Fork.h"
#include "Adafruit_SPIFlash.h"
#include "Adafruit_TinyUSB.h"
@ -93,14 +93,19 @@ void setupMassStorage(void)
// MSC is ready for read/write
fs_changed = false;
usb_msc.setReadyCallback(0, msc_ready_callback);
usb_msc.begin();
// If already enumerated, additional class driverr begin() e.g msc, hid, midi won't take effect until re-enumeration
if (TinyUSBDevice.mounted()) {
TinyUSBDevice.detach();
delay(10);
TinyUSBDevice.attach();
}
// Init file system on the flash
fs_formatted = fatfs.begin(&flash);
if ( !fs_formatted )
{
if ( !fs_formatted ) {
DBG_SERIAL.println("Failed to init files system, flash may not be formatted");
}
}

View file

@ -0,0 +1,3 @@
feather_esp32_v2
pico_rp2040_tinyusb_host
CH32V20x_EVT

View file

@ -23,7 +23,7 @@
*/
#include "SPI.h"
#include "SdFat.h"
#include "SdFat_Adafruit_Fork.h"
#include "Adafruit_SPIFlash.h"
#include "Adafruit_TinyUSB.h"
@ -48,9 +48,12 @@ bool fs_formatted = false;
bool fs_changed = true;;
// the setup function runs once when you press reset or power the board
void setup()
{
void setup() {
#ifdef LED_BUILTIN
pinMode(LED_BUILTIN, OUTPUT);
#endif
Serial.begin(115200);
flash.begin();
@ -68,10 +71,16 @@ void setup()
usb_msc.begin();
// If already enumerated, additional class driverr begin() e.g msc, hid, midi won't take effect until re-enumeration
if (TinyUSBDevice.mounted()) {
TinyUSBDevice.detach();
delay(10);
TinyUSBDevice.attach();
}
// Init file system on the flash
fs_formatted = fatfs.begin(&flash);
Serial.begin(115200);
//while ( !Serial ) delay(10); // wait for native usb
Serial.println("Adafruit TinyUSB Mass Storage External Flash example");
@ -79,15 +88,12 @@ void setup()
Serial.print("Flash size: "); Serial.print(flash.size() / 1024); Serial.println(" KB");
}
void loop()
{
void loop() {
// check if formatted
if ( !fs_formatted )
{
if ( !fs_formatted ) {
fs_formatted = fatfs.begin(&flash);
if (!fs_formatted)
{
if (!fs_formatted) {
Serial.println("Failed to init files system, flash may not be formatted");
Serial.println("Please format it as FAT12 with your PC or using Adafruit_SPIFlash's SdFat_format example:");
Serial.println("- https://github.com/adafruit/Adafruit_SPIFlash/tree/master/examples/SdFat_format");
@ -98,14 +104,12 @@ void loop()
}
}
if ( fs_changed )
{
if ( fs_changed ) {
fs_changed = false;
Serial.println("Opening root");
if ( !root.open("/") )
{
if ( !root.open("/") ) {
Serial.println("open root failed");
return;
}
@ -115,13 +119,11 @@ void loop()
// Open next file in root.
// Warning, openNext starts at the current directory position
// so a rewind of the directory may be required.
while ( file.openNext(&root, O_RDONLY) )
{
while ( file.openNext(&root, O_RDONLY) ) {
file.printFileSize(&Serial);
Serial.write(' ');
file.printName(&Serial);
if ( file.isDir() )
{
if ( file.isDir() ) {
// Indicate a directory.
Serial.write('/');
}
@ -139,8 +141,7 @@ void loop()
// Callback invoked when received READ10 command.
// Copy disk's data to buffer (up to bufsize) and
// return number of copied bytes (must be multiple of block size)
int32_t msc_read_cb (uint32_t lba, void* buffer, uint32_t bufsize)
{
int32_t msc_read_cb (uint32_t lba, void* buffer, uint32_t bufsize) {
// Note: SPIFLash Block API: readBlocks/writeBlocks/syncBlocks
// already include 4K sector caching internally. We don't need to cache it, yahhhh!!
return flash.readBlocks(lba, (uint8_t*) buffer, bufsize/512) ? bufsize : -1;
@ -149,9 +150,10 @@ int32_t msc_read_cb (uint32_t lba, void* buffer, uint32_t bufsize)
// Callback invoked when received WRITE10 command.
// Process data in buffer to disk's storage and
// return number of written bytes (must be multiple of block size)
int32_t msc_write_cb (uint32_t lba, uint8_t* buffer, uint32_t bufsize)
{
int32_t msc_write_cb (uint32_t lba, uint8_t* buffer, uint32_t bufsize) {
#ifdef LED_BUILTIN
digitalWrite(LED_BUILTIN, HIGH);
#endif
// Note: SPIFLash Block API: readBlocks/writeBlocks/syncBlocks
// already include 4K sector caching internally. We don't need to cache it, yahhhh!!
@ -160,8 +162,7 @@ int32_t msc_write_cb (uint32_t lba, uint8_t* buffer, uint32_t bufsize)
// Callback invoked when WRITE10 command is completed (status received and accepted by host).
// used to flush any pending cache.
void msc_flush_cb (void)
{
void msc_flush_cb (void) {
// sync with flash
flash.syncBlocks();
@ -170,5 +171,7 @@ void msc_flush_cb (void)
fs_changed = true;
#ifdef LED_BUILTIN
digitalWrite(LED_BUILTIN, LOW);
#endif
}

View file

@ -0,0 +1,3 @@
feather_esp32_v2
pico_rp2040_tinyusb_host
CH32V20x_EVT

View file

@ -23,7 +23,7 @@
*/
#include "SPI.h"
#include "SdFat.h"
#include "SdFat_Adafruit_Fork.h"
#include "Adafruit_SPIFlash.h"
#include "Adafruit_TinyUSB.h"
@ -33,42 +33,67 @@
// for flashTransport definition
#include "flash_config.h"
Adafruit_SPIFlash flash(&flashTransport);
// External Flash File system
FatVolume fatfs;
//--------------------------------------------------------------------+
// SDCard Config
//--------------------------------------------------------------------+
#if defined(ARDUINO_PYPORTAL_M4) || defined(ARDUINO_PYPORTAL_M4_TITANO)
// PyPortal has on-board card reader
#define SDCARD_CS 32
#define SDCARD_DETECT 33
#define SDCARD_CS 32
#define SDCARD_DETECT 33
#define SDCARD_DETECT_ACTIVE HIGH
#elif defined(ARDUINO_ADAFRUIT_METRO_RP2040)
#define SDIO_CLK_PIN 18
#define SDIO_CMD_PIN 19 // MOSI
#define SDIO_DAT0_PIN 20 // DAT1: 21, DAT2: 22, DAT3: 23
#define SDCARD_DETECT 15
#define SDCARD_DETECT_ACTIVE LOW
#elif defined(ARDUINO_ADAFRUIT_METRO_RP2350)
// Note: not working yet (need troubleshoot later)
#define SDIO_CLK_PIN 34
#define SDIO_CMD_PIN 35 // MOSI
#define SDIO_DAT0_PIN 36 // DAT1: 37, DAT2: 38, DAT3: 39
#define SDCARD_DETECT 40
#define SDCARD_DETECT_ACTIVE LOW
#elif defined(ARDUINO_ADAFRUIT_FRUITJAM_RP2350)
#define SDIO_CLK_PIN 34
#define SDIO_CMD_PIN 35 // MOSI
#define SDIO_DAT0_PIN 36 // DAT1: 37, DAT2: 38, DAT3: 39
#define SDCARD_DETECT 33
#define SDCARD_DETECT_ACTIVE LOW
#else
// Use SPI, no detect
#define SDCARD_CS 10
// no detect
#endif
// SDCard File system
#if defined(SDIO_CLK_PIN) && defined(SDIO_CMD_PIN) && defined(SDIO_DAT0_PIN)
#define SD_CONFIG SdioConfig(SDIO_CLK_PIN, SDIO_CMD_PIN, SDIO_DAT0_PIN)
#else
#define SD_CONFIG SdSpiConfig(SDCARD_CS, SHARED_SPI, SD_SCK_MHZ(50))
#endif
// File system on SD Card
SdFat sd;
// USB Mass Storage object
Adafruit_USBD_MSC usb_msc;
// Set to true when PC write to flash
bool sd_changed = false;
bool sd_inited = false;
bool flash_formatted = false;
bool flash_changed = false;
// the setup function runs once when you press reset or power the board
void setup()
{
void setup() {
#ifdef LED_BUILTIN
pinMode(LED_BUILTIN, OUTPUT);
#endif
Serial.begin(115200);
// MSC with 2 Logical Units: LUN0: External Flash, LUN1: SDCard
@ -83,16 +108,20 @@ void setup()
// LUN readiness will always be set later on
usb_msc.begin();
// If already enumerated, additional class driverr begin() e.g msc, hid, midi won't take effect until re-enumeration
if (TinyUSBDevice.mounted()) {
TinyUSBDevice.detach();
delay(10);
TinyUSBDevice.attach();
}
//------------- Lun 0 for external flash -------------//
flash.begin();
flash_formatted = fatfs.begin(&flash);
usb_msc.setCapacity(0, flash.size()/512, 512);
usb_msc.setReadWriteCallback(0, external_flash_read_cb, external_flash_write_cb, external_flash_flush_cb);
usb_msc.setUnitReady(0, true);
flash_changed = true; // to print contents initially
//------------- Lun 1 for SD card -------------//
#ifdef SDCARD_DETECT
// DETECT pin is available, detect card present on the fly with test unit ready
@ -105,58 +134,44 @@ void setup()
usb_msc.setUnitReady(1, true);
#endif
// while ( !Serial ) delay(10); // wait for native usb
// while ( !Serial ) delay(10); // wait for native usb
Serial.println("Adafruit TinyUSB Mass Storage External Flash + SD Card example");
delay(1000);
}
bool init_sdcard(void)
{
bool init_sdcard(void) {
Serial.print("Init SDCard ... ");
if ( !sd.begin(SDCARD_CS, SD_SCK_MHZ(50)) )
{
Serial.print("Failed ");
sd.errorPrint("sd.begin() failed");
if (!sd.begin(SD_CONFIG)) {
Serial.println("initialization failed. Things to check:");
Serial.println("- is a card inserted?");
Serial.println("- is your wiring correct?");
Serial.println("- did you change the SDCARD_CS or SDIO pin to match your shield or module?");
return false;
}
uint32_t block_count;
#if SD_FAT_VERSION >= 20000
block_count = sd.card()->sectorCount();
#else
block_count = sd.card()->cardSize();
#endif
uint32_t block_count = sd.card()->sectorCount();
usb_msc.setCapacity(1, block_count, 512);
usb_msc.setReadWriteCallback(1, sdcard_read_cb, sdcard_write_cb, sdcard_flush_cb);
sd_changed = true; // to print contents initially
Serial.print("OK, Card size = ");
Serial.print((block_count / (1024*1024)) * 512);
Serial.print((block_count / (1024 * 1024)) * 512);
Serial.println(" MB");
return true;
}
void print_rootdir(File32* rdir)
{
void print_rootdir(File32* rdir) {
File32 file;
// Open next file in root.
// Warning, openNext starts at the current directory position
// so a rewind of the directory may be required.
while ( file.openNext(rdir, O_RDONLY) )
{
while (file.openNext(rdir, O_RDONLY)) {
file.printFileSize(&Serial);
Serial.write(' ');
file.printName(&Serial);
if ( file.isDir() )
{
if (file.isDir()) {
// Indicate a directory.
Serial.write('/');
}
@ -165,46 +180,8 @@ void print_rootdir(File32* rdir)
}
}
void loop()
{
if ( flash_changed )
{
if (!flash_formatted)
{
flash_formatted = fatfs.begin(&flash);
}
// skip if still not formatted
if (flash_formatted)
{
File32 root;
root = fatfs.open("/");
Serial.println("Flash contents:");
print_rootdir(&root);
Serial.println();
root.close();
}
flash_changed = false;
}
if ( sd_changed )
{
File32 root;
root = sd.open("/");
Serial.println("SD contents:");
print_rootdir(&root);
Serial.println();
root.close();
sd_changed = false;
}
delay(1000); // refresh every 1 second
void loop() {
// nothing to do
}
@ -212,76 +189,48 @@ void loop()
// SD Card callbacks
//--------------------------------------------------------------------+
int32_t sdcard_read_cb (uint32_t lba, void* buffer, uint32_t bufsize)
{
bool rc;
#if SD_FAT_VERSION >= 20000
rc = sd.card()->readSectors(lba, (uint8_t*) buffer, bufsize/512);
#else
rc = sd.card()->readBlocks(lba, (uint8_t*) buffer, bufsize/512);
#endif
int32_t sdcard_read_cb (uint32_t lba, void* buffer, uint32_t bufsize) {
bool rc = sd.card()->readSectors(lba, (uint8_t*) buffer, bufsize/512);
return rc ? bufsize : -1;
}
// Callback invoked when received WRITE10 command.
// Process data in buffer to disk's storage and
// return number of written bytes (must be multiple of block size)
int32_t sdcard_write_cb (uint32_t lba, uint8_t* buffer, uint32_t bufsize)
{
bool rc;
int32_t sdcard_write_cb (uint32_t lba, uint8_t* buffer, uint32_t bufsize) {
#ifdef LED_BUILTIN
digitalWrite(LED_BUILTIN, HIGH);
#if SD_FAT_VERSION >= 20000
rc = sd.card()->writeSectors(lba, buffer, bufsize/512);
#else
rc = sd.card()->writeBlocks(lba, buffer, bufsize/512);
#endif
bool rc = sd.card()->writeSectors(lba, buffer, bufsize/512);
return rc ? bufsize : -1;
}
// Callback invoked when WRITE10 command is completed (status received and accepted by host).
// used to flush any pending cache.
void sdcard_flush_cb (void)
{
#if SD_FAT_VERSION >= 20000
void sdcard_flush_cb (void) {
sd.card()->syncDevice();
#else
sd.card()->syncBlocks();
#endif
// clear file system's cache to force refresh
sd.cacheClear();
sd_changed = true;
sd.cacheClear(); // clear file system's cache to force refresh
#ifdef LED_BUILTIN
digitalWrite(LED_BUILTIN, LOW);
#endif
}
#ifdef SDCARD_DETECT
// Invoked when received Test Unit Ready command.
// return true allowing host to read/write this LUN e.g SD card inserted
bool sdcard_ready_callback(void)
{
bool sdcard_ready_callback(void) {
// Card is inserted
if ( digitalRead(SDCARD_DETECT) == HIGH )
{
if (digitalRead(SDCARD_DETECT) == SDCARD_DETECT_ACTIVE) {
// init SD card if not already
if ( !sd_inited )
{
if (!sd_inited) {
sd_inited = init_sdcard();
}
}else
{
} else {
sd_inited = false;
usb_msc.setReadWriteCallback(1, NULL, NULL, NULL);
}
Serial.println(sd_inited);
return sd_inited;
}
#endif
@ -293,8 +242,7 @@ bool sdcard_ready_callback(void)
// Callback invoked when received READ10 command.
// Copy disk's data to buffer (up to bufsize) and
// return number of copied bytes (must be multiple of block size)
int32_t external_flash_read_cb (uint32_t lba, void* buffer, uint32_t bufsize)
{
int32_t external_flash_read_cb (uint32_t lba, void* buffer, uint32_t bufsize) {
// Note: SPIFLash Bock API: readBlocks/writeBlocks/syncBlocks
// already include 4K sector caching internally. We don't need to cache it, yahhhh!!
return flash.readBlocks(lba, (uint8_t*) buffer, bufsize/512) ? bufsize : -1;
@ -303,9 +251,10 @@ int32_t external_flash_read_cb (uint32_t lba, void* buffer, uint32_t bufsize)
// Callback invoked when received WRITE10 command.
// Process data in buffer to disk's storage and
// return number of written bytes (must be multiple of block size)
int32_t external_flash_write_cb (uint32_t lba, uint8_t* buffer, uint32_t bufsize)
{
int32_t external_flash_write_cb (uint32_t lba, uint8_t* buffer, uint32_t bufsize) {
#ifdef LED_BUILTIN
digitalWrite(LED_BUILTIN, HIGH);
#endif
// Note: SPIFLash Bock API: readBlocks/writeBlocks/syncBlocks
// already include 4K sector caching internally. We don't need to cache it, yahhhh!!
@ -314,14 +263,9 @@ int32_t external_flash_write_cb (uint32_t lba, uint8_t* buffer, uint32_t bufsize
// Callback invoked when WRITE10 command is completed (status received and accepted by host).
// used to flush any pending cache.
void external_flash_flush_cb (void)
{
void external_flash_flush_cb (void) {
flash.syncBlocks();
// clear file system's cache to force refresh
fatfs.cacheClear();
flash_changed = true;
#ifdef LED_BUILTIN
digitalWrite(LED_BUILTIN, LOW);
#endif
}

View file

@ -10,7 +10,7 @@
*********************************************************************/
#include "SPI.h"
#include "SdFat.h"
#include "SdFat_Adafruit_Fork.h"
#include "Adafruit_InternalFlash.h"
#include "Adafruit_TinyUSB.h"
@ -35,8 +35,9 @@ Adafruit_USBD_MSC usb_msc;
bool fs_changed;
// the setup function runs once when you press reset or power the board
void setup()
{
void setup() {
Serial.begin(115200);
// Initialize internal flash
flash.begin();
@ -46,32 +47,30 @@ void setup()
// Set callback
usb_msc.setReadWriteCallback(msc_read_callback, msc_write_callback, msc_flush_callback);
usb_msc.setWritableCallback(msc_writable_callback);
// Set disk size, block size should be 512 regardless of flash page size
usb_msc.setCapacity(flash.size()/512, 512);
// Set Lun ready
usb_msc.setUnitReady(true);
usb_msc.setCapacity(flash.size()/512, 512); // Set disk size, block size should be 512 regardless of flash page size
usb_msc.setUnitReady(true); // Set Lun ready
usb_msc.begin();
// If already enumerated, additional class driverr begin() e.g msc, hid, midi won't take effect until re-enumeration
if (TinyUSBDevice.mounted()) {
TinyUSBDevice.detach();
delay(10);
TinyUSBDevice.attach();
}
// Init file system on the flash
fatfs.begin(&flash);
Serial.begin(115200);
//while ( !Serial ) delay(10); // wait for native usb
fs_changed = true; // to print contents initially
}
void loop()
{
if ( fs_changed )
{
void loop() {
if ( fs_changed ) {
fs_changed = false;
if ( !root.open("/") )
{
if ( !root.open("/") ) {
Serial.println("open root failed");
return;
}
@ -81,13 +80,11 @@ void loop()
// Open next file in root.
// Warning, openNext starts at the current directory position
// so a rewind of the directory may be required.
while ( file.openNext(&root, O_RDONLY) )
{
while ( file.openNext(&root, O_RDONLY) ) {
file.printFileSize(&Serial);
Serial.write(' ');
file.printName(&Serial);
if ( file.isDir() )
{
if ( file.isDir() ) {
// Indicate a directory.
Serial.write('/');
}
@ -105,8 +102,7 @@ void loop()
// Callback invoked when received READ10 command.
// Copy disk's data to buffer (up to bufsize) and
// return number of copied bytes (must be multiple of block size)
int32_t msc_read_callback (uint32_t lba, void* buffer, uint32_t bufsize)
{
int32_t msc_read_callback (uint32_t lba, void* buffer, uint32_t bufsize) {
// Note: InternalFlash Block API: readBlocks/writeBlocks/syncBlocks
// already include sector caching (if needed). We don't need to cache it, yahhhh!!
return flash.readBlocks(lba, (uint8_t*) buffer, bufsize/512) ? bufsize : -1;
@ -115,8 +111,7 @@ int32_t msc_read_callback (uint32_t lba, void* buffer, uint32_t bufsize)
// Callback invoked when received WRITE10 command.
// Process data in buffer to disk's storage and
// return number of written bytes (must be multiple of block size)
int32_t msc_write_callback (uint32_t lba, uint8_t* buffer, uint32_t bufsize)
{
int32_t msc_write_callback (uint32_t lba, uint8_t* buffer, uint32_t bufsize) {
// Note: InternalFlash Block API: readBlocks/writeBlocks/syncBlocks
// already include sector caching (if needed). We don't need to cache it, yahhhh!!
return flash.writeBlocks(lba, buffer, bufsize/512) ? bufsize : -1;
@ -124,8 +119,7 @@ int32_t msc_write_callback (uint32_t lba, uint8_t* buffer, uint32_t bufsize)
// Callback invoked when WRITE10 command is completed (status received and accepted by host).
// used to flush any pending cache.
void msc_flush_callback (void)
{
void msc_flush_callback (void) {
// sync with flash
flash.syncBlocks();
@ -137,8 +131,7 @@ void msc_flush_callback (void)
// Invoked to check if device is writable as part of SCSI WRITE10
// Default mode is writable
bool msc_writable_callback(void)
{
bool msc_writable_callback(void) {
// true for writable, false for read-only
return true;
}

View file

@ -0,0 +1,2 @@
feather_esp32_v2
pico_rp2040_tinyusb_host

View file

@ -14,6 +14,7 @@
// 8KB is the smallest size that windows allow to mount
#define DISK_BLOCK_NUM 16
#define DISK_BLOCK_SIZE 512
#include "ramdisk.h"
Adafruit_USBD_MSC usb_msc;
@ -36,10 +37,15 @@ Adafruit_USBD_MSC usb_msc;
// the setup function runs once when you press reset or power the board
void setup() {
#if defined(ARDUINO_ARCH_MBED) && defined(ARDUINO_ARCH_RP2040)
// Manual begin() is required on core without built-in support for TinyUSB such as
// - mbed rp2040
TinyUSB_Device_Init(0);
// Manual begin() is required on core without built-in support e.g. mbed rp2040
if (!TinyUSBDevice.isInitialized()) {
TinyUSBDevice.begin(0);
}
Serial.begin(115200);
#ifdef BTN_EJECT
pinMode(BTN_EJECT, activeState ? INPUT_PULLDOWN : INPUT_PULLUP);
#endif
// Set disk vendor id, product id and revision with string up to 8, 16, 4 characters respectively
@ -50,33 +56,35 @@ void setup() {
// Set callback
usb_msc.setReadWriteCallback(msc_read_callback, msc_write_callback, msc_flush_callback);
usb_msc.setStartStopCallback(msc_start_stop_callback);
usb_msc.setReadyCallback(msc_ready_callback);
// Set Lun ready (RAM disk is always ready)
usb_msc.setUnitReady(true);
#ifdef BTN_EJECT
pinMode(BTN_EJECT, activeState ? INPUT_PULLDOWN : INPUT_PULLUP);
usb_msc.setReadyCallback(msc_ready_callback);
#endif
usb_msc.begin();
Serial.begin(115200);
//while ( !Serial ) delay(10); // wait for native usb
// If already enumerated, additional class driverr begin() e.g msc, hid, midi won't take effect until re-enumeration
if (TinyUSBDevice.mounted()) {
TinyUSBDevice.detach();
delay(10);
TinyUSBDevice.attach();
}
// while ( !Serial ) delay(10); // wait for native usb
Serial.println("Adafruit TinyUSB Mass Storage RAM Disk example");
}
void loop()
{
// nothing to do
void loop() {
#ifdef TINYUSB_NEED_POLLING_TASK
// Manual call tud_task since it isn't called by Core's background
TinyUSBDevice.task();
#endif
}
// Callback invoked when received READ10 command.
// Copy disk's data to buffer (up to bufsize) and
// return number of copied bytes (must be multiple of block size)
int32_t msc_read_callback (uint32_t lba, void* buffer, uint32_t bufsize)
{
int32_t msc_read_callback(uint32_t lba, void* buffer, uint32_t bufsize) {
uint8_t const* addr = msc_disk[lba];
memcpy(buffer, addr, bufsize);
@ -86,8 +94,7 @@ int32_t msc_read_callback (uint32_t lba, void* buffer, uint32_t bufsize)
// Callback invoked when received WRITE10 command.
// Process data in buffer to disk's storage and
// return number of written bytes (must be multiple of block size)
int32_t msc_write_callback (uint32_t lba, uint8_t* buffer, uint32_t bufsize)
{
int32_t msc_write_callback(uint32_t lba, uint8_t* buffer, uint32_t bufsize) {
uint8_t* addr = msc_disk[lba];
memcpy(addr, buffer, bufsize);
@ -96,18 +103,22 @@ int32_t msc_write_callback (uint32_t lba, uint8_t* buffer, uint32_t bufsize)
// Callback invoked when WRITE10 command is completed (status received and accepted by host).
// used to flush any pending cache.
void msc_flush_callback (void)
{
void msc_flush_callback(void) {
// nothing to do
}
bool msc_start_stop_callback(uint8_t power_condition, bool start, bool load_eject) {
Serial.printf("Start/Stop callback: power condition %u, start %u, load_eject %u\n", power_condition, start, load_eject);
return true;
}
#ifdef BTN_EJECT
// Invoked when received Test Unit Ready command.
// return true allowing host to read/write this LUN e.g SD card inserted
bool msc_ready_callback(void)
{
bool msc_ready_callback(void) {
#ifdef BTN_EJECT
// button not active --> medium ready
return digitalRead(BTN_EJECT) != activeState;
#else
return true;
#endif
}
#endif

View file

@ -0,0 +1,3 @@
feather_esp32_v2
pico_rp2040_tinyusb_host
CH32V20x_EVT

View file

@ -14,20 +14,22 @@
// 8KB is the smallest size that windows allow to mount
#define DISK_BLOCK_NUM 16
#define DISK_BLOCK_SIZE 512
#include "ramdisk.h"
Adafruit_USBD_MSC usb_msc;
// the setup function runs once when you press reset or power the board
void setup()
{
#if defined(ARDUINO_ARCH_MBED) && defined(ARDUINO_ARCH_RP2040)
// Manual begin() is required on core without built-in support for TinyUSB such as mbed rp2040
TinyUSB_Device_Init(0);
#endif
void setup() {
// Manual begin() is required on core without built-in support e.g. mbed rp2040
if (!TinyUSBDevice.isInitialized()) {
TinyUSBDevice.begin(0);
}
Serial.begin(115200);
usb_msc.setMaxLun(2);
// Set disk size and callback for Logical Unit 0 (LUN 0)
usb_msc.setID(0, "Adafruit", "Lun0", "1.0");
usb_msc.setCapacity(0, DISK_BLOCK_NUM, DISK_BLOCK_SIZE);
@ -39,18 +41,25 @@ void setup()
usb_msc.setCapacity(1, DISK_BLOCK_NUM, DISK_BLOCK_SIZE);
usb_msc.setReadWriteCallback(1, ram1_read_cb, ram1_write_cb, ram1_flush_cb);
usb_msc.setUnitReady(1, true);
usb_msc.begin();
Serial.begin(115200);
//while ( !Serial ) delay(10); // wait for native usb
// If already enumerated, additional class driverr begin() e.g msc, hid, midi won't take effect until re-enumeration
if (TinyUSBDevice.mounted()) {
TinyUSBDevice.detach();
delay(10);
TinyUSBDevice.attach();
}
//while ( !Serial ) delay(10); // wait for native usb
Serial.println("Adafruit TinyUSB Mass Storage Dual RAM Disks example");
}
void loop()
{
// nothing to do
void loop() {
#ifdef TINYUSB_NEED_POLLING_TASK
// Manual call tud_task since it isn't called by Core's background
TinyUSBDevice.task();
#endif
}
@ -61,8 +70,7 @@ void loop()
// Callback invoked when received READ10 command.
// Copy disk's data to buffer (up to bufsize) and
// return number of copied bytes (must be multiple of block size)
int32_t ram0_read_cb (uint32_t lba, void* buffer, uint32_t bufsize)
{
int32_t ram0_read_cb(uint32_t lba, void* buffer, uint32_t bufsize) {
uint8_t const* addr = msc_disk0[lba];
memcpy(buffer, addr, bufsize);
@ -72,8 +80,7 @@ int32_t ram0_read_cb (uint32_t lba, void* buffer, uint32_t bufsize)
// Callback invoked when received WRITE10 command.
// Process data in buffer to disk's storage and
// return number of written bytes (must be multiple of block size)
int32_t ram0_write_cb (uint32_t lba, uint8_t* buffer, uint32_t bufsize)
{
int32_t ram0_write_cb(uint32_t lba, uint8_t* buffer, uint32_t bufsize) {
uint8_t* addr = msc_disk0[lba];
memcpy(addr, buffer, bufsize);
@ -82,8 +89,7 @@ int32_t ram0_write_cb (uint32_t lba, uint8_t* buffer, uint32_t bufsize)
// Callback invoked when WRITE10 command is completed (status received and accepted by host).
// used to flush any pending cache.
void ram0_flush_cb (void)
{
void ram0_flush_cb(void) {
// nothing to do
}
@ -95,8 +101,7 @@ void ram0_flush_cb (void)
// Callback invoked when received READ10 command.
// Copy disk's data to buffer (up to bufsize) and
// return number of copied bytes (must be multiple of block size)
int32_t ram1_read_cb (uint32_t lba, void* buffer, uint32_t bufsize)
{
int32_t ram1_read_cb(uint32_t lba, void* buffer, uint32_t bufsize) {
uint8_t const* addr = msc_disk1[lba];
memcpy(buffer, addr, bufsize);
@ -106,8 +111,7 @@ int32_t ram1_read_cb (uint32_t lba, void* buffer, uint32_t bufsize)
// Callback invoked when received WRITE10 command.
// Process data in buffer to disk's storage and
// return number of written bytes (must be multiple of block size)
int32_t ram1_write_cb (uint32_t lba, uint8_t* buffer, uint32_t bufsize)
{
int32_t ram1_write_cb(uint32_t lba, uint8_t* buffer, uint32_t bufsize) {
uint8_t* addr = msc_disk1[lba];
memcpy(addr, buffer, bufsize);
@ -116,7 +120,6 @@ int32_t ram1_write_cb (uint32_t lba, uint8_t* buffer, uint32_t bufsize)
// Callback invoked when WRITE10 command is completed (status received and accepted by host).
// used to flush any pending cache.
void ram1_flush_cb (void)
{
void ram1_flush_cb(void) {
// nothing to do
}

View file

@ -0,0 +1,10 @@
feather_esp32_v2
feather_esp32s2
feather_esp32s3
funhouse
magtag
metroesp32s2
esp32p4
feather_rp2040_tinyusb
pico_rp2040_tinyusb_host
CH32V20x_EVT

View file

@ -26,6 +26,8 @@ SdVolume volume;
// the setup function runs once when you press reset or power the board
void setup()
{
Serial.begin(115200);
// Set disk vendor id, product id and revision with string up to 8, 16, 4 characters respectively
usb_msc.setID("Adafruit", "SD Card", "1.0");
@ -37,15 +39,18 @@ void setup()
usb_msc.setUnitReady(false);
usb_msc.begin();
Serial.begin(115200);
// If already enumerated, additional class driverr begin() e.g msc, hid, midi won't take effect until re-enumeration
if (TinyUSBDevice.mounted()) {
TinyUSBDevice.detach();
delay(10);
TinyUSBDevice.attach();
}
//while ( !Serial ) delay(10); // wait for native usb
Serial.println("Adafruit TinyUSB Mass Storage SD Card example");
Serial.println("\nInitializing SD card...");
if ( !card.init(SPI_HALF_SPEED, chipSelect) )
{
if ( !card.init(SPI_HALF_SPEED, chipSelect) ) {
Serial.println("initialization failed. Things to check:");
Serial.println("* is a card inserted?");
Serial.println("* is your wiring correct?");
@ -71,16 +76,14 @@ void setup()
usb_msc.setUnitReady(true);
}
void loop()
{
void loop() {
// nothing to do
}
// Callback invoked when received READ10 command.
// Copy disk's data to buffer (up to bufsize) and
// return number of copied bytes (must be multiple of block size)
int32_t msc_read_cb (uint32_t lba, void* buffer, uint32_t bufsize)
{
int32_t msc_read_cb (uint32_t lba, void* buffer, uint32_t bufsize) {
(void) bufsize;
return card.readBlock(lba, (uint8_t*) buffer) ? 512 : -1;
}
@ -88,15 +91,13 @@ int32_t msc_read_cb (uint32_t lba, void* buffer, uint32_t bufsize)
// Callback invoked when received WRITE10 command.
// Process data in buffer to disk's storage and
// return number of written bytes (must be multiple of block size)
int32_t msc_write_cb (uint32_t lba, uint8_t* buffer, uint32_t bufsize)
{
int32_t msc_write_cb (uint32_t lba, uint8_t* buffer, uint32_t bufsize) {
(void) bufsize;
return card.writeBlock(lba, buffer) ? 512 : -1;
}
// Callback invoked when WRITE10 command is completed (status received and accepted by host).
// used to flush any pending cache.
void msc_flush_cb (void)
{
void msc_flush_cb (void) {
// nothing to do
}

View file

@ -0,0 +1,2 @@
feather_esp32_v2
pico_rp2040_tinyusb_host

View file

@ -10,31 +10,69 @@
*********************************************************************/
/* This example expose SD card as mass storage using
* SdFat Library
* - SdFat https://github.com/adafruit/SdFat
*/
#include "SPI.h"
#include "SdFat.h"
#include "SdFat_Adafruit_Fork.h"
#include "Adafruit_TinyUSB.h"
const int chipSelect = 10;
//--------------------------------------------------------------------+
// SDCard Config
//--------------------------------------------------------------------+
#if defined(ARDUINO_PYPORTAL_M4) || defined(ARDUINO_PYPORTAL_M4_TITANO)
// PyPortal has on-board card reader
#define SDCARD_CS 32
#define SDCARD_DETECT 33
#define SDCARD_DETECT_ACTIVE HIGH
#elif defined(ARDUINO_ADAFRUIT_METRO_RP2040)
#define SDIO_CLK_PIN 18
#define SDIO_CMD_PIN 19 // MOSI
#define SDIO_DAT0_PIN 20 // DAT1: 21, DAT2: 22, DAT3: 23
#define SDCARD_DETECT 15
#define SDCARD_DETECT_ACTIVE LOW
#elif defined(ARDUINO_ADAFRUIT_METRO_RP2350)
#define SDIO_CLK_PIN 34
#define SDIO_CMD_PIN 35 // MOSI
#define SDIO_DAT0_PIN 36 // DAT1: 37, DAT2: 38, DAT3: 39
#define SDCARD_DETECT 40
#define SDCARD_DETECT_ACTIVE LOW
#elif defined(ARDUINO_ADAFRUIT_FRUITJAM_RP2350)
#define SDIO_CLK_PIN 34
#define SDIO_CMD_PIN 35 // MOSI
#define SDIO_DAT0_PIN 36 // DAT1: 37, DAT2: 38, DAT3: 39
#define SDCARD_DETECT 33
#define SDCARD_DETECT_ACTIVE LOW
#else
// Use SPI, no detect
#define SDCARD_CS 10
#endif
#if defined(SDIO_CLK_PIN) && defined(SDIO_CMD_PIN) && defined(SDIO_DAT0_PIN)
#define SD_CONFIG SdioConfig(SDIO_CLK_PIN, SDIO_CMD_PIN, SDIO_DAT0_PIN)
#else
#define SD_CONFIG SdSpiConfig(SDCARD_CS, SHARED_SPI, SD_SCK_MHZ(50))
#endif
// File system on SD Card
SdFat sd;
SdFile root;
SdFile file;
// USB Mass Storage object
Adafruit_USBD_MSC usb_msc;
// Set to true when PC write to flash
bool fs_changed;
// the setup function runs once when you press reset or power the board
void setup()
{
void setup() {
#ifdef LED_BUILTIN
pinMode(LED_BUILTIN, OUTPUT);
#endif
Serial.begin(115200);
// Set disk vendor id, product id and revision with string up to 8, 16, 4 characters respectively
usb_msc.setID("Adafruit", "SD Card", "1.0");
@ -47,30 +85,27 @@ void setup()
usb_msc.setUnitReady(false);
usb_msc.begin();
Serial.begin(115200);
// If already enumerated, additional class driverr begin() e.g msc, hid, midi won't take effect until re-enumeration
if (TinyUSBDevice.mounted()) {
TinyUSBDevice.detach();
delay(10);
TinyUSBDevice.attach();
}
//while ( !Serial ) delay(10); // wait for native usb
Serial.println("Adafruit TinyUSB Mass Storage SD Card example");
Serial.print("\nInitializing SD card ... ");
Serial.print("CS = "); Serial.println(chipSelect);
if ( !sd.begin(chipSelect, SD_SCK_MHZ(50)) )
{
if (!sd.begin(SD_CONFIG)) {
Serial.println("initialization failed. Things to check:");
Serial.println("* is a card inserted?");
Serial.println("* is your wiring correct?");
Serial.println("* did you change the chipSelect pin to match your shield or module?");
Serial.println("- is a card inserted?");
Serial.println("- is your wiring correct?");
Serial.println("- did you change the SDCARD_CS or SDIO pin to match your shield or module?");
while (1) delay(1);
}
// Size in blocks (512 bytes)
#if SD_FAT_VERSION >= 20000
uint32_t block_count = sd.card()->sectorCount();
#else
uint32_t block_count = sd.card()->cardSize();
#endif
Serial.print("Volume size (MB): ");
Serial.println((block_count/2) / 1024);
@ -79,91 +114,38 @@ void setup()
// MSC is ready for read/write
usb_msc.setUnitReady(true);
fs_changed = true; // to print contents initially
}
void loop()
{
if ( fs_changed )
{
root.open("/");
Serial.println("SD contents:");
// Open next file in root.
// Warning, openNext starts at the current directory position
// so a rewind of the directory may be required.
while ( file.openNext(&root, O_RDONLY) )
{
file.printFileSize(&Serial);
Serial.write(' ');
file.printName(&Serial);
if ( file.isDir() )
{
// Indicate a directory.
Serial.write('/');
}
Serial.println();
file.close();
}
root.close();
Serial.println();
fs_changed = false;
delay(1000); // refresh every 0.5 second
}
void loop() {
// noting to do
}
// Callback invoked when received READ10 command.
// Copy disk's data to buffer (up to bufsize) and
// return number of copied bytes (must be multiple of block size)
int32_t msc_read_cb (uint32_t lba, void* buffer, uint32_t bufsize)
{
bool rc;
#if SD_FAT_VERSION >= 20000
rc = sd.card()->readSectors(lba, (uint8_t*) buffer, bufsize/512);
#else
rc = sd.card()->readBlocks(lba, (uint8_t*) buffer, bufsize/512);
#endif
int32_t msc_read_cb (uint32_t lba, void* buffer, uint32_t bufsize) {
bool rc = sd.card()->readSectors(lba, (uint8_t*) buffer, bufsize/512);
return rc ? bufsize : -1;
}
// Callback invoked when received WRITE10 command.
// Process data in buffer to disk's storage and
// return number of written bytes (must be multiple of block size)
int32_t msc_write_cb (uint32_t lba, uint8_t* buffer, uint32_t bufsize)
{
bool rc;
int32_t msc_write_cb (uint32_t lba, uint8_t* buffer, uint32_t bufsize) {
#ifdef LED_BUILTIN
digitalWrite(LED_BUILTIN, HIGH);
#if SD_FAT_VERSION >= 20000
rc = sd.card()->writeSectors(lba, buffer, bufsize/512);
#else
rc = sd.card()->writeBlocks(lba, buffer, bufsize/512);
#endif
bool rc = sd.card()->writeSectors(lba, buffer, bufsize/512);
return rc ? bufsize : -1;
}
// Callback invoked when WRITE10 command is completed (status received and accepted by host).
// used to flush any pending cache.
void msc_flush_cb (void)
{
#if SD_FAT_VERSION >= 20000
void msc_flush_cb (void) {
sd.card()->syncDevice();
#else
sd.card()->syncBlocks();
#endif
// clear file system's cache to force refresh
sd.cacheClear();
fs_changed = true;
sd.cacheClear(); // clear file system's cache to force refresh
#ifdef LED_BUILTIN
digitalWrite(LED_BUILTIN, LOW);
#endif
}

View file

@ -0,0 +1,3 @@
feather_esp32_v2
pico_rp2040_tinyusb_host
CH32V20x_EVT

View file

@ -64,15 +64,29 @@ Adafruit_USBD_I2C::Adafruit_USBD_I2C(TwoWire* wire) {
setStringDescriptor("I2C Interface");
}
uint16_t Adafruit_USBD_I2C::getInterfaceDescriptor(uint8_t itfnum, uint8_t* buf, uint16_t bufsize) {
uint8_t desc[] = { TUD_VENDOR_DESCRIPTOR(itfnum, 0, 0x00, 0x80, 64) };
uint16_t Adafruit_USBD_I2C::getInterfaceDescriptor(uint8_t itfnum_deprecated, uint8_t* buf, uint16_t bufsize) {
uint8_t itfnum = 0;
uint8_t ep_in = 0;
uint8_t ep_out = 0;
(void) itfnum_deprecated;
// null buffer is used to get the length of descriptor only
if (buf) {
itfnum = TinyUSBDevice.allocInterface(1);
ep_in = TinyUSBDevice.allocEndpoint(TUSB_DIR_IN);
ep_out = TinyUSBDevice.allocEndpoint(TUSB_DIR_OUT);
}
uint8_t const desc[] = { TUD_VENDOR_DESCRIPTOR(itfnum, _strid, ep_out, ep_in, 64) };
uint16_t const len = sizeof(desc);
if (buf) {
if (bufsize < len) {
return 0;
}
memcpy(buf, desc, len);
}
return len;
}

View file

@ -88,11 +88,13 @@
class Adafruit_USBD_I2C : public Adafruit_USBD_Interface {
public:
Adafruit_USBD_I2C(TwoWire* wire);
uint16_t getInterfaceDescriptor(uint8_t itfnum, uint8_t* buf, uint16_t bufsize);
bool begin(uint8_t* buffer, size_t bufsize);
bool handleControlTransfer(uint8_t rhport, uint8_t stage, tusb_control_request_t const* request);
// from Adafruit_USBD_Interface
virtual uint16_t getInterfaceDescriptor(uint8_t itfnum, uint8_t* buf, uint16_t bufsize);
private:
TwoWire* _wire;
uint8_t _state;

View file

@ -63,6 +63,13 @@ void setup() {
// init i2c usb with buffer and size
i2c_usb.begin(i2c_buf, sizeof(i2c_buf));
// If already enumerated, additional class driverr begin() e.g msc, hid, midi won't take effect until re-enumeration
if (TinyUSBDevice.mounted()) {
TinyUSBDevice.detach();
delay(10);
TinyUSBDevice.attach();
}
}
void loop() {

View file

@ -0,0 +1,3 @@
feather_esp32_v2
pico_rp2040_tinyusb_host
CH32V20x_EVT

View file

@ -0,0 +1,237 @@
/*********************************************************************
Adafruit invests time and resources providing this open source code,
please support Adafruit and open-source hardware by purchasing
products from Adafruit!
MIT license, check LICENSE for more information
Copyright (c) 2019 Ha Thach for Adafruit Industries
All text above, and the splash screen below must be included in
any redistribution
*********************************************************************/
#include "Adafruit_TinyUSB.h"
//--------------------------------------------------------------------+
// Video descriptors
//--------------------------------------------------------------------+
/* Time stamp base clock. It is a deprecated parameter. */
#define FRAME_WIDTH 128
#define FRAME_HEIGHT 96
#define FRAME_RATE 30
/* video capture path
*
* | Camera Terminal (0x01) | ----> | Output Terminal (0x02 Streaming) |
* */
#define TERMID_CAMERA 0x01
#define TERMID_OUTPUT 0x02
tusb_desc_video_control_camera_terminal_t const desc_camera_terminal = {
.bLength = sizeof(tusb_desc_video_control_camera_terminal_t),
.bDescriptorType = TUSB_DESC_CS_INTERFACE,
.bDescriptorSubType = VIDEO_CS_ITF_VC_INPUT_TERMINAL,
.bTerminalID = TERMID_CAMERA,
.wTerminalType = VIDEO_ITT_CAMERA,
.bAssocTerminal = 0,
.iTerminal = 0,
.wObjectiveFocalLengthMin = 0,
.wObjectiveFocalLengthMax = 0,
.wOcularFocalLength = 0,
.bControlSize = 3,
.bmControls = { 0, 0, 0 }
};
tusb_desc_video_control_output_terminal_t const desc_output_terminal = {
.bLength = sizeof(tusb_desc_video_control_output_terminal_t),
.bDescriptorType = TUSB_DESC_CS_INTERFACE,
.bDescriptorSubType = VIDEO_CS_ITF_VC_OUTPUT_TERMINAL,
.bTerminalID = TERMID_OUTPUT,
.wTerminalType = VIDEO_TT_STREAMING,
.bAssocTerminal = 0,
.bSourceID = TERMID_CAMERA,
.iTerminal = 0
};
tusb_desc_video_format_uncompressed_t const desc_format = {
.bLength = sizeof(tusb_desc_video_format_uncompressed_t),
.bDescriptorType = TUSB_DESC_CS_INTERFACE,
.bDescriptorSubType = VIDEO_CS_ITF_VS_FORMAT_UNCOMPRESSED,
.bFormatIndex = 1, // 1-based index
.bNumFrameDescriptors = 1,
.guidFormat = { TUD_VIDEO_GUID_YUY2 },
.bBitsPerPixel = 16,
.bDefaultFrameIndex = 1,
.bAspectRatioX = 0,
.bAspectRatioY = 0,
.bmInterlaceFlags = 0,
.bCopyProtect = 0
};
tusb_desc_video_frame_uncompressed_continuous_t desc_frame = {
.bLength = sizeof(tusb_desc_video_frame_uncompressed_continuous_t),
.bDescriptorType = TUSB_DESC_CS_INTERFACE,
.bDescriptorSubType = VIDEO_CS_ITF_VS_FRAME_UNCOMPRESSED,
.bFrameIndex = 1, // 1-based index
.bmCapabilities = 0,
.wWidth = FRAME_WIDTH,
.wHeight = FRAME_HEIGHT,
.dwMinBitRate = FRAME_WIDTH * FRAME_HEIGHT * 16 * 1,
.dwMaxBitRate = FRAME_WIDTH * FRAME_HEIGHT * 16 * FRAME_RATE,
.dwMaxVideoFrameBufferSize = FRAME_WIDTH * FRAME_HEIGHT * 16 / 8,
.dwDefaultFrameInterval = 10000000 / FRAME_RATE,
.bFrameIntervalType = 0, // continuous
.dwFrameInterval = {
10000000 / FRAME_RATE, // min
10000000, // max
10000000 / FRAME_RATE // step
}
};
tusb_desc_video_streaming_color_matching_t desc_color = {
.bLength = sizeof(tusb_desc_video_streaming_color_matching_t),
.bDescriptorType = TUSB_DESC_CS_INTERFACE,
.bDescriptorSubType = VIDEO_CS_ITF_VS_COLORFORMAT,
.bColorPrimaries = VIDEO_COLOR_PRIMARIES_BT709,
.bTransferCharacteristics = VIDEO_COLOR_XFER_CH_BT709,
.bMatrixCoefficients = VIDEO_COLOR_COEF_SMPTE170M
};
//--------------------------------------------------------------------+
// Video and frame buffer
//--------------------------------------------------------------------+
Adafruit_USBD_Video usb_video;
// YUY2 frame buffer
static uint8_t frame_buffer[FRAME_WIDTH * FRAME_HEIGHT * 16 / 8];
static unsigned frame_num = 0;
static unsigned tx_busy = 0;
static unsigned interval_ms = 1000 / FRAME_RATE;
static unsigned start_ms = 0;
static unsigned already_sent = 0;
//--------------------------------------------------------------------+
//
//--------------------------------------------------------------------+
static void fill_color_bar(uint8_t* buffer, unsigned start_position);
void setup() {
// Manual begin() is required on core without built-in support e.g. mbed rp2040
if (!TinyUSBDevice.isInitialized()) {
TinyUSBDevice.begin(0);
}
Serial.begin(115200);
usb_video.addTerminal(&desc_camera_terminal);
usb_video.addTerminal(&desc_output_terminal);
usb_video.addFormat(&desc_format);
usb_video.addFrame(&desc_frame);
usb_video.addColorMatching(&desc_color);
usb_video.begin();
// If already enumerated, additional class driverr begin() e.g msc, hid, midi won't take effect until re-enumeration
if (TinyUSBDevice.mounted()) {
TinyUSBDevice.detach();
delay(10);
TinyUSBDevice.attach();
}
}
void loop() {
#ifdef TINYUSB_NEED_POLLING_TASK
// Manual call tud_task since it isn't called by Core's background
TinyUSBDevice.task();
#endif
if (!tud_video_n_streaming(0, 0)) {
already_sent = 0;
frame_num = 0;
return;
}
if (!already_sent) {
already_sent = 1;
tx_busy = 1;
start_ms = millis();
fill_color_bar(frame_buffer, frame_num);
tud_video_n_frame_xfer(0, 0, (void*) frame_buffer, FRAME_WIDTH * FRAME_HEIGHT * 16 / 8);
}
unsigned cur = millis();
if (cur - start_ms < interval_ms) return; // not enough time
if (tx_busy) return;
start_ms += interval_ms;
tx_busy = 1;
fill_color_bar(frame_buffer, frame_num);
tud_video_n_frame_xfer(0, 0, (void*) frame_buffer, FRAME_WIDTH * FRAME_HEIGHT * 16 / 8);
}
//--------------------------------------------------------------------+
// TinyUSB Video Callbacks
//--------------------------------------------------------------------+
extern "C" {
void tud_video_frame_xfer_complete_cb(uint_fast8_t ctl_idx, uint_fast8_t stm_idx) {
(void) ctl_idx;
(void) stm_idx;
tx_busy = 0;
/* flip buffer */
++frame_num;
}
int tud_video_commit_cb(uint_fast8_t ctl_idx, uint_fast8_t stm_idx,
video_probe_and_commit_control_t const* parameters) {
(void) ctl_idx;
(void) stm_idx;
/* convert unit to ms from 100 ns */
interval_ms = parameters->dwFrameInterval / 10000;
return VIDEO_ERROR_NONE;
}
} // extern C
//------------- Helper -------------//
static void fill_color_bar(uint8_t* buffer, unsigned start_position) {
/* EBU color bars
* See also https://stackoverflow.com/questions/6939422 */
static uint8_t const bar_color[8][4] = {
/* Y, U, Y, V */
{ 235, 128, 235, 128}, /* 100% White */
{ 219, 16, 219, 138}, /* Yellow */
{ 188, 154, 188, 16}, /* Cyan */
{ 173, 42, 173, 26}, /* Green */
{ 78, 214, 78, 230}, /* Magenta */
{ 63, 102, 63, 240}, /* Red */
{ 32, 240, 32, 118}, /* Blue */
{ 16, 128, 16, 128}, /* Black */
};
uint8_t* p;
/* Generate the 1st line */
uint8_t* end = &buffer[FRAME_WIDTH * 2];
unsigned idx = (FRAME_WIDTH / 2 - 1) - (start_position % (FRAME_WIDTH / 2));
p = &buffer[idx * 4];
for (unsigned i = 0; i < 8; ++i) {
for (int j = 0; j < FRAME_WIDTH / (2 * 8); ++j) {
memcpy(p, &bar_color[i], 4);
p += 4;
if (end <= p) {
p = buffer;
}
}
}
/* Duplicate the 1st line to the others */
p = &buffer[FRAME_WIDTH * 2];
for (unsigned i = 1; i < FRAME_HEIGHT; ++i) {
memcpy(p, buffer, FRAME_WIDTH * 2);
p += FRAME_WIDTH * 2;
}
}

View file

@ -0,0 +1,4 @@
feather_esp32_v2
pico_rp2040_tinyusb_host
CH32V20x_EVT
# CH32V20x_EVT is not supported due to Adafruit_Neopixel

View file

@ -54,18 +54,25 @@ Adafruit_USBD_WebUSB usb_web;
WEBUSB_URL_DEF(landingPage, 1 /*https*/, "example.tinyusb.org/webusb-rgb/index.html");
// the setup function runs once when you press reset or power the board
void setup()
{
#if defined(ARDUINO_ARCH_MBED) && defined(ARDUINO_ARCH_RP2040)
// Manual begin() is required on core without built-in support for TinyUSB such as mbed rp2040
TinyUSB_Device_Init(0);
#endif
void setup() {
// Manual begin() is required on core without built-in support e.g. mbed rp2040
if (!TinyUSBDevice.isInitialized()) {
TinyUSBDevice.begin(0);
}
Serial.begin(115200);
//usb_web.setStringDescriptor("TinyUSB WebUSB");
usb_web.setLandingPage(&landingPage);
usb_web.setLineStateCallback(line_state_callback);
usb_web.begin();
Serial.begin(115200);
// If already enumerated, additional class driverr begin() e.g msc, hid, midi won't take effect until re-enumeration
if (TinyUSBDevice.mounted()) {
TinyUSBDevice.detach();
delay(10);
TinyUSBDevice.attach();
}
// This initializes the NeoPixel with RED
#ifdef NEOPIXEL_POWER
@ -79,21 +86,24 @@ void setup()
pixels.show();
// wait until device mounted
while( !TinyUSBDevice.mounted() ) delay(1);
while (!TinyUSBDevice.mounted()) delay(1);
Serial.println("TinyUSB WebUSB RGB example");
}
// convert a hex character to number
uint8_t char2num(char c)
{
uint8_t char2num(char c) {
if (c >= 'a') return c - 'a' + 10;
if (c >= 'A') return c - 'A' + 10;
return c - '0';
return c - '0';
}
void loop()
{
void loop() {
#ifdef TINYUSB_NEED_POLLING_TASK
// Manual call tud_task since it isn't called by Core's background
TinyUSBDevice.task();
#endif
// Landing Page 7 characters as hex color '#RRGGBB'
if (usb_web.available() < 7) return;
@ -104,17 +114,16 @@ void loop()
Serial.write(input, 7);
Serial.println();
uint8_t red = 16*char2num(input[1]) + char2num(input[2]);
uint8_t green = 16*char2num(input[3]) + char2num(input[4]);
uint8_t blue = 16*char2num(input[5]) + char2num(input[6]);
uint8_t red = 16 * char2num(input[1]) + char2num(input[2]);
uint8_t green = 16 * char2num(input[3]) + char2num(input[4]);
uint8_t blue = 16 * char2num(input[5]) + char2num(input[6]);
uint32_t color = (red << 16) | (green << 8) | blue;
pixels.fill(color);
pixels.show();
}
void line_state_callback(bool connected)
{
void line_state_callback(bool connected) {
// connected = green, disconnected = red
pixels.fill(connected ? 0x00ff00 : 0xff0000);
pixels.show();

View file

@ -0,0 +1,4 @@
feather_esp32_v2
pico_rp2040_tinyusb_host
CH32V20x_EVT
# CH32V20x_EVT is not supported due to lacking of HardwareSerial::read(uint8_t [64], int)

View file

@ -34,78 +34,81 @@ Adafruit_USBD_WebUSB usb_web;
// Page source can be found at https://github.com/hathach/tinyusb-webusb-page/tree/main/webusb-serial
WEBUSB_URL_DEF(landingPage, 1 /*https*/, "example.tinyusb.org/webusb-serial/index.html");
int led_pin = LED_BUILTIN;
// the setup function runs once when you press reset or power the board
void setup()
{
#if defined(ARDUINO_ARCH_MBED) && defined(ARDUINO_ARCH_RP2040)
// Manual begin() is required on core without built-in support for TinyUSB such as mbed rp2040
TinyUSB_Device_Init(0);
void setup() {
// Manual begin() is required on core without built-in support e.g. mbed rp2040
if (!TinyUSBDevice.isInitialized()) {
TinyUSBDevice.begin(0);
}
Serial.begin(115200);
#ifdef LED_BUILTIN
pinMode(LED_BUILTIN, OUTPUT);
digitalWrite(LED_BUILTIN, LOW);
#endif
pinMode(led_pin, OUTPUT);
digitalWrite(led_pin, LOW);
usb_web.setLandingPage(&landingPage);
usb_web.setLineStateCallback(line_state_callback);
//usb_web.setStringDescriptor("TinyUSB WebUSB");
usb_web.begin();
Serial.begin(115200);
// If already enumerated, additional class driverr begin() e.g msc, hid, midi won't take effect until re-enumeration
if (TinyUSBDevice.mounted()) {
TinyUSBDevice.detach();
delay(10);
TinyUSBDevice.attach();
}
// wait until device mounted
while( !TinyUSBDevice.mounted() ) delay(1);
while (!TinyUSBDevice.mounted()) delay(1);
Serial.println("TinyUSB WebUSB Serial example");
}
// function to echo to both Serial and WebUSB
void echo_all(uint8_t buf[], uint32_t count)
{
if (usb_web.connected())
{
void echo_all(uint8_t buf[], uint32_t count) {
if (usb_web.connected()) {
usb_web.write(buf, count);
usb_web.flush();
}
if ( Serial )
{
for(uint32_t i=0; i<count; i++)
{
if (Serial) {
for (uint32_t i = 0; i < count; i++) {
Serial.write(buf[i]);
if ( buf[i] == '\r' ) Serial.write('\n');
if (buf[i] == '\r') Serial.write('\n');
}
Serial.flush();
}
}
void loop()
{
void loop() {
#ifdef TINYUSB_NEED_POLLING_TASK
// Manual call tud_task since it isn't called by Core's background
TinyUSBDevice.task();
#endif
uint8_t buf[64];
uint32_t count;
// From Serial to both Serial & webUSB
if (Serial.available())
{
if (Serial.available()) {
count = Serial.read(buf, 64);
echo_all(buf, count);
}
// from WebUSB to both Serial & webUSB
if (usb_web.available())
{
if (usb_web.available()) {
count = usb_web.read(buf, 64);
echo_all(buf, count);
}
}
void line_state_callback(bool connected)
{
digitalWrite(led_pin, connected);
void line_state_callback(bool connected) {
#ifdef LED_BUILTIN
digitalWrite(LED_BUILTIN, connected);
#endif
if ( connected )
{
if (connected) {
usb_web.println("WebUSB interface connected !!");
usb_web.flush();
}

View file

@ -1,7 +1,22 @@
{
"name": "Adafruit TinyUSB Library",
"keywords": "usb, arduino, tinyusb",
"description": "Arduino library for TinyUSB",
"version": "3.7.1",
"repository": {
"type": "git",
"url": "https://github.com/adafruit/Adafruit_TinyUSB_Arduino.git"
},
"frameworks": "*",
"platforms": "*",
"build": {
"libArchive": false,
"flags": "-DUSE_TINYUSB"
}
"libArchive": false
},
"authors":
[
{
"name": "Adafruit",
"maintainer": true
}
]
}

View file

@ -1,9 +1,9 @@
name=Adafruit TinyUSB Library
version=2.2.8
version=3.7.1
author=Adafruit
maintainer=Adafruit <info@adafruit.com>
sentence=TinyUSB library for Arduino
paragraph=Support nRF5x, SAMD21, SAMD51, RP2040, ESP32-S2/S3
paragraph=Support nRF5x, SAMD21, SAMD51, RP2040, ESP32-S2/S3, CH32V
category=Communication
url=https://github.com/adafruit/Adafruit_TinyUSB_Arduino
architectures=*

View file

@ -25,18 +25,6 @@
#ifndef ADAFRUIT_TINYUSB_H_
#define ADAFRUIT_TINYUSB_H_
// Error message for Core that must select TinyUSB via menu
#if !defined(USE_TINYUSB) && \
(defined(ARDUINO_ARCH_SAMD) || \
(defined(ARDUINO_ARCH_RP2040) && !defined(ARDUINO_ARCH_MBED)))
#error TinyUSB is not selected, please select it in "Tools->Menu->USB Stack"
#endif
// ESP32 out-of-sync
#ifdef ARDUINO_ARCH_ESP32
#include "arduino/ports/esp32/tusb_config_esp32.h"
#endif
#include "tusb_option.h"
// Device
@ -64,6 +52,10 @@
#include "arduino/webusb/Adafruit_USBD_WebUSB.h"
#endif
#if CFG_TUD_VIDEO
#include "arduino/video/Adafruit_USBD_Video.h"
#endif
// Initialize device hardware, stack, also Serial as CDC
// Wrapper for TinyUSBDevice.begin(rhport)
void TinyUSB_Device_Init(uint8_t rhport);

View file

@ -24,17 +24,19 @@
#include "tusb_option.h"
// ESP32 will use the arduino-esp32 core initialization and Serial
#if CFG_TUD_ENABLED && !defined(ARDUINO_ARCH_ESP32)
#if CFG_TUD_ENABLED || CFG_TUH_ENABLED
#include "Adafruit_TinyUSB.h"
#include "Arduino.h"
//--------------------------------------------------------------------+
// MACRO TYPEDEF CONSTANT ENUM DECLARATION
//--------------------------------------------------------------------+
extern "C" {
uint32_t tusb_time_millis_api(void) { return millis(); }
//--------------------------------------------------------------------+
// Device
//--------------------------------------------------------------------+
#if CFG_TUD_ENABLED
void TinyUSB_Device_Init(uint8_t rhport) {
// Init USB Device controller and stack
TinyUSBDevice.begin(rhport);
@ -48,18 +50,24 @@ void TinyUSB_Device_Task(void) {
}
#endif
#ifndef ARDUINO_ARCH_ESP32
void TinyUSB_Device_FlushCDC(void) {
uint8_t const cdc_instance = Adafruit_USBD_CDC::getInstanceCount();
for (uint8_t instance = 0; instance < cdc_instance; instance++) {
tud_cdc_n_write_flush(instance);
}
}
#endif
#endif // CFG_TUD_ENABLED
// Debug log with Serial1
#if CFG_TUSB_DEBUG && defined(CFG_TUSB_DEBUG_PRINTF)
//------------- Debug log with Serial1 -------------//
#if CFG_TUSB_DEBUG && defined(CFG_TUSB_DEBUG_PRINTF) && \
!defined(ARDUINO_ARCH_ESP32)
// #define USE_SEGGER_RTT
#ifndef SERIAL_TUSB_DEBUG
#define SERIAL_TUSB_DEBUG Serial1
#endif
#ifdef USE_SEGGER_RTT
#include "SEGGER_RTT/RTT/SEGGER_RTT.h"
@ -88,8 +96,8 @@ __attribute__((used)) int CFG_TUSB_DEBUG_PRINTF(const char *__restrict format,
va_end(ap);
return len;
}
#endif
#endif // CFG_TUSB_DEBUG
} // extern C
#endif
#endif // CFG_TUD_ENABLED || CFG_TUH_ENABLED

View file

@ -30,7 +30,25 @@
// API Version, need to be updated when there is changes for
// TinyUSB_API, USBD_CDC, USBD_Device, USBD_Interface,
#define TINYUSB_API_VERSION 20000
#define TINYUSB_API_VERSION 30000
#if defined(ARDUINO_ARCH_SAMD) || defined(ARDUINO_NRF52_ADAFRUIT) || \
defined(ARDUINO_ARCH_ESP32) || defined(ARDUINO_ARCH_CH32) || \
(defined(ARDUINO_ARCH_RP2040) && !defined(ARDUINO_ARCH_MBED))
#define TINYUSB_HAS_BUITLTIN_CORE_SUPPORT
#endif
// Core that has built-in support: Adafruit SAMD, Adafruit nRF, rp2040, esp32
#if !defined(TINYUSB_HAS_BUITLTIN_CORE_SUPPORT)
#define TINYUSB_NEED_POLLING_TASK
#endif
// Error message for Core that must select TinyUSB via menu (built-in except
// esp32)
#if !defined(USE_TINYUSB) && (defined(TINYUSB_HAS_BUITLTIN_CORE_SUPPORT) && \
!defined(ARDUINO_ARCH_ESP32))
#error TinyUSB is not selected, please select it in "Tools->Menu->USB Stack"
#endif
//--------------------------------------------------------------------+
// Core API

View file

@ -46,21 +46,44 @@ Adafruit_USBD_CDC::Adafruit_USBD_CDC(void) { _instance = INVALID_INSTANCE; }
#if CFG_TUD_ENABLED
#define EPOUT 0x00
#define EPIN 0x80
uint16_t Adafruit_USBD_CDC::getInterfaceDescriptor(uint8_t itfnum, uint8_t *buf,
uint16_t Adafruit_USBD_CDC::getInterfaceDescriptor(uint8_t itfnum_deprecated,
uint8_t *buf,
uint16_t bufsize) {
// CDC is mostly always existed for DFU
// usb core will automatically update endpoint number
uint8_t desc[] = {TUD_CDC_DESCRIPTOR(itfnum, 0, EPIN, 8, EPOUT, EPIN, 64)};
uint16_t const len = sizeof(desc);
(void)itfnum_deprecated;
if (bufsize < len) {
return 0;
// CDC is mostly always existed for DFU
uint8_t itfnum = 0;
uint8_t ep_notif = 0;
uint8_t ep_in = 0;
uint8_t ep_out = 0;
if (buf) {
itfnum = TinyUSBDevice.allocInterface(2);
ep_notif = TinyUSBDevice.allocEndpoint(TUSB_DIR_IN);
ep_in = TinyUSBDevice.allocEndpoint(TUSB_DIR_IN);
ep_out = TinyUSBDevice.allocEndpoint(TUSB_DIR_OUT);
}
#if TINYUSB_API_VERSION < 20400
// backward compatible for core that include pre-2.4.0 TinyUSB
uint8_t _strid = 0;
#endif
uint16_t const mps =
(TUD_OPT_HIGH_SPEED ? 512 : 64); // TODO actual link speed
uint8_t const desc[] = {
TUD_CDC_DESCRIPTOR(itfnum, _strid, ep_notif, 8, ep_out, ep_in, mps)};
uint16_t const len = sizeof(desc);
// null buffer is used to get the length of descriptor only
if (buf) {
if (bufsize < len) {
return 0;
}
memcpy(buf, desc, len);
}
memcpy(buf, desc, len);
return len;
}
@ -266,11 +289,12 @@ void tud_cdc_line_state_cb(uint8_t instance, bool dtr, bool rts) {
#else
// Device stack is not enabled (probably in host mode)
#warning "NO_USB selected. No output to Serial will occur!"
#warning "TinyUSB Host selected. No output to Serial will occur!"
uint16_t Adafruit_USBD_CDC::getInterfaceDescriptor(uint8_t itfnum, uint8_t *buf,
uint16_t Adafruit_USBD_CDC::getInterfaceDescriptor(uint8_t itfnum_deprecated,
uint8_t *buf,
uint16_t bufsize) {
(void)itfnum;
(void)itfnum_deprecated;
(void)buf;
(void)bufsize;

View file

@ -33,6 +33,7 @@
// For ESP32 use USBCDC as it is compatible
#define Adafruit_USBD_CDC USBCDC
#define SerialTinyUSB Serial
#else
@ -45,10 +46,6 @@ public:
static uint8_t getInstanceCount(void) { return _instance_count; }
// from Adafruit_USBD_Interface
virtual uint16_t getInterfaceDescriptor(uint8_t itfnum, uint8_t *buf,
uint16_t bufsize);
void setPins(uint8_t pin_rx, uint8_t pin_tx) {
(void)pin_rx;
(void)pin_tx;
@ -83,6 +80,10 @@ public:
using Print::write; // pull in write(str) from Print
operator bool();
// from Adafruit_USBD_Interface
virtual uint16_t getInterfaceDescriptor(uint8_t itfnum_deprecated,
uint8_t *buf, uint16_t bufsize);
private:
enum { INVALID_INSTANCE = 0xffu };
static uint8_t _instance_count;
@ -92,16 +93,15 @@ private:
bool isValid(void) { return _instance != INVALID_INSTANCE; }
};
// "Serial" is used with TinyUSB CDC
#if defined(USE_TINYUSB)
extern Adafruit_USBD_CDC Serial;
extern Adafruit_USBD_CDC SerialTinyUSB;
// Built-in support "Serial" is assigned to TinyUSB CDC
// CH32 defines Serial as alias in WSerial.h
#if defined(USE_TINYUSB) && !defined(ARDUINO_ARCH_CH32)
#define SerialTinyUSB Serial
#endif
// Serial is probably used with HW Uart
#ifndef SerialTinyUSB
extern Adafruit_USBD_CDC SerialTinyUSB;
#endif
#endif // else of ESP32
#endif // __cplusplus

Some files were not shown because too many files have changed in this diff Show more