Skip to content

Commit a80bcf7

Browse files
authored
Merge pull request #313 from Builty/GP5
Migrating EEZ fixes and start of GP5 support
2 parents cce4e67 + 3d68e71 commit a80bcf7

File tree

189 files changed

+31161
-9844
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

189 files changed

+31161
-9844
lines changed
1.08 MB
Binary file not shown.
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
# 1. IDF version >= 6.0 does not have usb component: usb from IDF component manager will be used
2+
# 2. For linux target, we can't use IDF component manager to get usb component, we need to add it 'the old way'
3+
# with EXTRA_COMPONENT_DIRS because mocking of managed components is not supported yet.
4+
# This is acceptable workaround for testing.
5+
set(requires "")
6+
if((${IDF_VERSION_MAJOR} LESS 6) OR ("${IDF_TARGET}" STREQUAL "linux"))
7+
list(APPEND requires usb)
8+
endif()
9+
10+
idf_component_register(SRCS
11+
"midi_host.c"
12+
"midi_host_descriptor_parsing.c"
13+
INCLUDE_DIRS "include"
14+
PRIV_INCLUDE_DIRS "private_include" "include/esp_private"
15+
REQUIRES "${requires}"
16+
)
Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
/*
2+
* SPDX-FileCopyrightText: 2024-2025 Espressif Systems (Shanghai) CO LTD
3+
*
4+
* SPDX-License-Identifier: Apache-2.0
5+
*/
6+
7+
#pragma once
8+
9+
#include <stdint.h>
10+
#include <stdbool.h>
11+
#include <sys/queue.h> // For singly linked list
12+
13+
#include "freertos/FreeRTOS.h"
14+
#include "freertos/semphr.h" // For mutexes and semaphores
15+
16+
#include "usb/usb_host.h" // For USB device handle and transfers
17+
18+
// MIDI check macros
19+
#define MIDI_CHECK(cond, ret_val) ({ \
20+
if (!(cond)) { \
21+
return (ret_val); \
22+
} \
23+
})
24+
25+
#define MIDI_CHECK_FROM_CRIT(cond, ret_val) ({ \
26+
if (!(cond)) { \
27+
MIDI_EXIT_CRITICAL(); \
28+
return ret_val; \
29+
} \
30+
})
31+
32+
typedef struct midi_dev_s midi_dev_t;
33+
struct midi_dev_s {
34+
usb_device_handle_t dev_hdl; // USB device handle
35+
void *cb_arg; // Common argument for user's callbacks (data IN and Notification)
36+
struct {
37+
usb_transfer_t *out_xfer; // OUT data transfer
38+
usb_transfer_t *in_xfer; // IN data transfer
39+
midi_data_callback_t in_cb; // User's callback for async (non-blocking) data IN
40+
uint16_t in_mps; // IN endpoint Maximum Packet Size
41+
uint8_t *in_data_buffer_base; // Pointer to IN data buffer in usb_transfer_t
42+
const usb_intf_desc_t *intf_desc; // Pointer to data interface descriptor
43+
SemaphoreHandle_t out_mux; // OUT mutex
44+
} data;
45+
46+
struct {
47+
usb_transfer_t *xfer; // IN notification transfer
48+
const usb_intf_desc_t *intf_desc; // Pointer to notification interface descriptor, can be NULL if there is no notification channel in the device
49+
midi_host_dev_callback_t cb; // User's callback for device events
50+
} notif; // Structure with Notif pipe data
51+
52+
usb_transfer_t *ctrl_transfer; // CTRL (endpoint 0) transfer
53+
SemaphoreHandle_t ctrl_mux; // CTRL mutex
54+
int midi_func_desc_cnt; // Number of Midi Functional descriptors in following array
55+
const usb_standard_desc_t *(*midi_func_desc)[]; // Pointer to array of pointers to const usb_standard_desc_t
56+
SLIST_ENTRY(midi_dev_s) list_entry;
57+
};
Lines changed: 148 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,148 @@
1+
/*
2+
* SPDX-FileCopyrightText: 2015-2024 Espressif Systems (Shanghai) CO LTD
3+
*
4+
* SPDX-License-Identifier: Apache-2.0
5+
*/
6+
7+
#pragma once
8+
9+
#include <stdbool.h>
10+
#include "esp_err.h"
11+
#include "usb/usb_host.h"
12+
#include "usb/midi_host_types.h"
13+
14+
// Pass these to midi_host_open() to signal that you don't care about VID/PID of the opened device
15+
#define MIDI_HOST_ANY_VID (0)
16+
#define MIDI_HOST_ANY_PID (0)
17+
18+
#ifdef __cplusplus
19+
extern "C" {
20+
#endif
21+
22+
/**
23+
* @brief New USB device callback
24+
*
25+
* Provides already opened usb_dev, that will be closed after this callback returns.
26+
* This is useful for peeking device's descriptors, e.g. peeking VID/PID and loading proper driver.
27+
*
28+
* @attention This callback is called from USB Host context, so the MIDI device can't be opened here.
29+
*/
30+
typedef void (*midi_new_dev_callback_t)(usb_device_handle_t usb_dev);
31+
32+
/**
33+
* @brief Configuration structure of USB Host MIDI-ACM driver
34+
*
35+
*/
36+
typedef struct {
37+
size_t driver_task_stack_size; /**< Stack size of the driver's task */
38+
unsigned driver_task_priority; /**< Priority of the driver's task */
39+
int xCoreID; /**< Core affinity of the driver's task */
40+
midi_new_dev_callback_t new_dev_cb; /**< New USB device connected callback. Can be NULL. */
41+
} midi_host_driver_config_t;
42+
43+
/**
44+
* @brief Install MIDI driver
45+
*
46+
* - USB Host Library must already be installed before calling this function (via usb_host_install())
47+
* - This function should be called before calling any other MIDI driver functions
48+
*
49+
* @param[in] driver_config Driver configuration structure. If set to NULL, a default configuration will be used.
50+
* @return
51+
* - ESP_OK: Success
52+
* - ESP_ERR_INVALID_STATE: The MIDI driver is already installed or USB host library is not installed
53+
* - ESP_ERR_NO_MEM: Not enough memory for installing the driver
54+
*/
55+
esp_err_t midi_host_install(const midi_host_driver_config_t *driver_config);
56+
57+
/**
58+
* @brief Uninstall MIDI driver
59+
*
60+
* - Users must ensure that all MIDI devices must be closed via midi_host_close() before calling this function
61+
*
62+
* @return
63+
* - ESP_OK: Success
64+
* - ESP_ERR_INVALID_STATE: The MIDI driver is not installed or not all MIDI devices are closed
65+
* - ESP_ERR_NOT_FINISHED: The MIDI driver failed to uninstall completely
66+
*/
67+
esp_err_t midi_host_uninstall(void);
68+
69+
/**
70+
* @brief Register new USB device callback
71+
*
72+
* The callback will be called for every new USB device, not just MIDI-ACM class.
73+
*
74+
* @param[in] new_dev_cb New device callback function
75+
* @return
76+
* - ESP_OK: Success
77+
*/
78+
esp_err_t midi_host_register_new_dev_callback(midi_new_dev_callback_t new_dev_cb);
79+
80+
/**
81+
* @brief Open MIDI device
82+
*
83+
* The driver first looks for MIDI compliant descriptor, if it is not found the driver checks if the interface has 2 Bulk endpoints that can be used for data
84+
*
85+
* Use MIDI_HOST_ANY_* macros to signal that you don't care about the device's VID and PID. In this case, first USB device will be opened.
86+
* It is recommended to use this feature if only one device can ever be in the system (there is no USB HUB connected).
87+
*
88+
* @param[in] vid Device's Vendor ID, set to MIDI_HOST_ANY_VID for any
89+
* @param[in] pid Device's Product ID, set to MIDI_HOST_ANY_PID for any
90+
* @param[in] interface_idx Index of device's interface used for MIDI-ACM communication
91+
* @param[in] dev_config Configuration structure of the device
92+
* @param[out] midi_hdl_ret MIDI device handle
93+
* @return
94+
* - ESP_OK: Success
95+
* - ESP_ERR_INVALID_STATE: The MIDI driver is not installed
96+
* - ESP_ERR_INVALID_ARG: dev_config or midi_hdl_ret is NULL
97+
* - ESP_ERR_NO_MEM: Not enough memory for opening the device
98+
* - ESP_ERR_NOT_FOUND: USB device with specified VID/PID is not connected or does not have specified interface
99+
*/
100+
esp_err_t midi_host_open(uint16_t vid, uint16_t pid, uint8_t interface_idx, const midi_host_device_config_t *dev_config, midi_dev_hdl_t *midi_hdl_ret);
101+
102+
/**
103+
* @brief Close MIDI device and release its resources
104+
*
105+
* @note All in-flight transfers will be prematurely canceled.
106+
* @param[in] midi_hdl MIDI handle obtained from midi_host_open()
107+
* @return
108+
* - ESP_OK: Success - device closed
109+
* - ESP_ERR_INVALID_STATE: midi_hdl is NULL or the MIDI driver is not installed
110+
*/
111+
esp_err_t midi_host_close(midi_dev_hdl_t midi_hdl);
112+
113+
/**
114+
* @brief Transmit data - blocking mode
115+
*
116+
* @param midi_hdl MIDI handle obtained from midi_host_open()
117+
* @param[in] data Data to be sent
118+
* @param[in] data_len Data length
119+
* @param[in] timeout_ms Timeout in [ms]
120+
* @return esp_err_t
121+
*/
122+
esp_err_t midi_host_data_tx_blocking(midi_dev_hdl_t midi_hdl, const uint8_t *data, size_t data_len, uint32_t timeout_ms);
123+
124+
/**
125+
* @brief Print device's descriptors
126+
*
127+
* Device and full Configuration descriptors are printed in human readable format to stdout.
128+
*
129+
* @param midi_hdl MIDI handle obtained from midi_host_open()
130+
*/
131+
void midi_host_desc_print(midi_dev_hdl_t midi_hdl);
132+
133+
/**
134+
* @brief Get MIDI functional descriptor
135+
*
136+
* @param midi_hdl MIDI handle obtained from midi_host_open()
137+
* @param[in] desc_type Type of functional descriptor
138+
* @param[out] desc_out Pointer to the required descriptor
139+
* @return
140+
* - ESP_OK: Success
141+
* - ESP_ERR_INVALID_ARG: Invalid device or descriptor type
142+
* - ESP_ERR_NOT_FOUND: The required descriptor is not present in the device
143+
*/
144+
esp_err_t midi_host_midi_desc_get(midi_dev_hdl_t midi_hdl, const usb_standard_desc_t **desc_out);
145+
146+
#ifdef __cplusplus
147+
}
148+
#endif
Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
/*
2+
* SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD
3+
*
4+
* SPDX-License-Identifier: Apache-2.0
5+
*/
6+
7+
#pragma once
8+
9+
#include <stdint.h>
10+
#include <stdbool.h>
11+
12+
typedef struct midi_dev_s *midi_dev_hdl_t;
13+
14+
/**
15+
* @brief MIDI- Device Event types to upper layer
16+
*/
17+
typedef enum {
18+
MIDI_HOST_ERROR,
19+
MIDI_HOST_SERIAL_STATE,
20+
MIDI_HOST_NETWORK_CONNECTION,
21+
MIDI_HOST_DEVICE_DISCONNECTED
22+
} midi_host_dev_event_t;
23+
24+
/**
25+
* @brief MIDI- Device Event data structure
26+
*/
27+
typedef struct {
28+
midi_host_dev_event_t type;
29+
union {
30+
int error; //!< Error code from USB Host
31+
bool network_connected; //!< Network connection event
32+
midi_dev_hdl_t midi_hdl; //!< Disconnection event
33+
} data;
34+
} midi_host_dev_event_data_t;
35+
36+
/**
37+
* @brief Data receive callback type
38+
*
39+
* @param[in] data Pointer to received data
40+
* @param[in] data_len Length of received data in bytes
41+
* @param[in] user_arg User's argument passed to open function
42+
* @return true Received data was processed -> Flush RX buffer
43+
* @return false Received data was NOT processed -> Append new data to the buffer
44+
*/
45+
typedef bool (*midi_data_callback_t)(const uint8_t *data, size_t data_len, void *user_arg);
46+
47+
/**
48+
* @brief Device event callback type
49+
*
50+
* @param[in] event Event structure
51+
* @param[in] user_arg User's argument passed to open function
52+
*/
53+
typedef void (*midi_host_dev_callback_t)(const midi_host_dev_event_data_t *event, void *user_ctx);
54+
55+
/**
56+
* @brief Configuration structure of MIDI- device
57+
*/
58+
typedef struct {
59+
uint32_t connection_timeout_ms; /**< Timeout for USB device connection in [ms] */
60+
size_t out_buffer_size; /**< Maximum size of USB bulk out transfer, set to 0 for read-only devices */
61+
size_t in_buffer_size; /**< Maximum size of USB bulk in transfer */
62+
midi_host_dev_callback_t event_cb; /**< Device's event callback function. Can be NULL */
63+
midi_data_callback_t data_cb; /**< Device's data RX callback function. Can be NULL for write-only devices */
64+
void *user_arg; /**< User's argument that will be passed to the callbacks */
65+
} midi_host_device_config_t;

0 commit comments

Comments
 (0)