Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

RP2040 MIDI Host #1627

Open
wants to merge 29 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 20 commits
Commits
Show all changes
29 commits
Select commit Hold shift + click to select a range
2ddd74f
Add MIDI host support to tinyusb
rppicomidi Aug 12, 2022
70eefcb
Add hooks to allow cloning an attached USB device descriptor
rppicomidi Aug 25, 2022
3325e26
Make USB MIDI device code allow a device with no Audio Control interface
rppicomidi Aug 25, 2022
4fbf996
Get rid of implicit uint conversions
atoktoto Sep 8, 2022
19563b4
Simple MIDI rx example
atoktoto Sep 8, 2022
81de7f3
Add Makefile for the midi host example
atoktoto Sep 11, 2022
0763bc5
Fix printf statement
atoktoto Sep 11, 2022
c14e3e2
Fix unused errors when LOG=0
atoktoto Sep 11, 2022
a6d4b64
Removed unused function prototype
atoktoto Oct 2, 2022
21e003a
Added explicit conversions
atoktoto Nov 13, 2022
0a844f2
Fix usb hubs
atoktoto Nov 19, 2022
375e822
Merge branch 'hathach:master' into midihost
atoktoto Nov 19, 2022
34729b1
Fix usb-hub data transfer problems by AndrewCapon
atoktoto Nov 21, 2022
3ba0311
Explicit type conversion
atoktoto Nov 21, 2022
89eac75
Explicit type conversion
atoktoto Nov 21, 2022
b41f5ea
Merge branch 'master' into midihost
atoktoto Nov 21, 2022
87adc63
Merge branch 'master' into fork/atoktoto/midihost
hathach Feb 12, 2025
85247e5
clean up
hathach Feb 12, 2025
294fb26
pre-commit fix
hathach Feb 12, 2025
7c40523
fix host midi build
hathach Feb 12, 2025
86d371f
more ci fix
hathach Feb 12, 2025
e0b192b
- use CFG_TUH_MIDI as number of midi host instance
hathach Feb 12, 2025
bad6cbe
update midi host to use endpoint stream API
hathach Feb 13, 2025
ed88fc9
- remove tuh_midi_read_poll(), auto schedule EP in when set_config() …
hathach Feb 14, 2025
31a2696
- change signature of tuh_midi_mount/umount_cb()
hathach Feb 14, 2025
997771f
- rename tuh_midi_stream_flush() to tuh_midi_write_flush()
hathach Feb 14, 2025
6ebd362
Merge branch 'master' into fork/atoktoto/midihost
hathach Feb 21, 2025
b12c8a9
remove CFG_MIDI_HOST_DEVSTRINGS support, we will leave that for appli…
hathach Feb 21, 2025
35f72a9
add tuh_midi_descriptor_cb()
hathach Feb 23, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions examples/host/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -11,4 +11,5 @@ family_add_subdirectory(cdc_msc_hid)
family_add_subdirectory(cdc_msc_hid_freertos)
family_add_subdirectory(device_info)
family_add_subdirectory(hid_controller)
family_add_subdirectory(midi_rx)
family_add_subdirectory(msc_file_explorer)
32 changes: 32 additions & 0 deletions examples/host/midi_rx/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
cmake_minimum_required(VERSION 3.20)

include(${CMAKE_CURRENT_SOURCE_DIR}/../../../hw/bsp/family_support.cmake)

# gets PROJECT name for the example
family_get_project_name(PROJECT ${CMAKE_CURRENT_LIST_DIR})

project(${PROJECT} C CXX ASM)

# Checks this example is valid for the family and initializes the project
family_initialize_project(${PROJECT} ${CMAKE_CURRENT_LIST_DIR})

# Espressif has its own cmake build system
if(FAMILY STREQUAL "espressif")
return()
endif()

add_executable(${PROJECT})

# Example source
target_sources(${PROJECT} PUBLIC
${CMAKE_CURRENT_SOURCE_DIR}/src/main.c
)

# Example include
target_include_directories(${PROJECT} PUBLIC
${CMAKE_CURRENT_SOURCE_DIR}/src
)

# Configure compilation flags and libraries for the example without RTOS.
# See the corresponding function in hw/bsp/FAMILY/family.cmake for details.
family_configure_host_example(${PROJECT} noos)
13 changes: 13 additions & 0 deletions examples/host/midi_rx/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
include ../../build_system/make/make.mk

INC += \
src \
$(TOP)/hw \

# Example source
EXAMPLE_SOURCE += \
src/main.c

SRC_C += $(addprefix $(CURRENT_PATH)/, $(EXAMPLE_SOURCE))

include ../../build_system/make/rules.mk
20 changes: 20 additions & 0 deletions examples/host/midi_rx/only.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
mcu:ESP32S2
mcu:ESP32S3
mcu:ESP32P4
mcu:KINETIS_KL
mcu:LPC175X_6X
mcu:LPC177X_8X
mcu:LPC18XX
mcu:LPC40XX
mcu:LPC43XX
mcu:MAX3421
mcu:MIMXRT1XXX
mcu:MIMXRT10XX
mcu:MIMXRT11XX
mcu:MSP432E4
mcu:RP2040
mcu:RX65X
mcu:RAXXX
mcu:STM32F4
mcu:STM32F7
mcu:STM32H7
158 changes: 158 additions & 0 deletions examples/host/midi_rx/src/main.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,158 @@
/*
* The MIT License (MIT)
*
* Copyright (c) 2019 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.
*
*/

#include <stdlib.h>
#include <stdio.h>
#include <string.h>

#include "bsp/board_api.h"
#include "tusb.h"

#if CFG_TUH_MIDI

//--------------------------------------------------------------------+
// STATIC GLOBALS DECLARATION
//--------------------------------------------------------------------+
static uint8_t midi_dev_addr = 0;

//--------------------------------------------------------------------+
// MACRO CONSTANT TYPEDEF PROTYPES
//--------------------------------------------------------------------+
void led_blinking_task(void);
void midi_host_rx_task(void);

/*------------- MAIN -------------*/
int main(void)
{
board_init();

printf("TinyUSB Host MIDI Example\r\n");

tusb_init();

while (1)
{
tuh_task();
led_blinking_task();
midi_host_rx_task();
}

return 0;
}

#endif

//--------------------------------------------------------------------+
// Blinking Task
//--------------------------------------------------------------------+
void led_blinking_task(void)
{
const uint32_t interval_ms = 1000;
static uint32_t start_ms = 0;

static bool led_state = false;

// Blink every interval ms
if ( board_millis() - start_ms < interval_ms) return; // not enough time
start_ms += interval_ms;

board_led_write(led_state);
led_state = 1 - led_state; // toggle
}

//--------------------------------------------------------------------+
// MIDI host receive task
//--------------------------------------------------------------------+
void midi_host_rx_task(void)
{
// device must be attached and have at least one endpoint ready to receive a message
if (!midi_dev_addr || !tuh_midi_configured(midi_dev_addr))
{
return;
}
if (tuh_midih_get_num_rx_cables(midi_dev_addr) < 1)
{
return;
}
tuh_midi_read_poll(midi_dev_addr);
}

//--------------------------------------------------------------------+
// TinyUSB Callbacks
//--------------------------------------------------------------------+

// Invoked when device with hid interface is mounted
// Report descriptor is also available for use. tuh_hid_parse_report_descriptor()
// can be used to parse common/simple enough descriptor.
// Note: if report descriptor length > CFG_TUH_ENUMERATION_BUFSIZE, it will be skipped
// therefore report_desc = NULL, desc_len = 0
void tuh_midi_mount_cb(uint8_t dev_addr, uint8_t in_ep, uint8_t out_ep, uint8_t num_cables_rx, uint16_t num_cables_tx)
{
(void ) in_ep;
(void ) out_ep;
(void ) num_cables_rx;
(void ) num_cables_tx;

TU_LOG1("MIDI device address = %u, IN endpoint %u has %u cables, OUT endpoint %u has %u cables\r\n",
dev_addr, in_ep & 0xf, num_cables_rx, out_ep & 0xf, num_cables_tx);

midi_dev_addr = dev_addr;
}

// Invoked when device with hid interface is un-mounted
void tuh_midi_umount_cb(uint8_t dev_addr, uint8_t instance)
{
(void ) dev_addr;
(void ) instance;

TU_LOG1("MIDI device address = %d, instance = %d is unmounted\r\n", dev_addr, instance);
midi_dev_addr = 0;
}

void tuh_midi_rx_cb(uint8_t dev_addr, uint32_t num_packets)
{
if (midi_dev_addr != dev_addr)
{
return;
}

if(num_packets == 0)
{
return;
}

uint8_t cable_num;
uint8_t buffer[48];
uint32_t bytes_read = tuh_midi_stream_read(dev_addr, &cable_num, buffer, sizeof(buffer));
(void ) bytes_read;

TU_LOG1("Read bytes %lu cable %u", bytes_read, cable_num);
TU_LOG1_MEM(buffer, bytes_read, 2);
}

void tuh_midi_tx_cb(uint8_t dev_addr)
{
(void ) dev_addr;
}
96 changes: 96 additions & 0 deletions examples/host/midi_rx/src/tusb_config.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
/*
* The MIT License (MIT)
*
* Copyright (c) 2019 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.
*
*/

#ifndef _TUSB_CONFIG_H_
#define _TUSB_CONFIG_H_

#ifdef __cplusplus
extern "C" {
#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
#endif

#ifndef CFG_TUSB_OS
#define CFG_TUSB_OS OPT_OS_NONE
#endif

// CFG_TUSB_DEBUG is defined by compiler in DEBUG build
// #define CFG_TUSB_DEBUG 0

/* 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
* into those specific section.
* e.g
* - CFG_TUSB_MEM SECTION : __attribute__ (( section(".usb_ram") ))
* - CFG_TUSB_MEM_ALIGN : __attribute__ ((aligned(4)))
*/
#ifndef CFG_TUSB_MEM_SECTION
#define CFG_TUSB_MEM_SECTION
#endif

#ifndef CFG_TUSB_MEM_ALIGN
#define CFG_TUSB_MEM_ALIGN __attribute__ ((aligned(4)))
#endif

//--------------------------------------------------------------------
// CONFIGURATION
//--------------------------------------------------------------------

// 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_CDC 0
#define CFG_TUH_HID 0 // typical keyboard + mouse device can have 3-4 HID interfaces
#define CFG_TUH_MIDI 1 // there will be at most one MIDIStreaming Interface descriptor
#define CFG_TUH_MSC 0
#define CFG_TUH_VENDOR 0

// max device support (excluding hub device)
#define CFG_TUH_DEVICE_MAX (CFG_TUH_HUB ? 4 : 1) // hub typically has 4 ports
#define CFG_MIDI_HOST_DEVSTRINGS 1

//------------- HID -------------//
#define CFG_TUH_HID_EPIN_BUFSIZE 64
#define CFG_TUH_HID_EPOUT_BUFSIZE 64

#ifdef __cplusplus
}
#endif

#endif /* _TUSB_CONFIG_H_ */
1 change: 1 addition & 0 deletions hw/bsp/rp2040/family.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,7 @@ target_sources(tinyusb_host_base INTERFACE
${TOP}/src/host/hub.c
${TOP}/src/class/cdc/cdc_host.c
${TOP}/src/class/hid/hid_host.c
${TOP}/src/class/midi/midi_host.c
${TOP}/src/class/msc/msc_host.c
${TOP}/src/class/vendor/vendor_host.c
)
Expand Down
1 change: 1 addition & 0 deletions src/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ function(tinyusb_target_add TARGET)
${CMAKE_CURRENT_FUNCTION_LIST_DIR}/host/hub.c
${CMAKE_CURRENT_FUNCTION_LIST_DIR}/class/cdc/cdc_host.c
${CMAKE_CURRENT_FUNCTION_LIST_DIR}/class/hid/hid_host.c
${CMAKE_CURRENT_FUNCTION_LIST_DIR}/class/midi/midi_host.c
${CMAKE_CURRENT_FUNCTION_LIST_DIR}/class/msc/msc_host.c
${CMAKE_CURRENT_FUNCTION_LIST_DIR}/class/vendor/vendor_host.c
# typec
Expand Down
Loading
Loading