summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHaiMianBB <[email protected]>2022-10-11 15:34:06 +0800
committersakumisu <[email protected]>2022-10-11 20:55:39 +0800
commit84eb90e5c0528667a502495593caa77e5331ac47 (patch)
tree2e05c24269142f2cfd301444bffa86904b5025ad
parent9ab90c7ce4141231bd6520d6a7681d70320efbd3 (diff)
Add rp2040 usbd demo
-rw-r--r--demo/rp2040/cherryusb/CMakeLists.txt1
-rw-r--r--demo/rp2040/cherryusb/device/CMakeLists.txt46
-rw-r--r--demo/rp2040/cherryusb/device/cdc_acm/CMakeLists.txt13
-rw-r--r--demo/rp2040/cherryusb/device/cdc_acm/main.c29
-rw-r--r--demo/rp2040/cherryusb/device/cdc_msc/CMakeLists.txt13
-rw-r--r--demo/rp2040/cherryusb/device/cdc_msc/main.c29
-rw-r--r--demo/rp2040/cherryusb/device/cdc_multitude/CMakeLists.txt15
-rw-r--r--demo/rp2040/cherryusb/device/cdc_multitude/main.c26
-rw-r--r--demo/rp2040/cherryusb/device/dfu/CMakeLists.txt17
-rw-r--r--demo/rp2040/cherryusb/device/dfu/main.c57
-rw-r--r--demo/rp2040/cherryusb/device/hid_cdc_msc/CMakeLists.txt13
-rw-r--r--demo/rp2040/cherryusb/device/hid_cdc_msc/main.c27
-rw-r--r--demo/rp2040/cherryusb/device/hid_custom/CMakeLists.txt13
-rw-r--r--demo/rp2040/cherryusb/device/hid_custom/main.c29
-rw-r--r--demo/rp2040/cherryusb/device/hid_kbd/CMakeLists.txt13
-rw-r--r--demo/rp2040/cherryusb/device/hid_kbd/main.c33
-rw-r--r--demo/rp2040/cherryusb/device/hid_mouse/CMakeLists.txt13
-rw-r--r--demo/rp2040/cherryusb/device/hid_mouse/main.c33
-rw-r--r--demo/rp2040/cherryusb/device/msc_ram/CMakeLists.txt13
-rw-r--r--demo/rp2040/cherryusb/device/msc_ram/main.c27
-rw-r--r--demo/rp2040/cherryusb/device/uvc/CMakeLists.txt13
-rw-r--r--demo/rp2040/cherryusb/device/uvc/cherryusb_uvc_demo.c228
-rw-r--r--demo/rp2040/cherryusb/device/uvc/main.c33
-rw-r--r--demo/rp2040/cherryusb/usb_config.h156
24 files changed, 890 insertions, 0 deletions
diff --git a/demo/rp2040/cherryusb/CMakeLists.txt b/demo/rp2040/cherryusb/CMakeLists.txt
new file mode 100644
index 00000000..270650c7
--- /dev/null
+++ b/demo/rp2040/cherryusb/CMakeLists.txt
@@ -0,0 +1 @@
+add_subdirectory(device) \ No newline at end of file
diff --git a/demo/rp2040/cherryusb/device/CMakeLists.txt b/demo/rp2040/cherryusb/device/CMakeLists.txt
new file mode 100644
index 00000000..e56c2b55
--- /dev/null
+++ b/demo/rp2040/cherryusb/device/CMakeLists.txt
@@ -0,0 +1,46 @@
+include_directories(${CMAKE_CURRENT_LIST_DIR}
+ ${CMAKE_CURRENT_LIST_DIR}../../../../pico-sdk/lib/CherryUSB/class/audio
+ ${CMAKE_CURRENT_LIST_DIR}../../../../pico-sdk/lib/CherryUSB/class/cdc
+ ${CMAKE_CURRENT_LIST_DIR}../../../../pico-sdk/lib/CherryUSB/class/dfu
+ ${CMAKE_CURRENT_LIST_DIR}../../../../pico-sdk/lib/CherryUSB/class/hid
+ ${CMAKE_CURRENT_LIST_DIR}../../../../pico-sdk/lib/CherryUSB/class/hub
+ ${CMAKE_CURRENT_LIST_DIR}../../../../pico-sdk/lib/CherryUSB/class/midi
+ ${CMAKE_CURRENT_LIST_DIR}../../../../pico-sdk/lib/CherryUSB/class/msc
+ ${CMAKE_CURRENT_LIST_DIR}../../../../pico-sdk/lib/CherryUSB/class/mtp
+ ${CMAKE_CURRENT_LIST_DIR}../../../../pico-sdk/lib/CherryUSB/class/printer
+ ${CMAKE_CURRENT_LIST_DIR}../../../../pico-sdk/lib/CherryUSB/class/vendor
+ ${CMAKE_CURRENT_LIST_DIR}../../../../pico-sdk/lib/CherryUSB/class/video
+ ${CMAKE_CURRENT_LIST_DIR}../../../../pico-sdk/lib/CherryUSB/class/wireless
+
+ ${CMAKE_CURRENT_LIST_DIR}../../../../pico-sdk/lib/CherryUSB/common
+ ${CMAKE_CURRENT_LIST_DIR}../../../../pico-sdk/lib/CherryUSB/core
+ ${CMAKE_CURRENT_LIST_DIR}../../../../pico-sdk/lib/CherryUSB/demo
+ ${CMAKE_CURRENT_LIST_DIR}../../../../pico-sdk/lib/CherryUSB/port/rp2040
+ ${CMAKE_CURRENT_LIST_DIR}../../
+)
+
+
+add_library(cherryusblib STATIC)
+target_sources(cherryusblib PRIVATE ${CMAKE_CURRENT_LIST_DIR}../../../../pico-sdk/lib/CherryUSB/port/rp2040/usb_dc_rp2040.c)
+target_sources(cherryusblib PRIVATE ${CMAKE_CURRENT_LIST_DIR}../../../../pico-sdk/lib/CherryUSB/class/audio/usbd_audio.c)
+target_sources(cherryusblib PRIVATE ${CMAKE_CURRENT_LIST_DIR}../../../../pico-sdk/lib/CherryUSB/class/cdc/usbd_cdc.c)
+target_sources(cherryusblib PRIVATE ${CMAKE_CURRENT_LIST_DIR}../../../../pico-sdk/lib/CherryUSB/class/dfu/usbd_dfu.c)
+target_sources(cherryusblib PRIVATE ${CMAKE_CURRENT_LIST_DIR}../../../../pico-sdk/lib/CherryUSB/class/hid/usbd_hid.c)
+target_sources(cherryusblib PRIVATE ${CMAKE_CURRENT_LIST_DIR}../../../../pico-sdk/lib/CherryUSB/class/msc/usbd_msc.c)
+# target_sources(cherryusblib PRIVATE ${CMAKE_CURRENT_LIST_DIR}../../../../pico-sdk/lib/CherryUSB/class/mtp/usbd_mtp.c)
+target_sources(cherryusblib PRIVATE ${CMAKE_CURRENT_LIST_DIR}../../../../pico-sdk/lib/CherryUSB/class/printer/usbd_printer.c)
+target_sources(cherryusblib PRIVATE ${CMAKE_CURRENT_LIST_DIR}../../../../pico-sdk/lib/CherryUSB/class/video/usbd_video.c)
+# target_sources(cherryusblib PRIVATE ${CMAKE_CURRENT_LIST_DIR}../../../../pico-sdk/lib/CherryUSB/class/wireless/usbd_rndis.c)
+target_sources(cherryusblib PRIVATE ${CMAKE_CURRENT_LIST_DIR}../../../../pico-sdk/lib/CherryUSB/core/usbd_core.c)
+
+add_subdirectory(cdc_acm)
+add_subdirectory(cdc_msc)
+add_subdirectory(cdc_multitude)
+add_subdirectory(dfu)
+add_subdirectory(hid_cdc_msc)
+add_subdirectory(hid_custom)
+add_subdirectory(hid_kbd)
+add_subdirectory(hid_mouse)
+add_subdirectory(msc_ram)
+add_subdirectory(uvc)
+
diff --git a/demo/rp2040/cherryusb/device/cdc_acm/CMakeLists.txt b/demo/rp2040/cherryusb/device/cdc_acm/CMakeLists.txt
new file mode 100644
index 00000000..9cc159e9
--- /dev/null
+++ b/demo/rp2040/cherryusb/device/cdc_acm/CMakeLists.txt
@@ -0,0 +1,13 @@
+get_filename_component(project_name ${CMAKE_CURRENT_LIST_DIR} NAME)
+
+add_executable(${project_name}
+main.c
+)
+
+# pull in common dependencies
+target_link_libraries(${project_name} PRIVATE pico_stdlib cherryusblib hardware_resets hardware_irq)
+# create map/bin/hex file etc.
+pico_add_extra_outputs(${project_name})
+
+# add url via pico_set_program_url
+example_auto_set_url(${project_name}) \ No newline at end of file
diff --git a/demo/rp2040/cherryusb/device/cdc_acm/main.c b/demo/rp2040/cherryusb/device/cdc_acm/main.c
new file mode 100644
index 00000000..827991e2
--- /dev/null
+++ b/demo/rp2040/cherryusb/device/cdc_acm/main.c
@@ -0,0 +1,29 @@
+#include "pico/stdlib.h"
+#include "pico/time.h"
+#include "usbd_core.h"
+#include <stdio.h>
+#include <string.h>
+
+/**
+ *
+ */
+#include "cdc_acm_template.c"
+
+int main(void) {
+ stdio_init_all();
+ printf("CherryUSB device cdc acm example\n");
+ extern void cdc_acm_init(void);
+ cdc_acm_init();
+
+ // Wait until configured
+ while (!usb_device_is_configured()) {
+ tight_loop_contents();
+ }
+
+ // Everything is interrupt driven so just loop here
+ while (1) {
+ extern void cdc_acm_data_send_with_dtr_test(void);
+ cdc_acm_data_send_with_dtr_test();
+ }
+ return 0;
+}
diff --git a/demo/rp2040/cherryusb/device/cdc_msc/CMakeLists.txt b/demo/rp2040/cherryusb/device/cdc_msc/CMakeLists.txt
new file mode 100644
index 00000000..9cc159e9
--- /dev/null
+++ b/demo/rp2040/cherryusb/device/cdc_msc/CMakeLists.txt
@@ -0,0 +1,13 @@
+get_filename_component(project_name ${CMAKE_CURRENT_LIST_DIR} NAME)
+
+add_executable(${project_name}
+main.c
+)
+
+# pull in common dependencies
+target_link_libraries(${project_name} PRIVATE pico_stdlib cherryusblib hardware_resets hardware_irq)
+# create map/bin/hex file etc.
+pico_add_extra_outputs(${project_name})
+
+# add url via pico_set_program_url
+example_auto_set_url(${project_name}) \ No newline at end of file
diff --git a/demo/rp2040/cherryusb/device/cdc_msc/main.c b/demo/rp2040/cherryusb/device/cdc_msc/main.c
new file mode 100644
index 00000000..b316e8b3
--- /dev/null
+++ b/demo/rp2040/cherryusb/device/cdc_msc/main.c
@@ -0,0 +1,29 @@
+#include "pico/stdlib.h"
+#include "pico/time.h"
+#include "usbd_core.h"
+#include <stdio.h>
+#include <string.h>
+
+/**
+ *
+ */
+#include "cdc_acm_msc_template.c"
+
+int main(void) {
+ stdio_init_all();
+ printf("CherryUSB device cdc msc example\n");
+ extern void cdc_acm_msc_init(void);
+ cdc_acm_msc_init();
+
+ // Wait until configured
+ while (!usb_device_is_configured()) {
+ tight_loop_contents();
+ }
+
+ // Everything is interrupt driven so just loop here
+ while (1) {
+ extern void cdc_acm_data_send_with_dtr_test(void);
+ cdc_acm_data_send_with_dtr_test();
+ }
+ return 0;
+}
diff --git a/demo/rp2040/cherryusb/device/cdc_multitude/CMakeLists.txt b/demo/rp2040/cherryusb/device/cdc_multitude/CMakeLists.txt
new file mode 100644
index 00000000..a512d138
--- /dev/null
+++ b/demo/rp2040/cherryusb/device/cdc_multitude/CMakeLists.txt
@@ -0,0 +1,15 @@
+get_filename_component(project_name ${CMAKE_CURRENT_LIST_DIR} NAME)
+
+add_executable(${project_name}
+main.c
+)
+
+# pull in common dependencies
+target_link_libraries(${project_name} PRIVATE pico_stdlib cherryusblib hardware_resets hardware_irq)
+
+
+# create map/bin/hex file etc.
+pico_add_extra_outputs(${project_name})
+
+# add url via pico_set_program_url
+example_auto_set_url(${project_name}) \ No newline at end of file
diff --git a/demo/rp2040/cherryusb/device/cdc_multitude/main.c b/demo/rp2040/cherryusb/device/cdc_multitude/main.c
new file mode 100644
index 00000000..3a3d9f6a
--- /dev/null
+++ b/demo/rp2040/cherryusb/device/cdc_multitude/main.c
@@ -0,0 +1,26 @@
+#include "pico/stdlib.h"
+#include "usbd_core.h"
+#include <stdio.h>
+#include <string.h>
+
+/**
+ *
+ */
+#include "cdc_acm_multi_template.c"
+
+int main(void) {
+ stdio_init_all();
+ printf("CherryUSB device cdc acm multitude example\n");
+ extern void cdc_acm_multi_init(void);
+ cdc_acm_multi_init();
+
+ // Wait until configured
+ while (!usb_device_is_configured()) {
+ tight_loop_contents();
+ }
+
+ // Everything is interrupt driven so just loop here
+ while (1) {
+ }
+ return 0;
+}
diff --git a/demo/rp2040/cherryusb/device/dfu/CMakeLists.txt b/demo/rp2040/cherryusb/device/dfu/CMakeLists.txt
new file mode 100644
index 00000000..d08fdde0
--- /dev/null
+++ b/demo/rp2040/cherryusb/device/dfu/CMakeLists.txt
@@ -0,0 +1,17 @@
+get_filename_component(project_name ${CMAKE_CURRENT_LIST_DIR} NAME)
+
+add_executable(${project_name}
+main.c
+)
+
+# pull in common dependencies
+target_link_libraries(${project_name} PRIVATE pico_stdlib cherryusblib hardware_resets hardware_irq)
+
+target_compile_definitions(cherryusblib INTERFACE -DUSBD_DFU_XFER_SIZE=1024)
+target_compile_definitions(cherryusblib INTERFACE -DCONFIG_USBDEV_REQUEST_BUFFER_LEN=1024)
+
+# create map/bin/hex file etc.
+pico_add_extra_outputs(${project_name})
+
+# add url via pico_set_program_url
+example_auto_set_url(${project_name}) \ No newline at end of file
diff --git a/demo/rp2040/cherryusb/device/dfu/main.c b/demo/rp2040/cherryusb/device/dfu/main.c
new file mode 100644
index 00000000..05794752
--- /dev/null
+++ b/demo/rp2040/cherryusb/device/dfu/main.c
@@ -0,0 +1,57 @@
+#include "pico/stdlib.h"
+#include "usbd_core.h"
+#include <stdio.h>
+#include <string.h>
+
+/**
+ *
+ */
+#include "dfu_with_st_tool_template.c"
+
+uint8_t *dfu_read_flash(uint8_t *src, uint8_t *dest, uint32_t len) {
+ uint32_t i = 0;
+ uint8_t *psrc = src;
+
+ for (i = 0; i < len; i++) {
+ dest[i] = *psrc++;
+ }
+ /* Return a valid address to avoid HardFault */
+ return (uint8_t *)(dest);
+}
+
+uint16_t dfu_write_flash(uint8_t *src, uint8_t *dest, uint32_t len) {
+ printf("dfu write flash -- src_add:%08x -- dest_add:%08x -- len:%d\r\n", src,
+ dest, len);
+
+ return 0;
+}
+
+uint16_t dfu_erase_flash(uint32_t add) {
+ /**
+ * The length of erasure needs to be consistent with USBD_DFU_XFER_SIZE equal
+ * If you want to modify USBD_DFU_XFER_SIZE, please pay attention to the
+ * CONFIG_USBDEV_REQUEST_BUFFER_LEN in the usb_config.h file
+ * CONFIG_USBDEV_REQUEST_BUFFER_LEN need >= USBD_DFU_XFER_SIZE
+ */
+ printf("dfu erase flash start add:%08x\r\n", add);
+ return 0;
+}
+
+void dfu_leave(void) { printf("dfu leave\r\n"); }
+
+int main(void) {
+ stdio_init_all();
+ printf("CherryUSB device dfu example\n");
+ extern void dfu_flash_init(void);
+ dfu_flash_init();
+
+ // Wait until configured
+ while (!usb_device_is_configured()) {
+ tight_loop_contents();
+ }
+
+ // Everything is interrupt driven so just loop here
+ while (1) {
+ }
+ return 0;
+}
diff --git a/demo/rp2040/cherryusb/device/hid_cdc_msc/CMakeLists.txt b/demo/rp2040/cherryusb/device/hid_cdc_msc/CMakeLists.txt
new file mode 100644
index 00000000..9cc159e9
--- /dev/null
+++ b/demo/rp2040/cherryusb/device/hid_cdc_msc/CMakeLists.txt
@@ -0,0 +1,13 @@
+get_filename_component(project_name ${CMAKE_CURRENT_LIST_DIR} NAME)
+
+add_executable(${project_name}
+main.c
+)
+
+# pull in common dependencies
+target_link_libraries(${project_name} PRIVATE pico_stdlib cherryusblib hardware_resets hardware_irq)
+# create map/bin/hex file etc.
+pico_add_extra_outputs(${project_name})
+
+# add url via pico_set_program_url
+example_auto_set_url(${project_name}) \ No newline at end of file
diff --git a/demo/rp2040/cherryusb/device/hid_cdc_msc/main.c b/demo/rp2040/cherryusb/device/hid_cdc_msc/main.c
new file mode 100644
index 00000000..3ca6f175
--- /dev/null
+++ b/demo/rp2040/cherryusb/device/hid_cdc_msc/main.c
@@ -0,0 +1,27 @@
+#include "pico/stdlib.h"
+#include "pico/time.h"
+#include "usbd_core.h"
+#include <stdio.h>
+#include <string.h>
+
+/**
+ *
+ */
+#include "cdc_acm_hid_msc_template.c"
+
+int main(void) {
+ stdio_init_all();
+ printf("CherryUSB device hid cdc msc composite example\n");
+ extern void cdc_acm_hid_msc_descriptor_init(void);
+ cdc_acm_hid_msc_descriptor_init();
+
+ // Wait until configured
+ while (!usb_device_is_configured()) {
+ tight_loop_contents();
+ }
+
+ // Everything is interrupt driven so just loop here
+ while (1) {
+ }
+ return 0;
+}
diff --git a/demo/rp2040/cherryusb/device/hid_custom/CMakeLists.txt b/demo/rp2040/cherryusb/device/hid_custom/CMakeLists.txt
new file mode 100644
index 00000000..9cc159e9
--- /dev/null
+++ b/demo/rp2040/cherryusb/device/hid_custom/CMakeLists.txt
@@ -0,0 +1,13 @@
+get_filename_component(project_name ${CMAKE_CURRENT_LIST_DIR} NAME)
+
+add_executable(${project_name}
+main.c
+)
+
+# pull in common dependencies
+target_link_libraries(${project_name} PRIVATE pico_stdlib cherryusblib hardware_resets hardware_irq)
+# create map/bin/hex file etc.
+pico_add_extra_outputs(${project_name})
+
+# add url via pico_set_program_url
+example_auto_set_url(${project_name}) \ No newline at end of file
diff --git a/demo/rp2040/cherryusb/device/hid_custom/main.c b/demo/rp2040/cherryusb/device/hid_custom/main.c
new file mode 100644
index 00000000..ccb366c0
--- /dev/null
+++ b/demo/rp2040/cherryusb/device/hid_custom/main.c
@@ -0,0 +1,29 @@
+#include "pico/stdlib.h"
+#include "pico/time.h"
+#include "usbd_core.h"
+#include <stdio.h>
+#include <string.h>
+
+/**
+ *
+ */
+#include "hid_custom_inout_template.c"
+
+int main(void) {
+ stdio_init_all();
+ printf("CherryUSB device hid custom example\n");
+ extern void hid_custom_keyboard_init(void);
+ hid_custom_keyboard_init();
+
+ // Wait until configured
+ while (!usb_device_is_configured()) {
+ tight_loop_contents();
+ }
+
+ // Everything is interrupt driven so just loop here
+ while (1) {
+ extern void hid_custom_test(void);
+ hid_custom_test();
+ }
+ return 0;
+}
diff --git a/demo/rp2040/cherryusb/device/hid_kbd/CMakeLists.txt b/demo/rp2040/cherryusb/device/hid_kbd/CMakeLists.txt
new file mode 100644
index 00000000..9cc159e9
--- /dev/null
+++ b/demo/rp2040/cherryusb/device/hid_kbd/CMakeLists.txt
@@ -0,0 +1,13 @@
+get_filename_component(project_name ${CMAKE_CURRENT_LIST_DIR} NAME)
+
+add_executable(${project_name}
+main.c
+)
+
+# pull in common dependencies
+target_link_libraries(${project_name} PRIVATE pico_stdlib cherryusblib hardware_resets hardware_irq)
+# create map/bin/hex file etc.
+pico_add_extra_outputs(${project_name})
+
+# add url via pico_set_program_url
+example_auto_set_url(${project_name}) \ No newline at end of file
diff --git a/demo/rp2040/cherryusb/device/hid_kbd/main.c b/demo/rp2040/cherryusb/device/hid_kbd/main.c
new file mode 100644
index 00000000..9cbfeda2
--- /dev/null
+++ b/demo/rp2040/cherryusb/device/hid_kbd/main.c
@@ -0,0 +1,33 @@
+#include "pico/stdlib.h"
+#include "pico/time.h"
+#include "usbd_core.h"
+#include <stdio.h>
+#include <string.h>
+
+/**
+ *
+ */
+#include "hid_keyboard_template.c"
+
+int main(void) {
+ stdio_init_all();
+ printf("CherryUSB device hid keyboard example\n");
+ extern void hid_keyboard_init(void);
+ hid_keyboard_init();
+
+ // Wait until configured
+ while (!usb_device_is_configured()) {
+ tight_loop_contents();
+ }
+
+ // Everything is interrupt driven so just loop here
+ while (1) {
+ extern void hid_keyboard_test(void);
+ hid_keyboard_test();
+ sleep_ms(1);
+ uint8_t sendbuffer[8] = {0};
+ usbd_ep_start_write(HID_INT_EP, sendbuffer, 8);
+ sleep_ms(2000);
+ }
+ return 0;
+}
diff --git a/demo/rp2040/cherryusb/device/hid_mouse/CMakeLists.txt b/demo/rp2040/cherryusb/device/hid_mouse/CMakeLists.txt
new file mode 100644
index 00000000..9cc159e9
--- /dev/null
+++ b/demo/rp2040/cherryusb/device/hid_mouse/CMakeLists.txt
@@ -0,0 +1,13 @@
+get_filename_component(project_name ${CMAKE_CURRENT_LIST_DIR} NAME)
+
+add_executable(${project_name}
+main.c
+)
+
+# pull in common dependencies
+target_link_libraries(${project_name} PRIVATE pico_stdlib cherryusblib hardware_resets hardware_irq)
+# create map/bin/hex file etc.
+pico_add_extra_outputs(${project_name})
+
+# add url via pico_set_program_url
+example_auto_set_url(${project_name}) \ No newline at end of file
diff --git a/demo/rp2040/cherryusb/device/hid_mouse/main.c b/demo/rp2040/cherryusb/device/hid_mouse/main.c
new file mode 100644
index 00000000..66c99428
--- /dev/null
+++ b/demo/rp2040/cherryusb/device/hid_mouse/main.c
@@ -0,0 +1,33 @@
+#include "pico/stdlib.h"
+#include "pico/time.h"
+#include "usbd_core.h"
+#include <stdio.h>
+#include <string.h>
+
+/**
+ *
+ */
+#include "hid_mouse_template.c"
+
+int main(void) {
+ stdio_init_all();
+ printf("CherryUSB device hid mouse example\n");
+ extern void hid_mouse_init(void);
+ hid_mouse_init();
+
+ // Wait until configured
+ while (!usb_device_is_configured()) {
+ tight_loop_contents();
+ }
+
+ // Everything is interrupt driven so just loop here
+ while (1) {
+ extern void hid_mouse_test(void);
+ hid_mouse_test();
+ sleep_ms(1);
+ uint8_t zero_data[4] = {0};
+ usbd_ep_start_write(HID_INT_EP, zero_data, 4);
+ sleep_ms(2000);
+ }
+ return 0;
+}
diff --git a/demo/rp2040/cherryusb/device/msc_ram/CMakeLists.txt b/demo/rp2040/cherryusb/device/msc_ram/CMakeLists.txt
new file mode 100644
index 00000000..9cc159e9
--- /dev/null
+++ b/demo/rp2040/cherryusb/device/msc_ram/CMakeLists.txt
@@ -0,0 +1,13 @@
+get_filename_component(project_name ${CMAKE_CURRENT_LIST_DIR} NAME)
+
+add_executable(${project_name}
+main.c
+)
+
+# pull in common dependencies
+target_link_libraries(${project_name} PRIVATE pico_stdlib cherryusblib hardware_resets hardware_irq)
+# create map/bin/hex file etc.
+pico_add_extra_outputs(${project_name})
+
+# add url via pico_set_program_url
+example_auto_set_url(${project_name}) \ No newline at end of file
diff --git a/demo/rp2040/cherryusb/device/msc_ram/main.c b/demo/rp2040/cherryusb/device/msc_ram/main.c
new file mode 100644
index 00000000..6477f457
--- /dev/null
+++ b/demo/rp2040/cherryusb/device/msc_ram/main.c
@@ -0,0 +1,27 @@
+#include "pico/stdlib.h"
+#include "pico/time.h"
+#include "usbd_core.h"
+#include <stdio.h>
+#include <string.h>
+
+/**
+ *
+ */
+#include "msc_ram_template.c"
+
+int main(void) {
+ stdio_init_all();
+ printf("CherryUSB device msc ram example\n");
+ extern void msc_ram_init(void);
+ msc_ram_init();
+
+ // Wait until configured
+ while (!usb_device_is_configured()) {
+ tight_loop_contents();
+ }
+
+ // Everything is interrupt driven so just loop here
+ while (1) {
+ }
+ return 0;
+}
diff --git a/demo/rp2040/cherryusb/device/uvc/CMakeLists.txt b/demo/rp2040/cherryusb/device/uvc/CMakeLists.txt
new file mode 100644
index 00000000..9cc159e9
--- /dev/null
+++ b/demo/rp2040/cherryusb/device/uvc/CMakeLists.txt
@@ -0,0 +1,13 @@
+get_filename_component(project_name ${CMAKE_CURRENT_LIST_DIR} NAME)
+
+add_executable(${project_name}
+main.c
+)
+
+# pull in common dependencies
+target_link_libraries(${project_name} PRIVATE pico_stdlib cherryusblib hardware_resets hardware_irq)
+# create map/bin/hex file etc.
+pico_add_extra_outputs(${project_name})
+
+# add url via pico_set_program_url
+example_auto_set_url(${project_name}) \ No newline at end of file
diff --git a/demo/rp2040/cherryusb/device/uvc/cherryusb_uvc_demo.c b/demo/rp2040/cherryusb/device/uvc/cherryusb_uvc_demo.c
new file mode 100644
index 00000000..022cd949
--- /dev/null
+++ b/demo/rp2040/cherryusb/device/uvc/cherryusb_uvc_demo.c
@@ -0,0 +1,228 @@
+#include "usbd_core.h"
+#include "usbd_video.h"
+#include "pic_data.h"
+
+#define VIDEO_IN_EP 0x81
+
+#ifdef CONFIG_USB_HS
+#define MAX_PAYLOAD_SIZE 1024 // for high speed with one transcations every one micro frame
+#define VIDEO_PACKET_SIZE (unsigned int)(((MAX_PAYLOAD_SIZE / 1)) | (0x00 << 11))
+
+// #define MAX_PAYLOAD_SIZE 2048 // for high speed with two transcations every one micro frame
+// #define VIDEO_PACKET_SIZE (unsigned int)(((MAX_PAYLOAD_SIZE / 2)) | (0x01 << 11))
+
+// #define MAX_PAYLOAD_SIZE 3072 // for high speed with three transcations every one micro frame
+// #define VIDEO_PACKET_SIZE (unsigned int)(((MAX_PAYLOAD_SIZE / 3)) | (0x02 << 11))
+
+#else
+#define MAX_PAYLOAD_SIZE 1023
+#define VIDEO_PACKET_SIZE (unsigned int)(((MAX_PAYLOAD_SIZE / 1)) | (0x00 << 11))
+#endif
+
+#define WIDTH (unsigned int)(640)
+#define HEIGHT (unsigned int)(480)
+
+#define CAM_FPS (30)
+#define INTERVAL (unsigned long)(10000000 / CAM_FPS)
+#define MIN_BIT_RATE (unsigned long)(WIDTH * HEIGHT * 16 * CAM_FPS) //16 bit
+#define MAX_BIT_RATE (unsigned long)(WIDTH * HEIGHT * 16 * CAM_FPS)
+#define MAX_FRAME_SIZE (unsigned long)(WIDTH * HEIGHT * 2)
+
+#define USB_VIDEO_DESC_SIZ (unsigned long)(9 + \
+ 8 + \
+ 9 + \
+ 13 + \
+ 18 + \
+ 9 + \
+ 12 + \
+ 9 + \
+ 14 + \
+ 11 + \
+ 38 + \
+ 9 + \
+ 7)
+
+#define VC_TERMINAL_SIZ (unsigned int)(13 + 18 + 12 + 9)
+#define VS_HEADER_SIZ (unsigned int)(13 + 1 + 11 + 38)
+
+#define USBD_VID 0xffff
+#define USBD_PID 0xffff
+#define USBD_MAX_POWER 100
+#define USBD_LANGID_STRING 1033
+
+const uint8_t video_descriptor[] = {
+ USB_DEVICE_DESCRIPTOR_INIT(USB_2_0, 0x00, 0x00, 0x00, USBD_VID, USBD_PID, 0x0001, 0x01),
+ USB_CONFIG_DESCRIPTOR_INIT(USB_VIDEO_DESC_SIZ, 0x02, 0x01, USB_CONFIG_BUS_POWERED, USBD_MAX_POWER),
+ VIDEO_VC_DESCRIPTOR_INIT(0x00, 0, 0x0100, VC_TERMINAL_SIZ, 48000000, 0x02),
+ VIDEO_VS_DESCRIPTOR_INIT(0x01, 0x00, 0x00),
+ VIDEO_VS_HEADER_DESCRIPTOR_INIT(0x01, VS_HEADER_SIZ, VIDEO_IN_EP, 1, 0x00),
+ VIDEO_VS_FORMAT_MJPEG_DESCRIPTOR_INIT(0x01, 0x01),
+ VIDEO_VS_FRAME_MJPEG_DESCRIPTOR_INIT(0x01, WIDTH, HEIGHT, MIN_BIT_RATE, MAX_BIT_RATE, MAX_FRAME_SIZE, INTERVAL, 0x00, DBVAL(INTERVAL), DBVAL(INTERVAL), DBVAL(0)),
+ VIDEO_VS_DESCRIPTOR_INIT(0x01, 0x01, 0x01),
+ /* 1.2.2.2 Standard VideoStream Isochronous Video Data Endpoint Descriptor */
+ 0x07, /* bLength */
+ USB_DESCRIPTOR_TYPE_ENDPOINT, /* bDescriptorType: ENDPOINT */
+ 0x81, /* bEndpointAddress: IN endpoint 2 */
+ 0x01, /* bmAttributes: Isochronous transfer type. Asynchronous synchronization type. */
+ WBVAL(VIDEO_PACKET_SIZE), /* wMaxPacketSize */
+ 0x01, /* bInterval: One frame interval */
+
+ ///////////////////////////////////////
+ /// string0 descriptor
+ ///////////////////////////////////////
+ USB_LANGID_INIT(USBD_LANGID_STRING),
+ ///////////////////////////////////////
+ /// string1 descriptor
+ ///////////////////////////////////////
+ 0x14, /* bLength */
+ USB_DESCRIPTOR_TYPE_STRING, /* bDescriptorType */
+ 'C', 0x00, /* wcChar0 */
+ 'h', 0x00, /* wcChar1 */
+ 'e', 0x00, /* wcChar2 */
+ 'r', 0x00, /* wcChar3 */
+ 'r', 0x00, /* wcChar4 */
+ 'y', 0x00, /* wcChar5 */
+ 'U', 0x00, /* wcChar6 */
+ 'S', 0x00, /* wcChar7 */
+ 'B', 0x00, /* wcChar8 */
+ ///////////////////////////////////////
+ /// string2 descriptor
+ ///////////////////////////////////////
+ 0x26, /* bLength */
+ USB_DESCRIPTOR_TYPE_STRING, /* bDescriptorType */
+ 'C', 0x00, /* wcChar0 */
+ 'h', 0x00, /* wcChar1 */
+ 'e', 0x00, /* wcChar2 */
+ 'r', 0x00, /* wcChar3 */
+ 'r', 0x00, /* wcChar4 */
+ 'y', 0x00, /* wcChar5 */
+ 'U', 0x00, /* wcChar6 */
+ 'S', 0x00, /* wcChar7 */
+ 'B', 0x00, /* wcChar8 */
+ ' ', 0x00, /* wcChar9 */
+ 'U', 0x00, /* wcChar10 */
+ 'V', 0x00, /* wcChar11 */
+ 'C', 0x00, /* wcChar12 */
+ ' ', 0x00, /* wcChar13 */
+ 'D', 0x00, /* wcChar14 */
+ 'E', 0x00, /* wcChar15 */
+ 'M', 0x00, /* wcChar16 */
+ 'O', 0x00, /* wcChar17 */
+ ///////////////////////////////////////
+ /// string3 descriptor
+ ///////////////////////////////////////
+ 0x16, /* bLength */
+ USB_DESCRIPTOR_TYPE_STRING, /* bDescriptorType */
+ '2', 0x00, /* wcChar0 */
+ '0', 0x00, /* wcChar1 */
+ '2', 0x00, /* wcChar2 */
+ '1', 0x00, /* wcChar3 */
+ '0', 0x00, /* wcChar4 */
+ '3', 0x00, /* wcChar5 */
+ '1', 0x00, /* wcChar6 */
+ '0', 0x00, /* wcChar7 */
+ '0', 0x00, /* wcChar8 */
+ '0', 0x00, /* wcChar9 */
+#ifdef CONFIG_USB_HS
+ ///////////////////////////////////////
+ /// device qualifier descriptor
+ ///////////////////////////////////////
+ 0x0a,
+ USB_DESCRIPTOR_TYPE_DEVICE_QUALIFIER,
+ 0x00,
+ 0x02,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x40,
+ 0x01,
+ 0x00,
+#endif
+ 0x00
+};
+
+void usbd_configure_done_callback(void)
+{
+ /* no out ep, so do nothing */
+}
+
+volatile bool tx_flag = 0;
+volatile bool iso_tx_busy = false;
+
+void usbd_video_open(uint8_t intf)
+{
+ tx_flag = 1;
+ iso_tx_busy = false;
+}
+void usbd_video_close(uint8_t intf)
+{
+ tx_flag = 0;
+}
+
+void usbd_video_iso_callback(uint8_t ep, uint32_t nbytes)
+{
+ iso_tx_busy = false;
+}
+
+static struct usbd_endpoint video_in_ep = {
+ .ep_cb = usbd_video_iso_callback,
+ .ep_addr = VIDEO_IN_EP
+};
+
+void video_init(void)
+{
+ usbd_desc_register(video_descriptor);
+ usbd_add_interface(usbd_video_alloc_intf(CAM_FPS, MAX_FRAME_SIZE, MAX_PAYLOAD_SIZE));
+ usbd_add_interface(usbd_video_alloc_intf(CAM_FPS, MAX_FRAME_SIZE, MAX_PAYLOAD_SIZE));
+ usbd_add_endpoint(&video_in_ep);
+
+ usbd_initialize();
+}
+
+USB_NOCACHE_RAM_SECTION USB_MEM_ALIGNX uint8_t packet_buffer[10 * 1024];
+
+extern uint32_t chey_board_millis(void);
+
+void video_task(void)
+{
+ static uint32_t start_ms = 0;
+ static uint32_t already_sent = 0;
+ static uint32_t packets = 0;
+
+ if (tx_flag) {
+ uint32_t out_len;
+ packets = usbd_video_mjpeg_payload_fill((uint8_t *)jpeg_data, sizeof(jpeg_data), packet_buffer, &out_len);
+
+ if (!already_sent) {
+ already_sent = 1;
+ start_ms = chey_board_millis();
+ iso_tx_busy = true;
+ usbd_ep_start_write(VIDEO_IN_EP, &packet_buffer[0 * MAX_PAYLOAD_SIZE], MAX_PAYLOAD_SIZE);
+ while (iso_tx_busy) {
+ }
+ }
+
+ for (uint16_t i = 1; i < packets; i++) {
+ while ((chey_board_millis() - start_ms) < (INTERVAL / 1000000)) {
+ }
+ start_ms += (INTERVAL / 1000000);
+
+ if (i == (packets - 1)) {
+ iso_tx_busy = true;
+ usbd_ep_start_write(VIDEO_IN_EP, &packet_buffer[i * MAX_PAYLOAD_SIZE], out_len - (packets - 1) * MAX_PAYLOAD_SIZE);
+ while (iso_tx_busy) {
+ }
+ } else {
+ iso_tx_busy = true;
+ usbd_ep_start_write(VIDEO_IN_EP, &packet_buffer[i * MAX_PAYLOAD_SIZE], MAX_PAYLOAD_SIZE);
+ while (iso_tx_busy) {
+ }
+ }
+ }
+ already_sent = 0;
+ } else {
+ start_ms = 0;
+ already_sent = 0;
+ packets = 0;
+ }
+} \ No newline at end of file
diff --git a/demo/rp2040/cherryusb/device/uvc/main.c b/demo/rp2040/cherryusb/device/uvc/main.c
new file mode 100644
index 00000000..851d9304
--- /dev/null
+++ b/demo/rp2040/cherryusb/device/uvc/main.c
@@ -0,0 +1,33 @@
+#include "pico/stdlib.h"
+#include "pico/time.h"
+#include "usbd_core.h"
+#include <stdio.h>
+#include <string.h>
+
+uint32_t chey_board_millis(void) {
+ return to_ms_since_boot(get_absolute_time());
+}
+
+/**
+ *
+ */
+#include "cherryusb_uvc_demo.c"
+
+int main(void) {
+ stdio_init_all();
+ printf("CherryUSB device uvc example\n");
+ extern void video_init(void);
+ video_init();
+
+ // Wait until configured
+ while (!usb_device_is_configured()) {
+ tight_loop_contents();
+ }
+
+ // Everything is interrupt driven so just loop here
+ while (1) {
+ extern void video_task(void);
+ video_task();
+ }
+ return 0;
+}
diff --git a/demo/rp2040/cherryusb/usb_config.h b/demo/rp2040/cherryusb/usb_config.h
new file mode 100644
index 00000000..34fb3409
--- /dev/null
+++ b/demo/rp2040/cherryusb/usb_config.h
@@ -0,0 +1,156 @@
+/*
+ * Copyright (c) 2022, sakumisu
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ */
+#ifndef CHERRYUSB_CONFIG_H
+#define CHERRYUSB_CONFIG_H
+
+/* ================ USB common Configuration ================ */
+
+#ifndef CONFIG_USB_DBG_LEVEL
+// #define CONFIG_USB_DBG_LEVEL USB_DBG_LOG
+#define CONFIG_USB_DBG_LEVEL USB_DBG_INFO
+// #define CONFIG_USB_DBG_LEVEL -1
+#endif
+
+#ifndef CONFIG_USB_PRINTF
+#define CONFIG_USB_PRINTF printf
+#endif
+
+/* Enable print with color */
+#define CONFIG_USB_PRINTF_COLOR_ENABLE
+
+/* data align size when use dma */
+#ifndef CONFIG_USB_ALIGN_SIZE
+#define CONFIG_USB_ALIGN_SIZE 4
+#endif
+
+/* attribute data into no cache ram */
+// #define USB_NOCACHE_RAM_SECTION __attribute__((section(".noncacheable")))
+#define USB_NOCACHE_RAM_SECTION
+/* ================= USB Device Stack Configuration ================ */
+
+/* Ep0 max transfer buffer, specially for receiving data from ep0 out */
+#ifndef CONFIG_USBDEV_REQUEST_BUFFER_LEN
+#define CONFIG_USBDEV_REQUEST_BUFFER_LEN 1024
+#endif
+
+/* Setup packet log for debug */
+// #define CONFIG_USBDEV_SETUP_LOG_PRINT
+
+/* Check if the input descriptor is correct */
+// #define CONFIG_USBDEV_DESC_CHECK
+
+/* Enable test mode */
+// #define CONFIG_USBDEV_TEST_MODE
+
+#ifndef CONFIG_USBDEV_MSC_BLOCK_SIZE
+#define CONFIG_USBDEV_MSC_BLOCK_SIZE 512
+#endif
+
+#ifndef CONFIG_USBDEV_MSC_MANUFACTURER_STRING
+#define CONFIG_USBDEV_MSC_MANUFACTURER_STRING ""
+#endif
+
+#ifndef CONFIG_USBDEV_MSC_PRODUCT_STRING
+#define CONFIG_USBDEV_MSC_PRODUCT_STRING ""
+#endif
+
+#ifndef CONFIG_USBDEV_MSC_VERSION_STRING
+#define CONFIG_USBDEV_MSC_VERSION_STRING "0.01"
+#endif
+
+// #define CONFIG_USBDEV_MSC_THREAD
+
+#ifdef CONFIG_USBDEV_MSC_THREAD
+#ifndef CONFIG_USBDEV_MSC_STACKSIZE
+#define CONFIG_USBDEV_MSC_STACKSIZE 2048
+#endif
+
+#ifndef CONFIG_USBDEV_MSC_PRIO
+#define CONFIG_USBDEV_MSC_PRIO 4
+#endif
+#endif
+
+#ifndef CONFIG_USBDEV_AUDIO_VERSION
+#define CONFIG_USBDEV_AUDIO_VERSION 0x0100
+#endif
+
+#ifndef CONFIG_USBDEV_AUDIO_MAX_CHANNEL
+#define CONFIG_USBDEV_AUDIO_MAX_CHANNEL 8
+#endif
+
+#ifndef CONFIG_USBDEV_RNDIS_RESP_BUFFER_SIZE
+#define CONFIG_USBDEV_RNDIS_RESP_BUFFER_SIZE 128
+#endif
+
+#ifndef CONFIG_USBDEV_RNDIS_ETH_MAX_FRAME_SIZE
+#define CONFIG_USBDEV_RNDIS_ETH_MAX_FRAME_SIZE 1536
+#endif
+
+#ifndef CONFIG_USBDEV_RNDIS_VENDOR_ID
+#define CONFIG_USBDEV_RNDIS_VENDOR_ID 0x0000ffff
+#endif
+
+#ifndef CONFIG_USBDEV_RNDIS_VENDOR_DESC
+#define CONFIG_USBDEV_RNDIS_VENDOR_DESC "CherryUSB"
+#endif
+
+/* ================ USB HOST Stack Configuration ================== */
+
+#define CONFIG_USBHOST_MAX_RHPORTS 1
+#define CONFIG_USBHOST_MAX_EXTHUBS 1
+#define CONFIG_USBHOST_MAX_EHPORTS 4
+#define CONFIG_USBHOST_MAX_INTERFACES 6
+#define CONFIG_USBHOST_MAX_INTF_ALTSETTINGS 1
+#define CONFIG_USBHOST_MAX_ENDPOINTS 4
+
+#define CONFIG_USBHOST_DEV_NAMELEN 16
+
+#ifndef CONFIG_USBHOST_PSC_PRIO
+#define CONFIG_USBHOST_PSC_PRIO 4
+#endif
+#ifndef CONFIG_USBHOST_PSC_STACKSIZE
+#define CONFIG_USBHOST_PSC_STACKSIZE 2048
+#endif
+
+//#define CONFIG_USBHOST_GET_STRING_DESC
+
+/* Ep0 max transfer buffer */
+#define CONFIG_USBHOST_REQUEST_BUFFER_LEN 512
+
+#ifndef CONFIG_USBHOST_CONTROL_TRANSFER_TIMEOUT
+#define CONFIG_USBHOST_CONTROL_TRANSFER_TIMEOUT 500
+#endif
+
+#ifndef CONFIG_USBHOST_MSC_TIMEOUT
+#define CONFIG_USBHOST_MSC_TIMEOUT 5000
+#endif
+
+/* ================ USB Device Port Configuration ================*/
+
+//#define USBD_IRQHandler USBD_IRQHandler
+//#define USB_BASE (0x40080000UL)
+//#define USB_NUM_BIDIR_ENDPOINTS 4
+
+// #define USBD_IRQHandler USB_IRQHandler
+// #define USB_BASE (0x40000C00U)
+
+
+
+/* ================ USB Host Port Configuration ==================*/
+
+#define CONFIG_USBHOST_PIPE_NUM 10
+
+/* ================ EHCI Configuration ================ */
+
+#define CONFIG_USB_EHCI_HCCR_BASE (0x20072000)
+#define CONFIG_USB_EHCI_HCOR_BASE (0x20072000 + 0x10)
+#define CONFIG_USB_EHCI_FRAME_LIST_SIZE 1024
+// #define CONFIG_USB_EHCI_INFO_ENABLE
+// #define CONFIG_USB_ECHI_HCOR_RESERVED_DISABLE
+// #define CONFIG_USB_EHCI_CONFIGFLAG
+// #define CONFIG_USB_EHCI_PORT_POWER
+
+#endif