update TinyUSB examples for latest TinyUSB (#325)

This commit is contained in:
Graham Sanderson
2023-02-06 16:56:50 -06:00
committed by GitHub
parent 9600dec1f0
commit f3f5d9fe61
11 changed files with 196 additions and 90 deletions

View File

@@ -275,6 +275,17 @@ At the time of writing, there is only one host example available:
- tinyusb_host_cdc_msc_hid
### USB Dual Mode
USB Dual Mode uses PIO as a USB host controller and the RP2040 USB device controller as a device controller. All the USB dual examples come directly from the TinyUSB dual examples directory [here](https://github.com/hathach/tinyusb/tree/master/examples/dual).
Those that are supported on RP2040 devices are automatically included as part of the pico-examples
build as targets named `tinyusb_dual_<example_name>`, e.g. https://github.com/hathach/tinyusb/tree/master/examples/dual/host_hid_to_device_cdc
is built as `tinyusb_dual_host_hid_to_device_cdc`.
At the time of writing, there is only one dual example available:
- tinyusb_dual_host_hid_to_device_cdc
### Watchdog
App|Description

View File

@@ -7,4 +7,13 @@ if (TARGET tinyusb_host)
add_subdirectory(host)
else ()
message("Skipping TinyUSB host examples as TinyUSB is unavailable")
endif ()
if (TARGET tinyusb_pico_pio_usb)
if (CMAKE_C_COMPILER_ID STREQUAL "GNU" AND CMAKE_C_COMPILER_VERSION VERSION_GREATER_EQUAL 11.3)
message("Skipping TinyUSB dual examples, as TinyUSB hw/mcu/raspberry_pi/Pico-PIO-USB does not currently compile on GCC 11.3 or greater")
else()
add_subdirectory(dual)
endif()
else ()
message("Skipping TinyUSB dual examples, as TinyUSB hw/mcu/raspberry_pi/Pico-PIO-USB submodule unavailable")
endif ()

View File

@@ -223,7 +223,7 @@ void hid_task(void)
// Invoked when sent REPORT successfully to host
// Application can use this to send the next report
// Note: For composite reports, report[0] is report ID
void tud_hid_report_complete_cb(uint8_t instance, uint8_t const* report, uint8_t len)
void tud_hid_report_complete_cb(uint8_t instance, uint8_t const* report, uint16_t len)
{
(void) instance;
(void) len;

4
usb/dual/CMakeLists.txt Normal file
View File

@@ -0,0 +1,4 @@
set(FAMILY rp2040)
set(BOARD pico_sdk)
set(TINYUSB_FAMILY_PROJECT_NAME_PREFIX "tinyusb_dual_")
add_subdirectory(${PICO_TINYUSB_PATH}/examples/dual tinyusb_dual_examples)

View File

@@ -1,6 +1,8 @@
set(FAMILY rp2040)
set(BOARD pico_sdk)
set(TINYUSB_FAMILY_PROJECT_NAME_PREFIX "tinyusb_host_")
# Hack as some host examples use $TOP in their path
set(TOP ${PICO_TINYUSB_PATH})
add_subdirectory(${PICO_TINYUSB_PATH}/examples/host tinyusb_host_examples)
add_subdirectory(host_cdc_msc_hid)

View File

@@ -7,6 +7,7 @@ target_sources(host_cdc_msc_hid PUBLIC
${CMAKE_CURRENT_LIST_DIR}/hid_app.c
${CMAKE_CURRENT_LIST_DIR}/main.c
${CMAKE_CURRENT_LIST_DIR}/msc_app.c
${CMAKE_CURRENT_LIST_DIR}/cdc_app.c
)
# Make sure TinyUSB can find tusb_config.h

View File

@@ -0,0 +1,113 @@
/*
* The MIT License (MIT)
*
* Copyright (c) 2022, Ha Thach (tinyusb.org)
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*
* This file is part of the TinyUSB stack.
*/
#include "tusb.h"
#include "bsp/board.h"
//--------------------------------------------------------------------+
// MACRO TYPEDEF CONSTANT ENUM DECLARATION
//--------------------------------------------------------------------+
//------------- IMPLEMENTATION -------------//
size_t get_console_inputs(uint8_t* buf, size_t bufsize)
{
size_t count = 0;
while (count < bufsize)
{
int ch = board_getchar();
if ( ch <= 0 ) break;
buf[count] = (uint8_t) ch;
count++;
}
return count;
}
void cdc_app_task(void)
{
uint8_t buf[64+1]; // +1 for extra null character
uint32_t const bufsize = sizeof(buf)-1;
uint32_t count = get_console_inputs(buf, bufsize);
buf[count] = 0;
// loop over all mounted interfaces
for(uint8_t idx=0; idx<CFG_TUH_CDC; idx++)
{
if ( tuh_cdc_mounted(idx) )
{
// console --> cdc interfaces
if (count)
{
tuh_cdc_write(idx, buf, count);
tuh_cdc_write_flush(idx);
}
}
}
}
// Invoked when received new data
void tuh_cdc_rx_cb(uint8_t idx)
{
uint8_t buf[64+1]; // +1 for extra null character
uint32_t const bufsize = sizeof(buf)-1;
// forward cdc interfaces -> console
uint32_t count = tuh_cdc_read(idx, buf, bufsize);
buf[count] = 0;
printf((char*) buf);
}
void tuh_cdc_mount_cb(uint8_t idx)
{
tuh_cdc_itf_info_t itf_info = { 0 };
tuh_cdc_itf_get_info(idx, &itf_info);
printf("CDC Interface is mounted: address = %u, itf_num = %u\r\n", itf_info.daddr, itf_info.bInterfaceNumber);
#ifdef CFG_TUH_CDC_LINE_CODING_ON_ENUM
// CFG_TUH_CDC_LINE_CODING_ON_ENUM must be defined for line coding is set by tinyusb in enumeration
// otherwise you need to call tuh_cdc_set_line_coding() first
cdc_line_coding_t line_coding = { 0 };
if ( tuh_cdc_get_local_line_coding(idx, &line_coding) )
{
printf(" Baudrate: %lu, Stop Bits : %u\r\n", line_coding.bit_rate, line_coding.stop_bits);
printf(" Parity : %u, Data Width: %u\r\n", line_coding.parity , line_coding.data_bits);
}
#endif
}
void tuh_cdc_umount_cb(uint8_t idx)
{
tuh_cdc_itf_info_t itf_info = { 0 };
tuh_cdc_itf_get_info(idx, &itf_info);
printf("CDC Interface is unmounted: address = %u, itf_num = %u\r\n", itf_info.daddr, itf_info.bInterfaceNumber);
}

View File

@@ -247,7 +247,7 @@ static void process_generic_report(uint8_t dev_addr, uint8_t instance, uint8_t c
// Composite report, 1st byte is report ID, data starts from 2nd byte
uint8_t const rpt_id = report[0];
// Find report id in the arrray
// Find report id in the array
for(uint8_t i=0; i<rpt_count; i++)
{
if (rpt_id == rpt_info_arr[i].report_id )

View File

@@ -35,7 +35,7 @@
//--------------------------------------------------------------------+
void led_blinking_task(void);
extern void cdc_task(void);
extern void cdc_app_task(void);
extern void hid_app_task(void);
/*------------- MAIN -------------*/
@@ -45,38 +45,30 @@ int main(void)
printf("TinyUSB Host CDC MSC HID Example\r\n");
tusb_init();
// init host stack on configured roothub port
tuh_init(BOARD_TUH_RHPORT);
while (1)
{
// tinyusb host task
tuh_task();
led_blinking_task();
#if CFG_TUH_CDC
cdc_task();
#endif
#if CFG_TUH_HID
cdc_app_task();
hid_app_task();
#endif
}
return 0;
}
//--------------------------------------------------------------------+
// USB CDC
// TinyUSB Callbacks
//--------------------------------------------------------------------+
#if CFG_TUH_CDC
CFG_TUSB_MEM_SECTION static char serial_in_buffer[64] = { 0 };
void tuh_mount_cb(uint8_t dev_addr)
{
// application set-up
printf("A device with address %d is mounted\r\n", dev_addr);
tuh_cdc_receive(dev_addr, serial_in_buffer, sizeof(serial_in_buffer), true); // schedule first transfer
}
void tuh_umount_cb(uint8_t dev_addr)
@@ -85,29 +77,6 @@ void tuh_umount_cb(uint8_t dev_addr)
printf("A device with address %d is unmounted \r\n", dev_addr);
}
// invoked ISR context
void tuh_cdc_xfer_isr(uint8_t dev_addr, xfer_result_t event, cdc_pipeid_t pipe_id, uint32_t xferred_bytes)
{
(void) event;
(void) pipe_id;
(void) xferred_bytes;
printf(serial_in_buffer);
tu_memclr(serial_in_buffer, sizeof(serial_in_buffer));
tuh_cdc_receive(dev_addr, serial_in_buffer, sizeof(serial_in_buffer), true); // waiting for next data
}
void cdc_task(void)
{
}
#endif
//--------------------------------------------------------------------+
// TinyUSB Callbacks
//--------------------------------------------------------------------+
//--------------------------------------------------------------------+
// Blinking Task

View File

@@ -25,15 +25,16 @@
#include "tusb.h"
#if CFG_TUH_MSC
//--------------------------------------------------------------------+
// MACRO TYPEDEF CONSTANT ENUM DECLARATION
//--------------------------------------------------------------------+
static scsi_inquiry_resp_t inquiry_resp;
bool inquiry_complete_cb(uint8_t dev_addr, msc_cbw_t const* cbw, msc_csw_t const* csw)
bool inquiry_complete_cb(uint8_t dev_addr, tuh_msc_complete_data_t const * cb_data)
{
msc_cbw_t const* cbw = cb_data->cbw;
msc_csw_t const* csw = cb_data->csw;
if (csw->status != 0)
{
printf("Inquiry failed\r\n");
@@ -59,48 +60,12 @@ void tuh_msc_mount_cb(uint8_t dev_addr)
printf("A MassStorage device is mounted\r\n");
uint8_t const lun = 0;
tuh_msc_inquiry(dev_addr, lun, &inquiry_resp, inquiry_complete_cb);
//
// //------------- file system (only 1 LUN support) -------------//
// uint8_t phy_disk = dev_addr-1;
// disk_initialize(phy_disk);
//
// if ( disk_is_ready(phy_disk) )
// {
// if ( f_mount(phy_disk, &fatfs[phy_disk]) != FR_OK )
// {
// puts("mount failed");
// return;
// }
//
// f_chdrive(phy_disk); // change to newly mounted drive
// f_chdir("/"); // root as current dir
//
// cli_init();
// }
tuh_msc_inquiry(dev_addr, lun, &inquiry_resp, inquiry_complete_cb, 0);
}
void tuh_msc_umount_cb(uint8_t dev_addr)
{
(void) dev_addr;
printf("A MassStorage device is unmounted\r\n");
// uint8_t phy_disk = dev_addr-1;
//
// f_mount(phy_disk, NULL); // unmount disk
// disk_deinitialize(phy_disk);
//
// if ( phy_disk == f_get_current_drive() )
// { // active drive is unplugged --> change to other drive
// for(uint8_t i=0; i<CFG_TUH_DEVICE_MAX; i++)
// {
// if ( disk_is_ready(i) )
// {
// f_chdrive(i);
// cli_init(); // refractor, rename
// }
// }
// }
}
#endif

View File

@@ -30,27 +30,48 @@
extern "C" {
#endif
//--------------------------------------------------------------------+
// Board Specific Configuration
//--------------------------------------------------------------------+
#if CFG_TUSB_MCU == OPT_MCU_RP2040
// change to 1 if using pico-pio-usb as host controller for raspberry rp2040
#define CFG_TUH_RPI_PIO_USB 0
#define BOARD_TUH_RHPORT CFG_TUH_RPI_PIO_USB
#endif
// RHPort number used for host can be defined by board.mk, default to port 0
#ifndef BOARD_TUH_RHPORT
#define BOARD_TUH_RHPORT 0
#endif
// RHPort max operational speed can defined by board.mk
#ifndef BOARD_TUH_MAX_SPEED
#define BOARD_TUH_MAX_SPEED OPT_MODE_DEFAULT_SPEED
#endif
//--------------------------------------------------------------------
// COMMON CONFIGURATION
//--------------------------------------------------------------------
// defined by compiler flags for flexibility
#ifndef CFG_TUSB_MCU
#error CFG_TUSB_MCU must be defined
#endif
#if CFG_TUSB_MCU == OPT_MCU_LPC43XX || CFG_TUSB_MCU == OPT_MCU_LPC18XX || CFG_TUSB_MCU == OPT_MCU_MIMXRT10XX
#define CFG_TUSB_RHPORT0_MODE (OPT_MODE_HOST | OPT_MODE_HIGH_SPEED)
#else
#define CFG_TUSB_RHPORT0_MODE OPT_MODE_HOST
#error CFG_TUSB_MCU must be defined
#endif
#ifndef CFG_TUSB_OS
#define CFG_TUSB_OS OPT_OS_NONE
#define CFG_TUSB_OS OPT_OS_NONE
#endif
// CFG_TUSB_DEBUG is defined by compiler in DEBUG build
// #define CFG_TUSB_DEBUG 0
#ifndef CFG_TUSB_DEBUG
#define CFG_TUSB_DEBUG 0
#endif
// Enable Host stack
#define CFG_TUH_ENABLED 1
// Default is max speed that hardware controller could support with on-chip PHY
#define CFG_TUH_MAX_SPEED BOARD_TUH_MAX_SPEED
/* USB DMA on some MCUs can only access a specific SRAM region with restriction on alignment.
* Tinyusb use follows macros to declare transferring memory so that they can be put
@@ -74,7 +95,7 @@
// Size of buffer to hold descriptors and other data used for enumeration
#define CFG_TUH_ENUMERATION_BUFSIZE 256
#define CFG_TUH_HUB 1
#define CFG_TUH_HUB 1 // number of supported hubs
#define CFG_TUH_CDC 1
#define CFG_TUH_HID 4 // typical keyboard + mouse device can have 3-4 HID interfaces
#define CFG_TUH_MSC 1
@@ -87,6 +108,17 @@
#define CFG_TUH_HID_EPIN_BUFSIZE 64
#define CFG_TUH_HID_EPOUT_BUFSIZE 64
//------------- CDC -------------//
// Set Line Control state on enumeration/mounted:
// DTR ( bit 0), RTS (bit 1)
#define CFG_TUH_CDC_LINE_CONTROL_ON_ENUM 0x03
// Set Line Coding on enumeration/mounted, value for cdc_line_coding_t
// bit rate = 115200, 1 stop bit, no parity, 8 bit data width
#define CFG_TUH_CDC_LINE_CODING_ON_ENUM { 115200, CDC_LINE_CONDING_STOP_BITS_1, CDC_LINE_CODING_PARITY_NONE, 8 }
#ifdef __cplusplus
}
#endif