mirror of
https://github.com/raspberrypi/pico-sdk.git
synced 2025-04-16 23:43:15 +00:00
Merge 1c2f927d4b6c166d93abeffa3d1e37e5b2f2e28e into 65a8907828ad87acd6a8e3363f175a64337b65cd
This commit is contained in:
commit
dd7ec56e53
3
.gitmodules
vendored
3
.gitmodules
vendored
@ -13,3 +13,6 @@
|
||||
[submodule "lib/btstack"]
|
||||
path = lib/btstack
|
||||
url = https://github.com/bluekitchen/btstack.git
|
||||
[submodule "lib/cherryusb"]
|
||||
path = lib/cherryusb
|
||||
url = https://github.com/cherry-embedded/CherryUSB.git
|
||||
|
1
lib/cherryusb
Submodule
1
lib/cherryusb
Submodule
@ -0,0 +1 @@
|
||||
Subproject commit 43e6b5b1b1f6af62497e740db8faee4499724627
|
@ -120,6 +120,8 @@ if (NOT PICO_BARE_METAL)
|
||||
pico_add_subdirectory(rp2_common/cmsis)
|
||||
endif()
|
||||
pico_add_subdirectory(rp2_common/tinyusb)
|
||||
pico_add_subdirectory(rp2_common/cherryusb)
|
||||
pico_add_subdirectory(rp2_common/pico_stdio_cherryusb)
|
||||
pico_add_subdirectory(rp2_common/pico_stdio_usb)
|
||||
pico_add_subdirectory(rp2_common/pico_i2c_slave)
|
||||
|
||||
|
46
src/rp2_common/cherryusb/CMakeLists.txt
Normal file
46
src/rp2_common/cherryusb/CMakeLists.txt
Normal file
@ -0,0 +1,46 @@
|
||||
if (DEFINED ENV{PICO_CHERRYUSB_PATH} AND (NOT PICO_CHERRYUSB_PATH))
|
||||
set(PICO_CHERRYUSB_PATH $ENV{PICO_CHERRYUSB_PATH})
|
||||
message("Using PICO_CHERRYUSB_PATH from environment ('${PICO_CHERRYUSB_PATH}')")
|
||||
endif ()
|
||||
|
||||
set(CHERRYUSB_TEST_PATH "port/rp2040")
|
||||
if (NOT PICO_CHERRYUSB_PATH)
|
||||
set(PICO_CHERRYUSB_PATH ${PROJECT_SOURCE_DIR}/lib/cherryusb)
|
||||
if (NOT EXISTS ${PICO_CHERRYUSB_PATH}/${CHERRYUSB_TEST_PATH})
|
||||
message(WARNING "CherryUSB submodule has not been initialized; USB support will be unavailable
|
||||
hint: try 'git submodule update --init' from your SDK directory (${PICO_SDK_PATH}).")
|
||||
endif()
|
||||
elseif (NOT EXISTS ${PICO_CHERRYUSB_PATH}/${CHERRYUSB_TEST_PATH})
|
||||
message(WARNING "PICO_CHERRYUSB_PATH specified but content not present.")
|
||||
endif()
|
||||
|
||||
if (EXISTS ${PICO_CHERRYUSB_PATH}/${CHERRYUSB_TEST_PATH})
|
||||
message("CherryUSB available at ${PICO_CHERRYUSB_PATH}; enabling build support for USB.")
|
||||
pico_register_common_scope_var(PICO_CHERRYUSB_PATH)
|
||||
|
||||
set(CONFIG_CHERRYUSB_DEVICE 1)
|
||||
set(CONFIG_CHERRYUSB_DEVICE_CDC_ACM 1)
|
||||
set(CONFIG_CHERRYUSB_DEVICE_HID 1)
|
||||
set(CONFIG_CHERRYUSB_DEVICE_MSC 1)
|
||||
set(CONFIG_CHERRYUSB_DEVICE_AUDIO 1)
|
||||
set(CONFIG_CHERRYUSB_DEVICE_VIDEO 1)
|
||||
set(CONFIG_CHERRYUSB_DEVICE_DCD "rp2040")
|
||||
include(${PICO_CHERRYUSB_PATH}/cherryusb.cmake)
|
||||
pico_add_library(cherryusb_device NOFLAG)
|
||||
target_include_directories(cherryusb_device_headers SYSTEM INTERFACE ${cherryusb_incs})
|
||||
target_sources(cherryusb_device INTERFACE ${cherryusb_srcs})
|
||||
|
||||
set(CONFIG_CHERRYUSB_HOST 1)
|
||||
set(CONFIG_CHERRYUSB_HOST_CDC_ACM 1)
|
||||
set(CONFIG_CHERRYUSB_HOST_HID 1)
|
||||
set(CONFIG_CHERRYUSB_HOST_MSC 1)
|
||||
set(CONFIG_CHERRYUSB_OSAL "freertos")
|
||||
set(CONFIG_CHERRYUSB_HOST_HCD "rp2040")
|
||||
|
||||
include(${PICO_CHERRYUSB_PATH}/cherryusb.cmake)
|
||||
pico_add_library(cherryusb_host NOFLAG)
|
||||
target_include_directories(cherryusb_host_headers SYSTEM INTERFACE ${cherryusb_incs})
|
||||
target_sources(cherryusb_host INTERFACE ${cherryusb_srcs})
|
||||
|
||||
pico_promote_common_scope_vars()
|
||||
endif()
|
@ -106,6 +106,12 @@ SECTIONS
|
||||
*(.fini_array)
|
||||
PROVIDE_HIDDEN (__fini_array_end = .);
|
||||
|
||||
/* section information for usbh class */
|
||||
. = ALIGN(4);
|
||||
__usbh_class_info_start__ = .;
|
||||
KEEP(*(.usbh_class_info))
|
||||
__usbh_class_info_end__ = .;
|
||||
|
||||
*(.eh_frame*)
|
||||
. = ALIGN(4);
|
||||
} > FLASH
|
||||
|
@ -125,6 +125,12 @@ SECTIONS
|
||||
*(SORT(.dtors.*))
|
||||
*(.dtors)
|
||||
|
||||
/* section information for usbh class */
|
||||
. = ALIGN(4);
|
||||
__usbh_class_info_start__ = .;
|
||||
KEEP(*(.usbh_class_info))
|
||||
__usbh_class_info_end__ = .;
|
||||
|
||||
*(.eh_frame*)
|
||||
. = ALIGN(4);
|
||||
__ram_text_end__ = .;
|
||||
|
@ -106,6 +106,12 @@ SECTIONS
|
||||
*(.fini_array)
|
||||
PROVIDE_HIDDEN (__fini_array_end = .);
|
||||
|
||||
/* section information for usbh class */
|
||||
. = ALIGN(4);
|
||||
__usbh_class_info_start__ = .;
|
||||
KEEP(*(.usbh_class_info))
|
||||
__usbh_class_info_end__ = .;
|
||||
|
||||
*(.eh_frame*)
|
||||
. = ALIGN(4);
|
||||
} > FLASH
|
||||
|
@ -68,6 +68,12 @@ SECTIONS
|
||||
*(SORT(.dtors.*))
|
||||
*(.dtors)
|
||||
|
||||
/* section information for usbh class */
|
||||
. = ALIGN(4);
|
||||
__usbh_class_info_start__ = .;
|
||||
KEEP(*(.usbh_class_info))
|
||||
__usbh_class_info_end__ = .;
|
||||
|
||||
*(.eh_frame*)
|
||||
} > RAM
|
||||
|
||||
|
@ -141,6 +141,12 @@ SECTIONS
|
||||
*(SORT(.dtors.*))
|
||||
*(.dtors)
|
||||
|
||||
/* section information for usbh class */
|
||||
. = ALIGN(4);
|
||||
__usbh_class_info_start__ = .;
|
||||
KEEP(*(.usbh_class_info))
|
||||
__usbh_class_info_end__ = .;
|
||||
|
||||
*(.eh_frame*)
|
||||
. = ALIGN(4);
|
||||
__ram_text_end__ = .;
|
||||
|
@ -96,6 +96,12 @@ SECTIONS
|
||||
*(.fini_array)
|
||||
PROVIDE_HIDDEN (__fini_array_end = .);
|
||||
|
||||
/* section information for usbh class */
|
||||
. = ALIGN(4);
|
||||
__usbh_class_info_start__ = .;
|
||||
KEEP(*(.usbh_class_info))
|
||||
__usbh_class_info_end__ = .;
|
||||
|
||||
*(.eh_frame*)
|
||||
. = ALIGN(4);
|
||||
} > FLASH
|
||||
|
@ -69,6 +69,12 @@ SECTIONS
|
||||
*(SORT(.dtors.*))
|
||||
*(.dtors)
|
||||
|
||||
/* section information for usbh class */
|
||||
. = ALIGN(4);
|
||||
__usbh_class_info_start__ = .;
|
||||
KEEP(*(.usbh_class_info))
|
||||
__usbh_class_info_end__ = .;
|
||||
|
||||
*(.eh_frame*)
|
||||
} > RAM
|
||||
|
||||
|
25
src/rp2_common/pico_stdio_cherryusb/CMakeLists.txt
Normal file
25
src/rp2_common/pico_stdio_cherryusb/CMakeLists.txt
Normal file
@ -0,0 +1,25 @@
|
||||
if (TARGET cherryusb_device)
|
||||
pico_add_library(pico_stdio_usb)
|
||||
|
||||
target_include_directories(pico_stdio_usb_headers SYSTEM INTERFACE ${CMAKE_CURRENT_LIST_DIR}/include)
|
||||
|
||||
target_sources(pico_stdio_usb INTERFACE
|
||||
${CMAKE_CURRENT_LIST_DIR}/stdio_usb.c
|
||||
)
|
||||
|
||||
pico_mirrored_target_link_libraries(pico_stdio_usb INTERFACE
|
||||
pico_stdio
|
||||
pico_time
|
||||
pico_unique_id
|
||||
pico_usb_reset_interface
|
||||
)
|
||||
target_link_libraries(pico_stdio_usb INTERFACE
|
||||
cherryusb_device
|
||||
)
|
||||
# PICO_CMAKE_CONFIG: PICO_STDIO_CHERRYUSB_CONNECT_WAIT_TIMEOUT_MS, Maximum number of milliseconds to wait during initialization for a CDC connection from the host (negative means indefinite) during initialization, type=int, default=0, group=pico_stdio_usb
|
||||
if (PICO_STDIO_CHERRYUSB_CONNECT_WAIT_TIMEOUT_MS)
|
||||
target_compile_definitions(pico_stdio_usb INTERFACE
|
||||
PICO_STDIO_CHERRYUSB_CONNECT_WAIT_TIMEOUT_MS=${PICO_STDIO_CHERRYUSB_CONNECT_WAIT_TIMEOUT_MS}
|
||||
)
|
||||
endif()
|
||||
endif()
|
153
src/rp2_common/pico_stdio_cherryusb/include/pico/stdio_usb.h
Normal file
153
src/rp2_common/pico_stdio_cherryusb/include/pico/stdio_usb.h
Normal file
@ -0,0 +1,153 @@
|
||||
/*
|
||||
* Copyright (c) 2020 Raspberry Pi (Trading) Ltd.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
#ifndef _PICO_STDIO_CHERRYUSB_H
|
||||
#define _PICO_STDIO_CHERRYUSB_H
|
||||
|
||||
#include "pico/stdio.h"
|
||||
|
||||
/** \brief Support for stdin/stdout over USB serial (CDC)
|
||||
* \defgroup pico_stdio_usb pico_stdio_usb
|
||||
* \ingroup pico_stdio
|
||||
*
|
||||
* Linking this library or calling `pico_enable_stdio_usb(TARGET ENABLED)` in the CMake (which
|
||||
* achieves the same thing) will add USB CDC to the drivers used for standard input/output
|
||||
*
|
||||
* Note this library is a developer convenience. It is not applicable in all cases; for one it takes full control of the USB device precluding your
|
||||
* use of the USB in device or host mode. For this reason, this library will automatically disengage if you try to using it alongside \ref tinyusb_device or
|
||||
* \ref tinyusb_host. It also takes control of a lower level IRQ and sets up a periodic background task.
|
||||
*
|
||||
* This library also includes (by default) functionality to enable the RP-series microcontroller to be reset over the USB interface.
|
||||
*/
|
||||
|
||||
// PICO_CONFIG: PICO_STDIO_CHERRYUSB_DEFAULT_CRLF, Default state of CR/LF translation for USB output, type=bool, default=PICO_STDIO_DEFAULT_CRLF, group=pico_stdio_usb
|
||||
#ifndef PICO_STDIO_CHERRYUSB_DEFAULT_CRLF
|
||||
#define PICO_STDIO_CHERRYUSB_DEFAULT_CRLF PICO_STDIO_DEFAULT_CRLF
|
||||
#endif
|
||||
|
||||
// PICO_CONFIG: PICO_STDIO_CHERRYUSB_STDOUT_TIMEOUT_US, Number of microseconds to be blocked trying to write USB output before assuming the host has disappeared and discarding data, default=500000, group=pico_stdio_usb
|
||||
#ifndef PICO_STDIO_CHERRYUSB_STDOUT_TIMEOUT_US
|
||||
#define PICO_STDIO_CHERRYUSB_STDOUT_TIMEOUT_US 500000
|
||||
#endif
|
||||
|
||||
// PICO_CONFIG: PICO_STDIO_CHERRYUSB_ENABLE_RESET_VIA_BAUD_RATE, Enable/disable resetting into BOOTSEL mode if the host sets the baud rate to a magic value (PICO_STDIO_CHERRYUSB_RESET_MAGIC_BAUD_RATE), type=bool, default=1 if application is not using TinyUSB directly, group=pico_stdio_usb
|
||||
#ifndef PICO_STDIO_CHERRYUSB_ENABLE_RESET_VIA_BAUD_RATE
|
||||
#define PICO_STDIO_CHERRYUSB_ENABLE_RESET_VIA_BAUD_RATE 1
|
||||
#endif
|
||||
|
||||
// PICO_CONFIG: PICO_STDIO_CHERRYUSB_RESET_MAGIC_BAUD_RATE, Baud rate that if selected causes a reset into BOOTSEL mode (if PICO_STDIO_CHERRYUSB_ENABLE_RESET_VIA_BAUD_RATE is set), default=1200, group=pico_stdio_usb
|
||||
#ifndef PICO_STDIO_CHERRYUSB_RESET_MAGIC_BAUD_RATE
|
||||
#define PICO_STDIO_CHERRYUSB_RESET_MAGIC_BAUD_RATE 1200
|
||||
#endif
|
||||
|
||||
// PICO_CONFIG: PICO_STDIO_CHERRYUSB_CONNECT_WAIT_TIMEOUT_MS, Maximum number of milliseconds to wait during initialization for a CDC connection from the host (negative means indefinite) during initialization, default=0, group=pico_stdio_usb
|
||||
#ifndef PICO_STDIO_CHERRYUSB_CONNECT_WAIT_TIMEOUT_MS
|
||||
#define PICO_STDIO_CHERRYUSB_CONNECT_WAIT_TIMEOUT_MS 0
|
||||
#endif
|
||||
|
||||
// PICO_CONFIG: PICO_STDIO_CHERRYUSB_CONNECT_WAIT_TIMEOUT_MS, Number of extra milliseconds to wait when using PICO_STDIO_CHERRYUSB_CONNECT_WAIT_TIMEOUT_MS after a host CDC connection is detected (some host terminals seem to sometimes lose transmissions sent right after connection), default=50, group=pico_stdio_usb
|
||||
#ifndef PICO_STDIO_CHERRYUSB_CONNECT_WAIT_TIMEOUT_MS
|
||||
#define PICO_STDIO_CHERRYUSB_CONNECT_WAIT_TIMEOUT_MS 50
|
||||
#endif
|
||||
|
||||
// PICO_CONFIG: PICO_STDIO_CHERRYUSB_DEINIT_DELAY_MS, Number of milliseconds to wait before deinitializing stdio_usb, default=110, group=pico_stdio_usb
|
||||
#ifndef PICO_STDIO_CHERRYUSB_DEINIT_DELAY_MS
|
||||
#define PICO_STDIO_CHERRYUSB_DEINIT_DELAY_MS 110
|
||||
#endif
|
||||
|
||||
// PICO_CONFIG: PICO_STDIO_CHERRYUSB_RESET_BOOTSEL_ACTIVITY_LED, Optionally define a pin to use as bootloader activity LED when BOOTSEL mode is entered via USB (either VIA_BAUD_RATE or VIA_VENDOR_INTERFACE), type=int, min=0, max=47 on RP2350B, 29 otherwise, group=pico_stdio_usb
|
||||
|
||||
// PICO_CONFIG: PICO_STDIO_CHERRYUSB_RESET_BOOTSEL_ACTIVITY_LED_ACTIVE_LOW, Whether pin to use as bootloader activity LED when BOOTSEL mode is entered via USB (either VIA_BAUD_RATE or VIA_VENDOR_INTERFACE) is active low, type=bool, default=0, group=pico_stdio_usb
|
||||
#ifndef PICO_STDIO_CHERRYUSB_RESET_BOOTSEL_FIXED_ACTIVITY_LED_ACTIVE_LOW
|
||||
#define PICO_STDIO_CHERRYUSB_RESET_BOOTSEL_FIXED_ACTIVITY_LED_ACTIVE_LOW 0
|
||||
#endif
|
||||
|
||||
// PICO_CONFIG: PICO_STDIO_CHERRYUSB_RESET_BOOTSEL_FIXED_ACTIVITY_LED, Whether the pin specified by PICO_STDIO_CHERRYUSB_RESET_BOOTSEL_ACTIVITY_LED is fixed or can be modified by picotool over the VENDOR USB interface, type=bool, default=0, group=pico_stdio_usb
|
||||
#ifndef PICO_STDIO_CHERRYUSB_RESET_BOOTSEL_FIXED_ACTIVITY_LED
|
||||
#define PICO_STDIO_CHERRYUSB_RESET_BOOTSEL_FIXED_ACTIVITY_LED 0
|
||||
#endif
|
||||
|
||||
// Any modes disabled here can't be re-enabled by picotool via VENDOR_INTERFACE.
|
||||
// PICO_CONFIG: PICO_STDIO_CHERRYUSB_RESET_BOOTSEL_INTERFACE_DISABLE_MASK, Optionally disable either the mass storage interface (bit 0) or the PICOBOOT interface (bit 1) when entering BOOTSEL mode via USB (either VIA_BAUD_RATE or VIA_VENDOR_INTERFACE), type=int, min=0, max=3, default=0, group=pico_stdio_usb
|
||||
#ifndef PICO_STDIO_CHERRYUSB_RESET_BOOTSEL_INTERFACE_DISABLE_MASK
|
||||
#define PICO_STDIO_CHERRYUSB_RESET_BOOTSEL_INTERFACE_DISABLE_MASK 0u
|
||||
#endif
|
||||
|
||||
// PICO_CONFIG: PICO_STDIO_CHERRYUSB_ENABLE_RESET_VIA_VENDOR_INTERFACE, Enable/disable resetting into BOOTSEL mode via an additional VENDOR USB interface - enables picotool based reset, type=bool, default=1 if application is not using TinyUSB directly, group=pico_stdio_usb
|
||||
#ifndef PICO_STDIO_CHERRYUSB_ENABLE_RESET_VIA_VENDOR_INTERFACE
|
||||
#define PICO_STDIO_CHERRYUSB_ENABLE_RESET_VIA_VENDOR_INTERFACE 1
|
||||
#endif
|
||||
|
||||
// PICO_CONFIG: PICO_STDIO_CHERRYUSB_RESET_INTERFACE_SUPPORT_RESET_TO_BOOTSEL, If vendor reset interface is included allow rebooting to BOOTSEL mode, type=bool, default=1, group=pico_stdio_usb
|
||||
#ifndef PICO_STDIO_CHERRYUSB_RESET_INTERFACE_SUPPORT_RESET_TO_BOOTSEL
|
||||
#define PICO_STDIO_CHERRYUSB_RESET_INTERFACE_SUPPORT_RESET_TO_BOOTSEL 1
|
||||
#endif
|
||||
|
||||
// PICO_CONFIG: PICO_STDIO_CHERRYUSB_RESET_INTERFACE_SUPPORT_RESET_TO_FLASH_BOOT, If vendor reset interface is included allow rebooting with regular flash boot, type=bool, default=1, group=pico_stdio_usb
|
||||
#ifndef PICO_STDIO_CHERRYUSB_RESET_INTERFACE_SUPPORT_RESET_TO_FLASH_BOOT
|
||||
#define PICO_STDIO_CHERRYUSB_RESET_INTERFACE_SUPPORT_RESET_TO_FLASH_BOOT 1
|
||||
#endif
|
||||
|
||||
// PICO_CONFIG: PICO_STDIO_CHERRYUSB_RESET_INTERFACE_SUPPORT_MS_OS_20_DESCRIPTOR, If vendor reset interface is included add support for Microsoft OS 2.0 Descriptor, type=bool, default=1, group=pico_stdio_usb
|
||||
#ifndef PICO_STDIO_CHERRYUSB_RESET_INTERFACE_SUPPORT_MS_OS_20_DESCRIPTOR
|
||||
#define PICO_STDIO_CHERRYUSB_RESET_INTERFACE_SUPPORT_MS_OS_20_DESCRIPTOR 1
|
||||
#endif
|
||||
|
||||
// PICO_CONFIG: PICO_STDIO_CHERRYUSB_RESET_RESET_TO_FLASH_DELAY_MS, Delay in ms before rebooting via regular flash boot, default=100, group=pico_stdio_usb
|
||||
#ifndef PICO_STDIO_CHERRYUSB_RESET_RESET_TO_FLASH_DELAY_MS
|
||||
#define PICO_STDIO_CHERRYUSB_RESET_RESET_TO_FLASH_DELAY_MS 100
|
||||
#endif
|
||||
|
||||
// PICO_CONFIG: PICO_STDIO_CHERRYUSB_CONNECTION_WITHOUT_DTR, Disable use of DTR for connection checking meaning connection is assumed to be valid, type=bool, default=0, group=pico_stdio_usb
|
||||
#ifndef PICO_STDIO_CHERRYUSB_CONNECTION_WITHOUT_DTR
|
||||
#define PICO_STDIO_CHERRYUSB_CONNECTION_WITHOUT_DTR 0
|
||||
#endif
|
||||
|
||||
// PICO_CONFIG: PICO_STDIO_CHERRYUSB_DEVICE_SELF_POWERED, Set USB device as self powered device, type=bool, default=0, group=pico_stdio_usb
|
||||
#ifndef PICO_STDIO_CHERRYUSB_DEVICE_SELF_POWERED
|
||||
#define PICO_STDIO_CHERRYUSB_DEVICE_SELF_POWERED 0
|
||||
#endif
|
||||
|
||||
// PICO_CONFIG: PICO_STDIO_CHERRYUSB_SUPPORT_CHARS_AVAILABLE_CALLBACK, Enable USB STDIO support for stdio_set_chars_available_callback. Can be disabled to make use of USB CDC RX callback elsewhere, type=bool, default=1, group=pico_stdio_usb
|
||||
#ifndef PICO_STDIO_CHERRYUSB_SUPPORT_CHARS_AVAILABLE_CALLBACK
|
||||
#define PICO_STDIO_CHERRYUSB_SUPPORT_CHARS_AVAILABLE_CALLBACK 1
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
extern stdio_driver_t stdio_usb;
|
||||
|
||||
/*! \brief Explicitly initialize USB stdio and add it to the current set of stdin drivers
|
||||
* \ingroup pico_stdio_usb
|
||||
*
|
||||
* \ref PICO_STDIO_CHERRYUSB_CONNECT_WAIT_TIMEOUT_MS can be set to cause this method to wait for a CDC connection
|
||||
* from the host before returning, which is useful if you don't want any initial stdout output to be discarded
|
||||
* before the connection is established.
|
||||
*
|
||||
* \return true if the USB CDC was initialized, false if an error occurred
|
||||
*/
|
||||
bool stdio_usb_init(void);
|
||||
|
||||
/*! \brief Explicitly deinitialize USB stdio and remove it from the current set of stdin drivers
|
||||
* \ingroup pico_stdio_usb
|
||||
*
|
||||
* \return true if the USB CDC was deinitialized, false if an error occurred
|
||||
*/
|
||||
bool stdio_usb_deinit(void);
|
||||
|
||||
/*! \brief Check if there is an active stdio CDC connection to a host
|
||||
* \ingroup pico_stdio_usb
|
||||
*
|
||||
* \return true if stdio is connected over CDC
|
||||
*/
|
||||
bool stdio_usb_connected(void);
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
@ -0,0 +1,13 @@
|
||||
/*
|
||||
* Copyright (c) 2021 Raspberry Pi (Trading) Ltd.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
#ifndef _PICO_STDIO_CHERRYUSB_RESET_INTERFACE_H
|
||||
#define _PICO_STDIO_CHERRYUSB_RESET_INTERFACE_H
|
||||
|
||||
// definitions have been moved here
|
||||
#include "pico/usb_reset_interface.h"
|
||||
|
||||
#endif
|
296
src/rp2_common/pico_stdio_cherryusb/include/usb_config.h
Normal file
296
src/rp2_common/pico_stdio_cherryusb/include/usb_config.h
Normal file
@ -0,0 +1,296 @@
|
||||
/*
|
||||
* Copyright (c) 2022, sakumisu
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
#ifndef CHERRYUSB_CONFIG_EXAMPLES_COMMON_H
|
||||
#define CHERRYUSB_CONFIG_EXAMPLES_COMMON_H
|
||||
|
||||
/* ================ USB common Configuration ================ */
|
||||
|
||||
#define CONFIG_USB_PRINTF(...)
|
||||
|
||||
#ifndef CONFIG_USB_DBG_LEVEL
|
||||
#define CONFIG_USB_DBG_LEVEL USB_DBG_INFO
|
||||
#endif
|
||||
|
||||
/* Enable print with color */
|
||||
#define CONFIG_USB_PRINTF_COLOR_ENABLE
|
||||
|
||||
/* data align size when use dma or use dcache */
|
||||
#ifndef CONFIG_USB_ALIGN_SIZE
|
||||
#define CONFIG_USB_ALIGN_SIZE 4
|
||||
#endif
|
||||
|
||||
//#define CONFIG_USB_DCACHE_ENABLE
|
||||
|
||||
/* attribute data into no cache ram */
|
||||
#define USB_NOCACHE_RAM_SECTION
|
||||
|
||||
/* ================= USB Device Stack Configuration ================ */
|
||||
|
||||
/* Ep0 in and out transfer buffer */
|
||||
#ifndef CONFIG_USBDEV_REQUEST_BUFFER_LEN
|
||||
#define CONFIG_USBDEV_REQUEST_BUFFER_LEN 512
|
||||
#endif
|
||||
|
||||
/* Setup packet log for debug */
|
||||
// #define CONFIG_USBDEV_SETUP_LOG_PRINT
|
||||
|
||||
/* Send ep0 in data from user buffer instead of copying into ep0 reqdata
|
||||
* Please note that user buffer must be aligned with CONFIG_USB_ALIGN_SIZE
|
||||
*/
|
||||
// #define CONFIG_USBDEV_EP0_INDATA_NO_COPY
|
||||
|
||||
/* Check if the input descriptor is correct */
|
||||
// #define CONFIG_USBDEV_DESC_CHECK
|
||||
|
||||
/* Enable test mode */
|
||||
// #define CONFIG_USBDEV_TEST_MODE
|
||||
|
||||
#ifndef CONFIG_USBDEV_MSC_MAX_LUN
|
||||
#define CONFIG_USBDEV_MSC_MAX_LUN 1
|
||||
#endif
|
||||
|
||||
#ifndef CONFIG_USBDEV_MSC_MAX_BUFSIZE
|
||||
#define CONFIG_USBDEV_MSC_MAX_BUFSIZE 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
|
||||
|
||||
/* move msc read & write from isr to while(1), you should call usbd_msc_polling in while(1) */
|
||||
// #define CONFIG_USBDEV_MSC_POLLING
|
||||
|
||||
/* move msc read & write from isr to thread */
|
||||
// #define CONFIG_USBDEV_MSC_THREAD
|
||||
|
||||
#ifndef CONFIG_USBDEV_MSC_PRIO
|
||||
#define CONFIG_USBDEV_MSC_PRIO 4
|
||||
#endif
|
||||
|
||||
#ifndef CONFIG_USBDEV_MSC_STACKSIZE
|
||||
#define CONFIG_USBDEV_MSC_STACKSIZE 2048
|
||||
#endif
|
||||
|
||||
#ifndef CONFIG_USBDEV_RNDIS_RESP_BUFFER_SIZE
|
||||
#define CONFIG_USBDEV_RNDIS_RESP_BUFFER_SIZE 156
|
||||
#endif
|
||||
|
||||
/* rndis transfer buffer size, must be a multiple of (1536 + 44)*/
|
||||
#ifndef CONFIG_USBDEV_RNDIS_ETH_MAX_FRAME_SIZE
|
||||
#define CONFIG_USBDEV_RNDIS_ETH_MAX_FRAME_SIZE 1580
|
||||
#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
|
||||
|
||||
#define CONFIG_USBDEV_RNDIS_USING_LWIP
|
||||
|
||||
/* ================ 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 8
|
||||
#define CONFIG_USBHOST_MAX_INTF_ALTSETTINGS 8
|
||||
#define CONFIG_USBHOST_MAX_ENDPOINTS 4
|
||||
|
||||
#define CONFIG_USBHOST_MAX_CDC_ACM_CLASS 4
|
||||
#define CONFIG_USBHOST_MAX_HID_CLASS 4
|
||||
#define CONFIG_USBHOST_MAX_MSC_CLASS 2
|
||||
#define CONFIG_USBHOST_MAX_AUDIO_CLASS 1
|
||||
#define CONFIG_USBHOST_MAX_VIDEO_CLASS 1
|
||||
|
||||
#define CONFIG_USBHOST_DEV_NAMELEN 16
|
||||
|
||||
#ifndef CONFIG_USBHOST_PSC_PRIO
|
||||
#define CONFIG_USBHOST_PSC_PRIO 0
|
||||
#endif
|
||||
#ifndef CONFIG_USBHOST_PSC_STACKSIZE
|
||||
#define CONFIG_USBHOST_PSC_STACKSIZE 2048
|
||||
#endif
|
||||
|
||||
//#define CONFIG_USBHOST_GET_STRING_DESC
|
||||
|
||||
// #define CONFIG_USBHOST_MSOS_ENABLE
|
||||
#ifndef CONFIG_USBHOST_MSOS_VENDOR_CODE
|
||||
#define CONFIG_USBHOST_MSOS_VENDOR_CODE 0x00
|
||||
#endif
|
||||
|
||||
/* Ep0 max transfer buffer */
|
||||
#ifndef CONFIG_USBHOST_REQUEST_BUFFER_LEN
|
||||
#define CONFIG_USBHOST_REQUEST_BUFFER_LEN 512
|
||||
#endif
|
||||
|
||||
#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
|
||||
|
||||
/* This parameter affects usb performance, and depends on (TCP_WND)tcp eceive windows size,
|
||||
* you can change to 2K ~ 16K and must be larger than TCP RX windows size in order to avoid being overflow.
|
||||
*/
|
||||
#ifndef CONFIG_USBHOST_RNDIS_ETH_MAX_RX_SIZE
|
||||
#define CONFIG_USBHOST_RNDIS_ETH_MAX_RX_SIZE (2048)
|
||||
#endif
|
||||
|
||||
/* Because lwip do not support multi pbuf at a time, so increasing this variable has no performance improvement */
|
||||
#ifndef CONFIG_USBHOST_RNDIS_ETH_MAX_TX_SIZE
|
||||
#define CONFIG_USBHOST_RNDIS_ETH_MAX_TX_SIZE (2048)
|
||||
#endif
|
||||
|
||||
/* This parameter affects usb performance, and depends on (TCP_WND)tcp eceive windows size,
|
||||
* you can change to 2K ~ 16K and must be larger than TCP RX windows size in order to avoid being overflow.
|
||||
*/
|
||||
#ifndef CONFIG_USBHOST_CDC_NCM_ETH_MAX_RX_SIZE
|
||||
#define CONFIG_USBHOST_CDC_NCM_ETH_MAX_RX_SIZE (2048)
|
||||
#endif
|
||||
/* Because lwip do not support multi pbuf at a time, so increasing this variable has no performance improvement */
|
||||
#ifndef CONFIG_USBHOST_CDC_NCM_ETH_MAX_TX_SIZE
|
||||
#define CONFIG_USBHOST_CDC_NCM_ETH_MAX_TX_SIZE (2048)
|
||||
#endif
|
||||
|
||||
/* This parameter affects usb performance, and depends on (TCP_WND)tcp eceive windows size,
|
||||
* you can change to 2K ~ 16K and must be larger than TCP RX windows size in order to avoid being overflow.
|
||||
*/
|
||||
#ifndef CONFIG_USBHOST_ASIX_ETH_MAX_RX_SIZE
|
||||
#define CONFIG_USBHOST_ASIX_ETH_MAX_RX_SIZE (2048)
|
||||
#endif
|
||||
/* Because lwip do not support multi pbuf at a time, so increasing this variable has no performance improvement */
|
||||
#ifndef CONFIG_USBHOST_ASIX_ETH_MAX_TX_SIZE
|
||||
#define CONFIG_USBHOST_ASIX_ETH_MAX_TX_SIZE (2048)
|
||||
#endif
|
||||
|
||||
/* This parameter affects usb performance, and depends on (TCP_WND)tcp eceive windows size,
|
||||
* you can change to 2K ~ 16K and must be larger than TCP RX windows size in order to avoid being overflow.
|
||||
*/
|
||||
#ifndef CONFIG_USBHOST_RTL8152_ETH_MAX_RX_SIZE
|
||||
#define CONFIG_USBHOST_RTL8152_ETH_MAX_RX_SIZE (2048)
|
||||
#endif
|
||||
/* Because lwip do not support multi pbuf at a time, so increasing this variable has no performance improvement */
|
||||
#ifndef CONFIG_USBHOST_RTL8152_ETH_MAX_TX_SIZE
|
||||
#define CONFIG_USBHOST_RTL8152_ETH_MAX_TX_SIZE (2048)
|
||||
#endif
|
||||
|
||||
#define CONFIG_USBHOST_BLUETOOTH_HCI_H4
|
||||
// #define CONFIG_USBHOST_BLUETOOTH_HCI_LOG
|
||||
|
||||
#ifndef CONFIG_USBHOST_BLUETOOTH_TX_SIZE
|
||||
#define CONFIG_USBHOST_BLUETOOTH_TX_SIZE 2048
|
||||
#endif
|
||||
#ifndef CONFIG_USBHOST_BLUETOOTH_RX_SIZE
|
||||
#define CONFIG_USBHOST_BLUETOOTH_RX_SIZE 2048
|
||||
#endif
|
||||
|
||||
/* ================ USB Device Port Configuration ================*/
|
||||
|
||||
#ifndef CONFIG_USBDEV_MAX_BUS
|
||||
#define CONFIG_USBDEV_MAX_BUS 1 // for now, bus num must be 1 except hpm ip
|
||||
#endif
|
||||
|
||||
#ifndef CONFIG_USBDEV_EP_NUM
|
||||
#define CONFIG_USBDEV_EP_NUM 16
|
||||
#endif
|
||||
|
||||
/* When your chip hardware supports high-speed and wants to initialize it in high-speed mode, the relevant IP will configure the internal or external high-speed PHY according to CONFIG_USB_HS. */
|
||||
// #define CONFIG_USB_HS
|
||||
|
||||
/* ---------------- FSDEV Configuration ---------------- */
|
||||
//#define CONFIG_USBDEV_FSDEV_PMA_ACCESS 2 // maybe 1 or 2, many chips may have a difference
|
||||
|
||||
/* ---------------- DWC2 Configuration ---------------- */
|
||||
/* (5 * number of control endpoints + 8) + ((largest USB packet used / 4) + 1 for
|
||||
* status information) + (2 * number of OUT endpoints) + 1 for Global NAK
|
||||
*/
|
||||
// #define CONFIG_USB_DWC2_RXALL_FIFO_SIZE (1024 / 4)
|
||||
/* IN Endpoints Max packet Size / 4 */
|
||||
// #define CONFIG_USB_DWC2_TX0_FIFO_SIZE (64 / 4)
|
||||
// #define CONFIG_USB_DWC2_TX1_FIFO_SIZE (1024 / 4)
|
||||
// #define CONFIG_USB_DWC2_TX2_FIFO_SIZE (64 / 4)
|
||||
// #define CONFIG_USB_DWC2_TX3_FIFO_SIZE (64 / 4)
|
||||
// #define CONFIG_USB_DWC2_TX4_FIFO_SIZE (0 / 4)
|
||||
// #define CONFIG_USB_DWC2_TX5_FIFO_SIZE (0 / 4)
|
||||
// #define CONFIG_USB_DWC2_TX6_FIFO_SIZE (0 / 4)
|
||||
// #define CONFIG_USB_DWC2_TX7_FIFO_SIZE (0 / 4)
|
||||
// #define CONFIG_USB_DWC2_TX8_FIFO_SIZE (0 / 4)
|
||||
|
||||
// #define CONFIG_USB_DWC2_DMA_ENABLE
|
||||
|
||||
/* ---------------- MUSB Configuration ---------------- */
|
||||
// #define CONFIG_USB_MUSB_SUNXI
|
||||
|
||||
/* ================ USB Host Port Configuration ==================*/
|
||||
#ifndef CONFIG_USBHOST_MAX_BUS
|
||||
#define CONFIG_USBHOST_MAX_BUS 1
|
||||
#endif
|
||||
|
||||
#ifndef CONFIG_USBHOST_PIPE_NUM
|
||||
#define CONFIG_USBHOST_PIPE_NUM 15
|
||||
#endif
|
||||
|
||||
/* ---------------- EHCI Configuration ---------------- */
|
||||
|
||||
#define CONFIG_USB_EHCI_HCCR_OFFSET (0x0)
|
||||
#define CONFIG_USB_EHCI_FRAME_LIST_SIZE 1024
|
||||
#define CONFIG_USB_EHCI_QH_NUM CONFIG_USBHOST_PIPE_NUM
|
||||
#define CONFIG_USB_EHCI_QTD_NUM 3
|
||||
#define CONFIG_USB_EHCI_ITD_NUM 20
|
||||
// #define CONFIG_USB_EHCI_HCOR_RESERVED_DISABLE
|
||||
// #define CONFIG_USB_EHCI_CONFIGFLAG
|
||||
// #define CONFIG_USB_EHCI_ISO
|
||||
// #define CONFIG_USB_EHCI_WITH_OHCI
|
||||
|
||||
/* ---------------- OHCI Configuration ---------------- */
|
||||
#define CONFIG_USB_OHCI_HCOR_OFFSET (0x0)
|
||||
|
||||
/* ---------------- XHCI Configuration ---------------- */
|
||||
#define CONFIG_USB_XHCI_HCCR_OFFSET (0x0)
|
||||
|
||||
/* ---------------- DWC2 Configuration ---------------- */
|
||||
/* largest non-periodic USB packet used / 4 */
|
||||
// #define CONFIG_USB_DWC2_NPTX_FIFO_SIZE (512 / 4)
|
||||
/* largest periodic USB packet used / 4 */
|
||||
// #define CONFIG_USB_DWC2_PTX_FIFO_SIZE (1024 / 4)
|
||||
/*
|
||||
* (largest USB packet used / 4) + 1 for status information + 1 transfer complete +
|
||||
* 1 location each for Bulk/Control endpoint for handling NAK/NYET scenario
|
||||
*/
|
||||
// #define CONFIG_USB_DWC2_RX_FIFO_SIZE ((1012 - CONFIG_USB_DWC2_NPTX_FIFO_SIZE - CONFIG_USB_DWC2_PTX_FIFO_SIZE))
|
||||
|
||||
/* ---------------- MUSB Configuration ---------------- */
|
||||
// #define CONFIG_USB_MUSB_SUNXI
|
||||
|
||||
/* ================ USB Dcache Configuration ==================*/
|
||||
|
||||
#ifdef CONFIG_USB_DCACHE_ENABLE
|
||||
/* style 1*/
|
||||
// void usb_dcache_clean(uintptr_t addr, uint32_t size);
|
||||
// void usb_dcache_invalidate(uintptr_t addr, uint32_t size);
|
||||
// void usb_dcache_flush(uintptr_t addr, uint32_t size);
|
||||
|
||||
/* style 2*/
|
||||
// #define usb_dcache_clean(addr, size)
|
||||
// #define usb_dcache_invalidate(addr, size)
|
||||
// #define usb_dcache_flush(addr, size)
|
||||
#endif
|
||||
|
||||
#define CONFIG_USBDEV_ADVANCE_DESC
|
||||
#endif
|
647
src/rp2_common/pico_stdio_cherryusb/stdio_usb.c
Normal file
647
src/rp2_common/pico_stdio_cherryusb/stdio_usb.c
Normal file
@ -0,0 +1,647 @@
|
||||
#ifndef LIB_CHERRYUSB_HOST
|
||||
|
||||
#if PICO_STDIO_CHERRYUSB_ENABLE_RESET_VIA_VENDOR_INTERFACE && !(PICO_STDIO_CHERRYUSB_RESET_INTERFACE_SUPPORT_RESET_TO_BOOTSEL || PICO_STDIO_CHERRYUSB_RESET_INTERFACE_SUPPORT_RESET_TO_FLASH_BOOT)
|
||||
#warning PICO_STDIO_CHERRYUSB_ENABLE_RESET_VIA_VENDOR_INTERFACE has been selected but neither PICO_STDIO_CHERRYUSB_RESET_INTERFACE_SUPPORT_RESET_TO_BOOTSEL nor PICO_STDIO_CHERRYUSB_RESET_INTERFACE_SUPPORT_RESET_TO_FLASH_BOOT have been selected.
|
||||
#endif
|
||||
|
||||
#include "usbd_core.h"
|
||||
#include "usbd_cdc_acm.h"
|
||||
#include "pico/stdio_usb.h"
|
||||
|
||||
#include "pico/binary_info.h"
|
||||
#include "pico/time.h"
|
||||
#include "pico/stdio/driver.h"
|
||||
#include "pico/mutex.h"
|
||||
#include "hardware/irq.h"
|
||||
|
||||
#include "pico/unique_id.h"
|
||||
|
||||
#if PICO_STDIO_CHERRYUSB_ENABLE_RESET_VIA_VENDOR_INTERFACE
|
||||
#include "pico/stdio_usb/reset_interface.h"
|
||||
#include "hardware/watchdog.h"
|
||||
#include "pico/bootrom.h"
|
||||
#endif
|
||||
|
||||
/*!< endpoint address */
|
||||
#define CDC_IN_EP 0x81
|
||||
#define CDC_OUT_EP 0x02
|
||||
#define CDC_INT_EP 0x83
|
||||
|
||||
#ifndef USBD_VID
|
||||
#define USBD_VID (0x2E8A) // Raspberry Pi
|
||||
#endif
|
||||
|
||||
#ifndef USBD_PID
|
||||
#if PICO_RP2040
|
||||
#define USBD_PID (0x000a) // Raspberry Pi Pico SDK CDC for RP2040
|
||||
#else
|
||||
#define USBD_PID (0x0009) // Raspberry Pi Pico SDK CDC
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifndef USBD_MANUFACTURER
|
||||
#define USBD_MANUFACTURER "Raspberry Pi"
|
||||
#endif
|
||||
|
||||
#ifndef USBD_PRODUCT
|
||||
#define USBD_PRODUCT "Pico"
|
||||
#endif
|
||||
|
||||
#define TUD_RPI_RESET_DESC_LEN 9
|
||||
#if !PICO_STDIO_CHERRYUSB_DEVICE_SELF_POWERED
|
||||
#define USBD_CONFIGURATION_DESCRIPTOR_ATTRIBUTE USB_CONFIG_BUS_POWERED
|
||||
#define USBD_MAX_POWER_MA (250)
|
||||
#else
|
||||
#define USBD_CONFIGURATION_DESCRIPTOR_ATTRIBUTE USB_CONFIG_SELF_POWERED
|
||||
#define USBD_MAX_POWER_MA (1)
|
||||
#endif
|
||||
|
||||
#define USBD_ITF_CDC (0) // needs 2 interfaces
|
||||
#if !PICO_STDIO_CHERRYUSB_ENABLE_RESET_VIA_VENDOR_INTERFACE
|
||||
#define USBD_ITF_MAX (2)
|
||||
#else
|
||||
#define USBD_ITF_RPI_RESET (2)
|
||||
#define USBD_ITF_MAX (3)
|
||||
#endif
|
||||
|
||||
#define USBD_LANGID_STRING 1033
|
||||
|
||||
#if !PICO_STDIO_CHERRYUSB_ENABLE_RESET_VIA_VENDOR_INTERFACE
|
||||
/*!< config descriptor size */
|
||||
#define USB_CONFIG_SIZE (9 + CDC_ACM_DESCRIPTOR_LEN)
|
||||
#else
|
||||
#define USB_CONFIG_SIZE (9 + CDC_ACM_DESCRIPTOR_LEN + TUD_RPI_RESET_DESC_LEN)
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_USB_HS
|
||||
#define CDC_MAX_MPS 512
|
||||
#else
|
||||
#define CDC_MAX_MPS 64
|
||||
#endif
|
||||
|
||||
#define USBD_STR_0 (0x00)
|
||||
#define USBD_STR_MANUF (0x01)
|
||||
#define USBD_STR_PRODUCT (0x02)
|
||||
#define USBD_STR_SERIAL (0x03)
|
||||
#define USBD_STR_CDC (0x04)
|
||||
#define USBD_STR_RPI_RESET (0x05)
|
||||
|
||||
#if PICO_STDIO_CHERRYUSB_ENABLE_RESET_VIA_VENDOR_INTERFACE && PICO_STDIO_CHERRYUSB_RESET_INTERFACE_SUPPORT_MS_OS_20_DESCRIPTOR
|
||||
#define USBD_WINUSB_VENDOR_CODE 0x01
|
||||
|
||||
#define USBD_WEBUSB_ENABLE 0
|
||||
#define USBD_BULK_ENABLE 1
|
||||
#define USBD_WINUSB_ENABLE 1
|
||||
|
||||
/* WinUSB Microsoft OS 2.0 descriptor sizes */
|
||||
#define WINUSB_DESCRIPTOR_SET_HEADER_SIZE 10
|
||||
#define WINUSB_FUNCTION_SUBSET_HEADER_SIZE 8
|
||||
#define WINUSB_FEATURE_COMPATIBLE_ID_SIZE 20
|
||||
|
||||
#define FUNCTION_SUBSET_LEN 160
|
||||
#define DEVICE_INTERFACE_GUIDS_FEATURE_LEN 132
|
||||
|
||||
#define USBD_WINUSB_DESC_SET_LEN (WINUSB_DESCRIPTOR_SET_HEADER_SIZE + USBD_WEBUSB_ENABLE * FUNCTION_SUBSET_LEN + USBD_BULK_ENABLE * FUNCTION_SUBSET_LEN)
|
||||
|
||||
__ALIGN_BEGIN const uint8_t USBD_WinUSBDescriptorSetDescriptor[] = {
|
||||
WBVAL(WINUSB_DESCRIPTOR_SET_HEADER_SIZE), /* wLength */
|
||||
WBVAL(WINUSB_SET_HEADER_DESCRIPTOR_TYPE), /* wDescriptorType */
|
||||
0x00, 0x00, 0x03, 0x06, /* >= Win 8.1 */ /* dwWindowsVersion*/
|
||||
WBVAL(USBD_WINUSB_DESC_SET_LEN), /* wDescriptorSetTotalLength */
|
||||
#if (USBD_WEBUSB_ENABLE)
|
||||
WBVAL(WINUSB_FUNCTION_SUBSET_HEADER_SIZE), // wLength
|
||||
WBVAL(WINUSB_SUBSET_HEADER_FUNCTION_TYPE), // wDescriptorType
|
||||
0, // bFirstInterface USBD_WINUSB_IF_NUM
|
||||
0, // bReserved
|
||||
WBVAL(FUNCTION_SUBSET_LEN), // wSubsetLength
|
||||
WBVAL(WINUSB_FEATURE_COMPATIBLE_ID_SIZE), // wLength
|
||||
WBVAL(WINUSB_FEATURE_COMPATIBLE_ID_TYPE), // wDescriptorType
|
||||
'W', 'I', 'N', 'U', 'S', 'B', 0, 0, // CompatibleId
|
||||
0, 0, 0, 0, 0, 0, 0, 0, // SubCompatibleId
|
||||
WBVAL(DEVICE_INTERFACE_GUIDS_FEATURE_LEN), // wLength
|
||||
WBVAL(WINUSB_FEATURE_REG_PROPERTY_TYPE), // wDescriptorType
|
||||
WBVAL(WINUSB_PROP_DATA_TYPE_REG_MULTI_SZ), // wPropertyDataType
|
||||
WBVAL(42), // wPropertyNameLength
|
||||
'D', 0, 'e', 0, 'v', 0, 'i', 0, 'c', 0, 'e', 0,
|
||||
'I', 0, 'n', 0, 't', 0, 'e', 0, 'r', 0, 'f', 0, 'a', 0, 'c', 0, 'e', 0,
|
||||
'G', 0, 'U', 0, 'I', 0, 'D', 0, 's', 0, 0, 0,
|
||||
WBVAL(80), // wPropertyDataLength
|
||||
'{', 0,
|
||||
'9', 0, '2', 0, 'C', 0, 'E', 0, '6', 0, '4', 0, '6', 0, '2', 0, '-', 0,
|
||||
'9', 0, 'C', 0, '7', 0, '7', 0, '-', 0,
|
||||
'4', 0, '6', 0, 'F', 0, 'E', 0, '-', 0,
|
||||
'9', 0, '3', 0, '3', 0, 'B', 0, '-',
|
||||
0, '3', 0, '1', 0, 'C', 0, 'B', 0, '9', 0, 'C', 0, '5', 0, 'A', 0, 'A', 0, '3', 0, 'B', 0, '9', 0,
|
||||
'}', 0, 0, 0, 0, 0
|
||||
#endif
|
||||
#if USBD_BULK_ENABLE
|
||||
WBVAL(WINUSB_FUNCTION_SUBSET_HEADER_SIZE), /* wLength */
|
||||
WBVAL(WINUSB_SUBSET_HEADER_FUNCTION_TYPE), /* wDescriptorType */
|
||||
USBD_ITF_RPI_RESET, /* bFirstInterface USBD_ITF_RPI_RESET*/
|
||||
0, /* bReserved */
|
||||
WBVAL(FUNCTION_SUBSET_LEN), /* wSubsetLength */
|
||||
WBVAL(WINUSB_FEATURE_COMPATIBLE_ID_SIZE), /* wLength */
|
||||
WBVAL(WINUSB_FEATURE_COMPATIBLE_ID_TYPE), /* wDescriptorType */
|
||||
'W', 'I', 'N', 'U', 'S', 'B', 0, 0, /* CompatibleId*/
|
||||
0, 0, 0, 0, 0, 0, 0, 0, /* SubCompatibleId*/
|
||||
WBVAL(DEVICE_INTERFACE_GUIDS_FEATURE_LEN), /* wLength */
|
||||
WBVAL(WINUSB_FEATURE_REG_PROPERTY_TYPE), /* wDescriptorType */
|
||||
WBVAL(WINUSB_PROP_DATA_TYPE_REG_MULTI_SZ), /* wPropertyDataType */
|
||||
WBVAL(42), /* wPropertyNameLength */
|
||||
'D', 0, 'e', 0, 'v', 0, 'i', 0, 'c', 0, 'e', 0,
|
||||
'I', 0, 'n', 0, 't', 0, 'e', 0, 'r', 0, 'f', 0, 'a', 0, 'c', 0, 'e', 0,
|
||||
'G', 0, 'U', 0, 'I', 0, 'D', 0, 's', 0, 0, 0,
|
||||
WBVAL(80), /* wPropertyDataLength */
|
||||
'{', 0,
|
||||
'C', 0, 'D', 0, 'B', 0, '3', 0, 'B', 0, '5', 0, 'A', 0, 'D', 0, '-', 0,
|
||||
'2', 0, '9', 0, '3', 0, 'B', 0, '-', 0,
|
||||
'4', 0, '6', 0, '6', 0, '3', 0, '-', 0,
|
||||
'A', 0, 'A', 0, '3', 0, '6', 0, '-',
|
||||
0, '1', 0, 'A', 0, 'A', 0, 'E', 0, '4', 0, '6', 0, '4', 0, '6', 0, '3', 0, '7', 0, '7', 0, '6', 0,
|
||||
'}', 0, 0, 0, 0, 0
|
||||
#endif
|
||||
};
|
||||
|
||||
#define USBD_NUM_DEV_CAPABILITIES (USBD_WEBUSB_ENABLE + USBD_WINUSB_ENABLE)
|
||||
|
||||
#define USBD_WEBUSB_DESC_LEN 24
|
||||
#define USBD_WINUSB_DESC_LEN 28
|
||||
|
||||
#define USBD_BOS_WTOTALLENGTH (0x05 + \
|
||||
USBD_WEBUSB_DESC_LEN * USBD_WEBUSB_ENABLE + \
|
||||
USBD_WINUSB_DESC_LEN * USBD_WINUSB_ENABLE)
|
||||
|
||||
__ALIGN_BEGIN const uint8_t USBD_BinaryObjectStoreDescriptor[] = {
|
||||
0x05, /* bLength */
|
||||
0x0f, /* bDescriptorType */
|
||||
WBVAL(USBD_BOS_WTOTALLENGTH), /* wTotalLength */
|
||||
USBD_NUM_DEV_CAPABILITIES, /* bNumDeviceCaps */
|
||||
#if (USBD_WEBUSB_ENABLE)
|
||||
USBD_WEBUSB_DESC_LEN, /* bLength */
|
||||
0x10, /* bDescriptorType */
|
||||
USB_DEVICE_CAPABILITY_PLATFORM, /* bDevCapabilityType */
|
||||
0x00, /* bReserved */
|
||||
0x38, 0xB6, 0x08, 0x34, /* PlatformCapabilityUUID */
|
||||
0xA9, 0x09, 0xA0, 0x47,
|
||||
0x8B, 0xFD, 0xA0, 0x76,
|
||||
0x88, 0x15, 0xB6, 0x65,
|
||||
WBVAL(0x0100), /* 1.00 */ /* bcdVersion */
|
||||
USBD_WINUSB_VENDOR_CODE, /* bVendorCode */
|
||||
0, /* iLandingPage */
|
||||
#endif
|
||||
#if (USBD_WINUSB_ENABLE)
|
||||
USBD_WINUSB_DESC_LEN, /* bLength */
|
||||
0x10, /* bDescriptorType */
|
||||
USB_DEVICE_CAPABILITY_PLATFORM, /* bDevCapabilityType */
|
||||
0x00, /* bReserved */
|
||||
0xDF, 0x60, 0xDD, 0xD8, /* PlatformCapabilityUUID */
|
||||
0x89, 0x45, 0xC7, 0x4C,
|
||||
0x9C, 0xD2, 0x65, 0x9D,
|
||||
0x9E, 0x64, 0x8A, 0x9F,
|
||||
0x00, 0x00, 0x03, 0x06, /* >= Win 8.1 */ /* dwWindowsVersion*/
|
||||
WBVAL(USBD_WINUSB_DESC_SET_LEN), /* wDescriptorSetTotalLength */
|
||||
USBD_WINUSB_VENDOR_CODE, /* bVendorCode */
|
||||
0, /* bAltEnumCode */
|
||||
#endif
|
||||
};
|
||||
|
||||
struct usb_msosv2_descriptor msosv2_desc = {
|
||||
.vendor_code = USBD_WINUSB_VENDOR_CODE,
|
||||
.compat_id = USBD_WinUSBDescriptorSetDescriptor,
|
||||
.compat_id_len = USBD_WINUSB_DESC_SET_LEN,
|
||||
};
|
||||
|
||||
struct usb_bos_descriptor bos_desc = {
|
||||
.string = USBD_BinaryObjectStoreDescriptor,
|
||||
.string_len = USBD_BOS_WTOTALLENGTH
|
||||
};
|
||||
|
||||
static int rp_vendor_request_handler(uint8_t busid, struct usb_setup_packet *setup, uint8_t **data, uint32_t *len) {
|
||||
if (setup->wIndex == USBD_ITF_RPI_RESET) {
|
||||
#if PICO_STDIO_CHERRYUSB_RESET_INTERFACE_SUPPORT_RESET_TO_BOOTSEL
|
||||
if (setup->bRequest == RESET_REQUEST_BOOTSEL) {
|
||||
#ifdef PICO_STDIO_CHERRYUSB_RESET_BOOTSEL_ACTIVITY_LED
|
||||
int gpio = PICO_STDIO_CHERRYUSB_RESET_BOOTSEL_ACTIVITY_LED;
|
||||
bool active_low = PICO_STDIO_CHERRYUSB_RESET_BOOTSEL_ACTIVITY_LED_ACTIVE_LOW;
|
||||
#else
|
||||
int gpio = -1;
|
||||
bool active_low = false;
|
||||
#endif
|
||||
#if !PICO_STDIO_CHERRYUSB_RESET_BOOTSEL_FIXED_ACTIVITY_LED
|
||||
if (setup->wValue & 0x100) {
|
||||
gpio = setup->wValue >> 9u;
|
||||
}
|
||||
active_low = setup->wValue & 0x200;
|
||||
#endif
|
||||
rom_reset_usb_boot_extra(gpio, (setup->wValue & 0x7f) | PICO_STDIO_CHERRYUSB_RESET_BOOTSEL_INTERFACE_DISABLE_MASK, active_low);
|
||||
// does not return, otherwise we'd return true
|
||||
}
|
||||
#endif
|
||||
|
||||
#if PICO_STDIO_CHERRYUSB_RESET_INTERFACE_SUPPORT_RESET_TO_FLASH_BOOT
|
||||
if (setup->bRequest == RESET_REQUEST_FLASH) {
|
||||
watchdog_reboot(0, 0, PICO_STDIO_CHERRYUSB_RESET_RESET_TO_FLASH_DELAY_MS);
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
} else {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_USBDEV_ADVANCE_DESC
|
||||
static const uint8_t device_descriptor[] = {
|
||||
#if PICO_STDIO_CHERRYUSB_ENABLE_RESET_VIA_VENDOR_INTERFACE && PICO_STDIO_CHERRYUSB_RESET_INTERFACE_SUPPORT_MS_OS_20_DESCRIPTOR
|
||||
USB_DEVICE_DESCRIPTOR_INIT(USB_2_1, 0xEF, 0x02, 0x01, USBD_VID, USBD_PID, 0x0100, 0x01),
|
||||
#else
|
||||
USB_DEVICE_DESCRIPTOR_INIT(USB_2_0, 0xEF, 0x02, 0x01, USBD_VID, USBD_PID, 0x0100, 0x01),
|
||||
#endif
|
||||
};
|
||||
|
||||
static const uint8_t config_descriptor[] = {
|
||||
USB_CONFIG_DESCRIPTOR_INIT(USB_CONFIG_SIZE, USBD_ITF_MAX, 0x01, USBD_CONFIGURATION_DESCRIPTOR_ATTRIBUTE, USBD_MAX_POWER_MA),
|
||||
CDC_ACM_DESCRIPTOR_INIT(USBD_ITF_CDC, CDC_INT_EP, CDC_OUT_EP, CDC_IN_EP, CDC_MAX_MPS, USBD_STR_CDC),
|
||||
#if PICO_STDIO_CHERRYUSB_ENABLE_RESET_VIA_VENDOR_INTERFACE
|
||||
USB_INTERFACE_DESCRIPTOR_INIT(USBD_ITF_RPI_RESET, 0x00, 0x00, 0xFF, RESET_INTERFACE_SUBCLASS, RESET_INTERFACE_PROTOCOL, USBD_STR_RPI_RESET),
|
||||
#endif
|
||||
};
|
||||
|
||||
static const uint8_t device_quality_descriptor[] = {
|
||||
///////////////////////////////////////
|
||||
/// device qualifier descriptor
|
||||
///////////////////////////////////////
|
||||
0x0a,
|
||||
USB_DESCRIPTOR_TYPE_DEVICE_QUALIFIER,
|
||||
0x00,
|
||||
0x02,
|
||||
0x00,
|
||||
0x00,
|
||||
0x00,
|
||||
0x40,
|
||||
0x00,
|
||||
0x00,
|
||||
};
|
||||
|
||||
static char usbd_serial_str[PICO_UNIQUE_BOARD_ID_SIZE_BYTES * 2 + 1];
|
||||
|
||||
static const char *string_descriptors[] = {
|
||||
[USBD_STR_0] = (const char[]){ 0x09, 0x04 },
|
||||
[USBD_STR_MANUF] = USBD_MANUFACTURER,
|
||||
[USBD_STR_PRODUCT] = USBD_PRODUCT,
|
||||
[USBD_STR_SERIAL] = usbd_serial_str,
|
||||
[USBD_STR_CDC] = "Board CDC",
|
||||
#if PICO_STDIO_CHERRYUSB_ENABLE_RESET_VIA_VENDOR_INTERFACE
|
||||
[USBD_STR_RPI_RESET] = "Reset",
|
||||
#endif
|
||||
};
|
||||
|
||||
static const uint8_t *device_descriptor_callback(uint8_t speed) {
|
||||
return device_descriptor;
|
||||
}
|
||||
|
||||
static const uint8_t *config_descriptor_callback(uint8_t speed) {
|
||||
return config_descriptor;
|
||||
}
|
||||
|
||||
static const uint8_t *device_quality_descriptor_callback(uint8_t speed) {
|
||||
return device_quality_descriptor;
|
||||
}
|
||||
|
||||
static const char *string_descriptor_callback(uint8_t speed, uint8_t index) {
|
||||
if (index > 5) {
|
||||
return NULL;
|
||||
}
|
||||
// Assign the SN using the unique flash id
|
||||
if (!usbd_serial_str[0]) {
|
||||
pico_get_unique_board_id_string(usbd_serial_str, sizeof(usbd_serial_str));
|
||||
}
|
||||
|
||||
return string_descriptors[index];
|
||||
}
|
||||
|
||||
const struct usb_descriptor cdc_descriptor = {
|
||||
.device_descriptor_callback = device_descriptor_callback,
|
||||
.config_descriptor_callback = config_descriptor_callback,
|
||||
.device_quality_descriptor_callback = device_quality_descriptor_callback,
|
||||
.string_descriptor_callback = string_descriptor_callback,
|
||||
#if PICO_STDIO_CHERRYUSB_ENABLE_RESET_VIA_VENDOR_INTERFACE && PICO_STDIO_CHERRYUSB_RESET_INTERFACE_SUPPORT_MS_OS_20_DESCRIPTOR
|
||||
.msosv2_descriptor = &msosv2_desc,
|
||||
.bos_descriptor = &bos_desc
|
||||
#endif
|
||||
};
|
||||
#else
|
||||
/*!< global descriptor */
|
||||
static const uint8_t cdc_descriptor[] = {
|
||||
USB_DEVICE_DESCRIPTOR_INIT(USB_2_0, 0xEF, 0x02, 0x01, USBD_VID, USBD_PID, 0x0100, 0x01),
|
||||
USB_CONFIG_DESCRIPTOR_INIT(USB_CONFIG_SIZE, 0x02, 0x01, USB_CONFIG_BUS_POWERED, USBD_MAX_POWER),
|
||||
CDC_ACM_DESCRIPTOR_INIT(0x00, CDC_INT_EP, CDC_OUT_EP, CDC_IN_EP, CDC_MAX_MPS, 0x02),
|
||||
///////////////////////////////////////
|
||||
/// 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 */
|
||||
'C', 0x00, /* wcChar10 */
|
||||
'D', 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 */
|
||||
'2', 0x00, /* wcChar3 */
|
||||
'1', 0x00, /* wcChar4 */
|
||||
'2', 0x00, /* wcChar5 */
|
||||
'3', 0x00, /* wcChar6 */
|
||||
'4', 0x00, /* wcChar7 */
|
||||
'5', 0x00, /* wcChar8 */
|
||||
'6', 0x00, /* wcChar9 */
|
||||
#ifdef CONFIG_USB_HS
|
||||
///////////////////////////////////////
|
||||
/// device qualifier descriptor
|
||||
///////////////////////////////////////
|
||||
0x0a,
|
||||
USB_DESCRIPTOR_TYPE_DEVICE_QUALIFIER,
|
||||
0x00,
|
||||
0x02,
|
||||
0x00,
|
||||
0x00,
|
||||
0x00,
|
||||
0x40,
|
||||
0x00,
|
||||
0x00,
|
||||
#endif
|
||||
0x00
|
||||
};
|
||||
#endif
|
||||
|
||||
USB_NOCACHE_RAM_SECTION USB_MEM_ALIGNX uint8_t g_usb_read_buffer[CDC_MAX_MPS];
|
||||
|
||||
volatile bool g_usb_tx_busy_flag = false;
|
||||
volatile uint32_t g_usb_rx_count = 0;
|
||||
volatile uint32_t g_usb_rx_offset = 0;
|
||||
|
||||
static void usbd_event_handler(uint8_t busid, uint8_t event) {
|
||||
switch (event) {
|
||||
case USBD_EVENT_RESET:
|
||||
g_usb_tx_busy_flag = false;
|
||||
g_usb_rx_offset = 0;
|
||||
g_usb_rx_count = 0;
|
||||
break;
|
||||
case USBD_EVENT_CONNECTED:
|
||||
break;
|
||||
case USBD_EVENT_DISCONNECTED:
|
||||
break;
|
||||
case USBD_EVENT_RESUME:
|
||||
break;
|
||||
case USBD_EVENT_SUSPEND:
|
||||
break;
|
||||
case USBD_EVENT_CONFIGURED:
|
||||
g_usb_tx_busy_flag = false;
|
||||
/* setup first out ep read transfer */
|
||||
usbd_ep_start_read(busid, CDC_OUT_EP, g_usb_read_buffer, CDC_MAX_MPS);
|
||||
break;
|
||||
case USBD_EVENT_SET_REMOTE_WAKEUP:
|
||||
break;
|
||||
case USBD_EVENT_CLR_REMOTE_WAKEUP:
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void usbd_cdc_acm_bulk_out(uint8_t busid, uint8_t ep, uint32_t nbytes) {
|
||||
g_usb_rx_count = nbytes;
|
||||
g_usb_rx_offset = 0;
|
||||
}
|
||||
|
||||
void usbd_cdc_acm_bulk_in(uint8_t busid, uint8_t ep, uint32_t nbytes) {
|
||||
if ((nbytes % usbd_get_ep_mps(busid, ep)) == 0 && nbytes) {
|
||||
/* send zlp */
|
||||
usbd_ep_start_write(busid, CDC_IN_EP, NULL, 0);
|
||||
} else {
|
||||
g_usb_tx_busy_flag = false;
|
||||
}
|
||||
}
|
||||
|
||||
/*!< endpoint call back */
|
||||
struct usbd_endpoint cdc_out_ep = {
|
||||
.ep_addr = CDC_OUT_EP,
|
||||
.ep_cb = usbd_cdc_acm_bulk_out
|
||||
};
|
||||
|
||||
struct usbd_endpoint cdc_in_ep = {
|
||||
.ep_addr = CDC_IN_EP,
|
||||
.ep_cb = usbd_cdc_acm_bulk_in
|
||||
};
|
||||
|
||||
static struct usbd_interface intf0;
|
||||
static struct usbd_interface intf1;
|
||||
static struct usbd_interface intf2;
|
||||
|
||||
#if PICO_STDIO_CHERRYUSB_ENABLE_RESET_VIA_BAUD_RATE
|
||||
// Support for default BOOTSEL reset by changing baud rate
|
||||
void usbd_cdc_acm_set_line_coding(uint8_t busid, uint8_t intf, struct cdc_line_coding *line_coding) {
|
||||
(void)busid;
|
||||
(void)intf;
|
||||
if (line_coding->dwDTERate == PICO_STDIO_CHERRYUSB_RESET_MAGIC_BAUD_RATE) {
|
||||
#ifdef PICO_STDIO_CHERRYUSB_RESET_BOOTSEL_ACTIVITY_LED
|
||||
int gpio = PICO_STDIO_CHERRYUSB_RESET_BOOTSEL_ACTIVITY_LED;
|
||||
bool active_low = PICO_STDIO_CHERRYUSB_RESET_BOOTSEL_ACTIVITY_LED_ACTIVE_LOW;
|
||||
#else
|
||||
int gpio = -1;
|
||||
bool active_low = false;
|
||||
#endif
|
||||
rom_reset_usb_boot_extra(gpio, PICO_STDIO_CHERRYUSB_RESET_BOOTSEL_INTERFACE_DISABLE_MASK, active_low);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
static void cdc_acm_init(uint8_t busid, uintptr_t reg_base) {
|
||||
#ifdef CONFIG_USBDEV_ADVANCE_DESC
|
||||
usbd_desc_register(busid, &cdc_descriptor);
|
||||
#else
|
||||
usbd_desc_register(busid, cdc_descriptor);
|
||||
#endif
|
||||
#ifndef CONFIG_USBDEV_ADVANCE_DESC
|
||||
#if PICO_STDIO_CHERRYUSB_ENABLE_RESET_VIA_VENDOR_INTERFACE && PICO_STDIO_CHERRYUSB_RESET_INTERFACE_SUPPORT_MS_OS_20_DESCRIPTOR
|
||||
usbd_bos_desc_register(busid, &bos_desc);
|
||||
usbd_msosv2_desc_register(busid, &msosv2_desc);
|
||||
#endif
|
||||
#endif
|
||||
usbd_add_interface(busid, usbd_cdc_acm_init_intf(busid, &intf0));
|
||||
usbd_add_interface(busid, usbd_cdc_acm_init_intf(busid, &intf1));
|
||||
#if PICO_STDIO_CHERRYUSB_ENABLE_RESET_VIA_VENDOR_INTERFACE && PICO_STDIO_CHERRYUSB_RESET_INTERFACE_SUPPORT_MS_OS_20_DESCRIPTOR
|
||||
intf2.vendor_handler = rp_vendor_request_handler;
|
||||
usbd_add_interface(busid, &intf2);
|
||||
#endif
|
||||
usbd_add_endpoint(busid, &cdc_out_ep);
|
||||
usbd_add_endpoint(busid, &cdc_in_ep);
|
||||
usbd_initialize(busid, reg_base, usbd_event_handler);
|
||||
}
|
||||
|
||||
#if PICO_STDIO_CHERRYUSB_SUPPORT_CHARS_AVAILABLE_CALLBACK
|
||||
static void (*chars_available_callback)(void *);
|
||||
static void *chars_available_param;
|
||||
#endif
|
||||
|
||||
static mutex_t stdio_usb_mutex;
|
||||
|
||||
static void stdio_usb_out_chars(const char *buf, int length) {
|
||||
uint64_t last_avail_time;
|
||||
if (!mutex_try_enter_block_until(&stdio_usb_mutex, make_timeout_time_ms(PICO_STDIO_DEADLOCK_TIMEOUT_MS))) {
|
||||
return;
|
||||
}
|
||||
|
||||
last_avail_time = time_us_64();
|
||||
if (usb_device_is_configured(0)) {
|
||||
g_usb_tx_busy_flag = true;
|
||||
usbd_ep_start_write(0, CDC_IN_EP, buf, length);
|
||||
while (g_usb_tx_busy_flag) {
|
||||
if ((time_us_64() - last_avail_time) > PICO_STDIO_CHERRYUSB_STDOUT_TIMEOUT_US) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
}
|
||||
mutex_exit(&stdio_usb_mutex);
|
||||
}
|
||||
|
||||
static void stdio_usb_out_flush(void) {
|
||||
}
|
||||
|
||||
static int stdio_usb_in_chars(char *buf, int length) {
|
||||
int rc = PICO_ERROR_NO_DATA;
|
||||
uint32_t len;
|
||||
|
||||
if (g_usb_rx_count > 0) {
|
||||
len = MIN(g_usb_rx_count - g_usb_rx_offset, length);
|
||||
memcpy(buf, &g_usb_read_buffer[g_usb_rx_offset], len);
|
||||
g_usb_rx_offset += len;
|
||||
if (len > 0) {
|
||||
return len;
|
||||
} else {
|
||||
g_usb_rx_count = 0;
|
||||
/* setup first out ep read transfer */
|
||||
usbd_ep_start_read(0, CDC_OUT_EP, g_usb_read_buffer, CDC_MAX_MPS);
|
||||
return rc;
|
||||
}
|
||||
} else {
|
||||
return rc;
|
||||
}
|
||||
}
|
||||
|
||||
#if PICO_STDIO_CHERRYUSB_SUPPORT_CHARS_AVAILABLE_CALLBACK
|
||||
void stdio_usb_set_chars_available_callback(void (*fn)(void *), void *param) {
|
||||
chars_available_callback = fn;
|
||||
chars_available_param = param;
|
||||
}
|
||||
#endif
|
||||
|
||||
stdio_driver_t stdio_usb = {
|
||||
.out_chars = stdio_usb_out_chars,
|
||||
.out_flush = stdio_usb_out_flush,
|
||||
.in_chars = stdio_usb_in_chars,
|
||||
#if PICO_STDIO_CHERRYUSB_SUPPORT_CHARS_AVAILABLE_CALLBACK
|
||||
.set_chars_available_callback = stdio_usb_set_chars_available_callback,
|
||||
#endif
|
||||
#if PICO_STDIO_ENABLE_CRLF_SUPPORT
|
||||
.crlf_enabled = PICO_STDIO_CHERRYUSB_DEFAULT_CRLF
|
||||
#endif
|
||||
};
|
||||
|
||||
bool stdio_usb_init(void) {
|
||||
if (get_core_num() != alarm_pool_core_num(alarm_pool_get_default())) {
|
||||
// included an assertion here rather than just returning false, as this is likely
|
||||
// a coding bug, rather than anything else.
|
||||
assert(false);
|
||||
return false;
|
||||
}
|
||||
#if !PICO_NO_BI_STDIO_USB
|
||||
bi_decl_if_func_used(bi_program_feature("USB stdin / stdout"));
|
||||
#endif
|
||||
|
||||
cdc_acm_init(0, 0);
|
||||
|
||||
if (!mutex_is_initialized(&stdio_usb_mutex))
|
||||
mutex_init(&stdio_usb_mutex);
|
||||
bool rc = true;
|
||||
if (rc) {
|
||||
stdio_set_driver_enabled(&stdio_usb, true);
|
||||
#if PICO_STDIO_CHERRYUSB_CONNECT_WAIT_TIMEOUT_MS
|
||||
#if PICO_STDIO_CHERRYUSB_CONNECT_WAIT_TIMEOUT_MS > 0
|
||||
absolute_time_t until = make_timeout_time_ms(PICO_STDIO_CHERRYUSB_CONNECT_WAIT_TIMEOUT_MS);
|
||||
#else
|
||||
absolute_time_t until = at_the_end_of_time;
|
||||
#endif
|
||||
do {
|
||||
if (usb_device_is_configured(0)) {
|
||||
#if PICO_STDIO_CHERRYUSB_CONNECT_WAIT_TIMEOUT_MS != 0
|
||||
sleep_ms(PICO_STDIO_CHERRYUSB_CONNECT_WAIT_TIMEOUT_MS);
|
||||
#endif
|
||||
break;
|
||||
}
|
||||
sleep_ms(10);
|
||||
} while (!time_reached(until));
|
||||
#endif
|
||||
}
|
||||
return rc;
|
||||
}
|
||||
|
||||
bool stdio_usb_deinit(void) {
|
||||
if (get_core_num() != alarm_pool_core_num(alarm_pool_get_default())) {
|
||||
// included an assertion here rather than just returning false, as this is likely
|
||||
// a coding bug, rather than anything else.
|
||||
assert(false);
|
||||
return false;
|
||||
}
|
||||
|
||||
usbd_deinitialize(0);
|
||||
|
||||
bool rc = true;
|
||||
|
||||
stdio_set_driver_enabled(&stdio_usb, false);
|
||||
|
||||
#if PICO_STDIO_CHERRYUSB_DEINIT_DELAY_MS != 0
|
||||
sleep_ms(PICO_STDIO_CHERRYUSB_DEINIT_DELAY_MS);
|
||||
#endif
|
||||
return rc;
|
||||
}
|
||||
#endif
|
Loading…
x
Reference in New Issue
Block a user