diff options
| author | HaiMianBB <[email protected]> | 2022-10-11 15:34:06 +0800 |
|---|---|---|
| committer | sakumisu <[email protected]> | 2022-10-11 20:55:39 +0800 |
| commit | 84eb90e5c0528667a502495593caa77e5331ac47 (patch) | |
| tree | 2e05c24269142f2cfd301444bffa86904b5025ad | |
| parent | 9ab90c7ce4141231bd6520d6a7681d70320efbd3 (diff) | |
Add rp2040 usbd demo
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 |
