Skip to content

Commit 208d74f

Browse files
committed
Simple MIDI rx example
1 parent 3ac0b00 commit 208d74f

File tree

6 files changed

+279
-2
lines changed

6 files changed

+279
-2
lines changed

examples/host/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,3 +8,4 @@ family_initialize_project(tinyusb_host_examples ${CMAKE_CURRENT_LIST_DIR})
88
# family_add_subdirectory will filter what to actually add based on selected FAMILY
99
family_add_subdirectory(cdc_msc_hid)
1010
family_add_subdirectory(hid_controller)
11+
family_add_subdirectory(midi_rx)
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
cmake_minimum_required(VERSION 3.5)
2+
3+
include(${CMAKE_CURRENT_SOURCE_DIR}/../../../hw/bsp/family_support.cmake)
4+
5+
# gets PROJECT name for the example (e.g. <BOARD>-<DIR_NAME>)
6+
family_get_project_name(PROJECT ${CMAKE_CURRENT_LIST_DIR})
7+
8+
project(${PROJECT})
9+
10+
# Checks this example is valid for the family and initializes the project
11+
family_initialize_project(${PROJECT} ${CMAKE_CURRENT_LIST_DIR})
12+
13+
add_executable(${PROJECT})
14+
15+
# Example source
16+
target_sources(${PROJECT} PUBLIC
17+
${CMAKE_CURRENT_SOURCE_DIR}/src/main.c
18+
)
19+
20+
# Example include
21+
target_include_directories(${PROJECT} PUBLIC
22+
${CMAKE_CURRENT_SOURCE_DIR}/src
23+
)
24+
25+
# Configure compilation flags and libraries for the example... see the corresponding function
26+
# in hw/bsp/FAMILY/family.cmake for details.
27+
family_configure_host_example(${PROJECT})

examples/host/midi_rx/only.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
mcu:RP2040

examples/host/midi_rx/src/main.c

Lines changed: 152 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,152 @@
1+
/*
2+
* The MIT License (MIT)
3+
*
4+
* Copyright (c) 2019 Ha Thach (tinyusb.org)
5+
*
6+
* Permission is hereby granted, free of charge, to any person obtaining a copy
7+
* of this software and associated documentation files (the "Software"), to deal
8+
* in the Software without restriction, including without limitation the rights
9+
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10+
* copies of the Software, and to permit persons to whom the Software is
11+
* furnished to do so, subject to the following conditions:
12+
*
13+
* The above copyright notice and this permission notice shall be included in
14+
* all copies or substantial portions of the Software.
15+
*
16+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17+
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18+
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19+
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20+
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21+
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22+
* THE SOFTWARE.
23+
*
24+
*/
25+
26+
#include <stdlib.h>
27+
#include <stdio.h>
28+
#include <string.h>
29+
30+
#include "bsp/board.h"
31+
#include "tusb.h"
32+
#include "class/midi/midi_host.h"
33+
34+
35+
#if CFG_TUH_MIDI
36+
37+
//--------------------------------------------------------------------+
38+
// STATIC GLOBALS DECLARATION
39+
//--------------------------------------------------------------------+
40+
static uint8_t midi_dev_addr = 0;
41+
42+
//--------------------------------------------------------------------+
43+
// MACRO CONSTANT TYPEDEF PROTYPES
44+
//--------------------------------------------------------------------+
45+
void led_blinking_task(void);
46+
void midi_host_rx_task(void);
47+
48+
/*------------- MAIN -------------*/
49+
int main(void)
50+
{
51+
board_init();
52+
53+
printf("TinyUSB Host MIDI Example\r\n");
54+
55+
tusb_init();
56+
57+
while (1)
58+
{
59+
tuh_task();
60+
led_blinking_task();
61+
midi_host_rx_task();
62+
}
63+
64+
return 0;
65+
}
66+
67+
#endif
68+
69+
//--------------------------------------------------------------------+
70+
// Blinking Task
71+
//--------------------------------------------------------------------+
72+
void led_blinking_task(void)
73+
{
74+
const uint32_t interval_ms = 1000;
75+
static uint32_t start_ms = 0;
76+
77+
static bool led_state = false;
78+
79+
// Blink every interval ms
80+
if ( board_millis() - start_ms < interval_ms) return; // not enough time
81+
start_ms += interval_ms;
82+
83+
board_led_write(led_state);
84+
led_state = 1 - led_state; // toggle
85+
}
86+
87+
//--------------------------------------------------------------------+
88+
// MIDI host receive task
89+
//--------------------------------------------------------------------+
90+
void midi_host_rx_task(void)
91+
{
92+
// device must be attached and have at least one endpoint ready to receive a message
93+
if (!midi_dev_addr || !tuh_midi_configured(midi_dev_addr))
94+
{
95+
return;
96+
}
97+
if (tuh_midih_get_num_rx_cables(midi_dev_addr) < 1)
98+
{
99+
return;
100+
}
101+
tuh_midi_read_poll(midi_dev_addr);
102+
}
103+
104+
//--------------------------------------------------------------------+
105+
// TinyUSB Callbacks
106+
//--------------------------------------------------------------------+
107+
108+
// Invoked when device with hid interface is mounted
109+
// Report descriptor is also available for use. tuh_hid_parse_report_descriptor()
110+
// can be used to parse common/simple enough descriptor.
111+
// Note: if report descriptor length > CFG_TUH_ENUMERATION_BUFSIZE, it will be skipped
112+
// therefore report_desc = NULL, desc_len = 0
113+
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)
114+
{
115+
TU_LOG1("MIDI device address = %u, IN endpoint %u has %u cables, OUT endpoint %u has %u cables\r\n",
116+
dev_addr, in_ep & 0xf, num_cables_rx, out_ep & 0xf, num_cables_tx);
117+
118+
midi_dev_addr = dev_addr;
119+
}
120+
121+
// Invoked when device with hid interface is un-mounted
122+
void tuh_midi_umount_cb(uint8_t dev_addr, uint8_t instance)
123+
{
124+
TU_LOG1("MIDI device address = %d, instance = %d is unmounted\r\n", dev_addr, instance);
125+
126+
midi_dev_addr = 0;
127+
}
128+
129+
void tuh_midi_rx_cb(uint8_t dev_addr, uint32_t num_packets)
130+
{
131+
if (midi_dev_addr != dev_addr)
132+
{
133+
return;
134+
}
135+
136+
if(num_packets == 0)
137+
{
138+
return;
139+
}
140+
141+
uint8_t cable_num;
142+
uint8_t buffer[48];
143+
uint32_t bytes_read = tuh_midi_stream_read(dev_addr, &cable_num, buffer, sizeof(buffer));
144+
145+
TU_LOG1("Read bytes %u cable %u", bytes_read, cable_num);
146+
TU_LOG1_MEM(buffer, bytes_read, 2);
147+
}
148+
149+
void tuh_midi_tx_cb(uint8_t dev_addr)
150+
{
151+
(void ) dev_addr;
152+
}
Lines changed: 96 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,96 @@
1+
/*
2+
* The MIT License (MIT)
3+
*
4+
* Copyright (c) 2019 Ha Thach (tinyusb.org)
5+
*
6+
* Permission is hereby granted, free of charge, to any person obtaining a copy
7+
* of this software and associated documentation files (the "Software"), to deal
8+
* in the Software without restriction, including without limitation the rights
9+
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10+
* copies of the Software, and to permit persons to whom the Software is
11+
* furnished to do so, subject to the following conditions:
12+
*
13+
* The above copyright notice and this permission notice shall be included in
14+
* all copies or substantial portions of the Software.
15+
*
16+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17+
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18+
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19+
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20+
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21+
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22+
* THE SOFTWARE.
23+
*
24+
*/
25+
26+
#ifndef _TUSB_CONFIG_H_
27+
#define _TUSB_CONFIG_H_
28+
29+
#ifdef __cplusplus
30+
extern "C" {
31+
#endif
32+
33+
//--------------------------------------------------------------------
34+
// COMMON CONFIGURATION
35+
//--------------------------------------------------------------------
36+
37+
// defined by compiler flags for flexibility
38+
#ifndef CFG_TUSB_MCU
39+
#error CFG_TUSB_MCU must be defined
40+
#endif
41+
42+
#if CFG_TUSB_MCU == OPT_MCU_LPC43XX || CFG_TUSB_MCU == OPT_MCU_LPC18XX || CFG_TUSB_MCU == OPT_MCU_MIMXRT10XX
43+
#define CFG_TUSB_RHPORT0_MODE (OPT_MODE_HOST | OPT_MODE_HIGH_SPEED)
44+
#else
45+
#define CFG_TUSB_RHPORT0_MODE OPT_MODE_HOST
46+
#endif
47+
48+
#ifndef CFG_TUSB_OS
49+
#define CFG_TUSB_OS OPT_OS_NONE
50+
#endif
51+
52+
// CFG_TUSB_DEBUG is defined by compiler in DEBUG build
53+
// #define CFG_TUSB_DEBUG 0
54+
55+
/* USB DMA on some MCUs can only access a specific SRAM region with restriction on alignment.
56+
* Tinyusb use follows macros to declare transferring memory so that they can be put
57+
* into those specific section.
58+
* e.g
59+
* - CFG_TUSB_MEM SECTION : __attribute__ (( section(".usb_ram") ))
60+
* - CFG_TUSB_MEM_ALIGN : __attribute__ ((aligned(4)))
61+
*/
62+
#ifndef CFG_TUSB_MEM_SECTION
63+
#define CFG_TUSB_MEM_SECTION
64+
#endif
65+
66+
#ifndef CFG_TUSB_MEM_ALIGN
67+
#define CFG_TUSB_MEM_ALIGN __attribute__ ((aligned(4)))
68+
#endif
69+
70+
//--------------------------------------------------------------------
71+
// CONFIGURATION
72+
//--------------------------------------------------------------------
73+
74+
// Size of buffer to hold descriptors and other data used for enumeration
75+
#define CFG_TUH_ENUMERATION_BUFSIZE 256
76+
77+
#define CFG_TUH_HUB 1
78+
#define CFG_TUH_CDC 0
79+
#define CFG_TUH_HID 0 // typical keyboard + mouse device can have 3-4 HID interfaces
80+
#define CFG_TUH_MIDI 1 // there will be at most one MIDIStreaming Interface descriptor
81+
#define CFG_TUH_MSC 0
82+
#define CFG_TUH_VENDOR 0
83+
84+
// max device support (excluding hub device)
85+
#define CFG_TUH_DEVICE_MAX (CFG_TUH_HUB ? 4 : 1) // hub typically has 4 ports
86+
#define CFG_MIDI_HOST_DEVSTRINGS 1
87+
88+
//------------- HID -------------//
89+
#define CFG_TUH_HID_EPIN_BUFSIZE 64
90+
#define CFG_TUH_HID_EPOUT_BUFSIZE 64
91+
92+
#ifdef __cplusplus
93+
}
94+
#endif
95+
96+
#endif /* _TUSB_CONFIG_H_ */

src/class/midi/midi_host.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -333,10 +333,10 @@ bool midih_open(uint8_t rhport, uint8_t dev_addr, tusb_desc_interface_t const *d
333333
p_midi_host->out_jack_info[p_midi_host->next_out_jack].jack_id = p_mdoj->bJackID;
334334
p_midi_host->out_jack_info[p_midi_host->next_out_jack].jack_type = p_mdoj->bJackType;
335335
p_midi_host->out_jack_info[p_midi_host->next_out_jack].num_source_ids = p_mdoj->bNrInputPins;
336-
struct associated_jack_s {
336+
const struct associated_jack_s {
337337
uint8_t id;
338338
uint8_t pin;
339-
} *associated_jack = (struct associated_jack_s *)(p_desc+6);
339+
} *associated_jack = (const struct associated_jack_s *)(p_desc+6);
340340
int jack;
341341
for (jack = 0; jack < p_mdoj->bNrInputPins; jack++)
342342
{

0 commit comments

Comments
 (0)