Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
5 changes: 5 additions & 0 deletions boards/shields/olimex_shield_midi/Kconfig.shield
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
# Copyright (c) 2025 Titouan Christophe
# SPDX-License-Identifier: Apache-2.0

config SHIELD_OLIMEX_SHIELD_MIDI
def_bool $(shields_list_contains,olimex_shield_midi)
44 changes: 44 additions & 0 deletions boards/shields/olimex_shield_midi/doc/index.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
.. _olimex_shield_midi:

Olimex SHIELD-MIDI
##################

Overview
********

This is a MIDI shield which allows Arduino like boards to receive and send MIDI
messages. The shield allows direct wiring of up to 5 piezzo sensors and a
keyboard (with buttons and serial resistors) making it ideal for drums projects.

.. figure:: olimex_shield_midi.jpg
:align: center
:alt: Olimex SHIELD-MIDI

* MIDI-IN, MIDI-OUT and MIDI-THRU connectors
* 5 Piezzo sensors for drum implementation
* Keyboard for piano implementation
* Works with both 3.3V and 5V Arduino-like boards

More information on the `SHIELD-MIDI website`_.

Peripherals
***********

The following peripherals are available in Zephyr:

- MIDI IN/OUT: on ``midi_serial`` (set at 31.25kb/s)
- leds: ``midi_green_led``, ``midi_red_led``

Programming
***********

Set ``--shield olimex_shield_midi`` when you invoke ``west build``. For example:

.. zephyr-app-commands::
:zephyr-app: samples/net/midi2
:board: nucleo_f429zi
:shield: olimex_shield_midi
:goals: build

.. _SHIELD-MIDI website:
https://www.olimex.com/Products/Duino/Shields/SHIELD-MIDI/open-source-hardware
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
20 changes: 20 additions & 0 deletions boards/shields/olimex_shield_midi/olimex_shield_midi.overlay
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
/*
* Copyright (c) 2025 Titouan Christophe
* SPDX-License-Identifier: Apache-2.0
*/

/ {
leds {
midi_green_led: midi-green-led {
gpios = <&arduino_header 13 GPIO_ACTIVE_HIGH>;
};

midi_red_led: midi-red-led {
gpios = <&arduino_header 12 GPIO_ACTIVE_HIGH>;
};
};
};

midi_serial: &arduino_serial {
current-speed = <31250>;
};
7 changes: 7 additions & 0 deletions boards/shields/olimex_shield_midi/shield.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
shield:
name: olimex_shield_midi
full_name: Olimex SHIELD-MIDI
vendor: olimex
supported_features:
- led
- uart
1 change: 1 addition & 0 deletions doc/zephyr.doxyfile.in
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# Doxyfile 1.14.0

Check warning on line 1 in doc/zephyr.doxyfile.in

View workflow job for this annotation

GitHub Actions / Run compliance checks on patch series (PR)

Copyright missing

doc/zephyr.doxyfile.in:1 File has no SPDX-FileCopyrightText header, consider adding one.

Check warning on line 1 in doc/zephyr.doxyfile.in

View workflow job for this annotation

GitHub Actions / Run compliance checks on patch series (PR)

License missing

doc/zephyr.doxyfile.in:1 File has no SPDX-License-Identifier header, consider adding one.

# This file describes the settings to be used by the documentation system
# Doxygen (www.doxygen.org) for a project.
Expand Down Expand Up @@ -1017,6 +1017,7 @@
@ZEPHYR_BASE@/include/zephyr/sys/atomic.h \
@ZEPHYR_BASE@/include/ \
@ZEPHYR_BASE@/lib/libc/minimal/include/ \
@ZEPHYR_BASE@/lib/midi2/ \
@ZEPHYR_BASE@/subsys/testsuite/include/ \
@ZEPHYR_BASE@/subsys/testsuite/ztest/include/ \
@ZEPHYR_BASE@/subsys/secure_storage/include/ \
Expand Down
14 changes: 14 additions & 0 deletions dts/bindings/usb/zephyr,midi2-device.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -14,13 +14,21 @@ properties:
type: int
const: 1

label:
type: string
description: Name of the UMP (MIDI 2.0) endpoint

child-binding:
description: |
MIDI2 Group terminal block.
This represent a set of contiguous MIDI2 groups through which the
device exchange Universal MIDI Packets with the host.

properties:
label:
type: string
description: Name of the corresponding UMP Function block

reg:
type: array
required: true
Expand Down Expand Up @@ -49,3 +57,9 @@ child-binding:
- "output-only"
description: |
Type (data direction) of Group Terminals in this Block.

serial-31250bps:
type: boolean
description: |
This represent a physical MIDI1 serial port, which is limited
to a transmission speed of 31.25kb/s.
Comment on lines +61 to +65
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't know about this technically, but this sounds like something that might be more future-proof as an enum. you can decide.

183 changes: 171 additions & 12 deletions include/zephyr/audio/midi.h
Original file line number Diff line number Diff line change
Expand Up @@ -19,11 +19,22 @@ extern "C" {
* @ingroup audio_interface
* @since 4.1
* @version 0.1.0
* @see ump112: "Universal MIDI Packet (UMP) Format and MIDI 2.0 Protocol"
* Document version 1.1.2
* @{
*/

/**
* @defgroup ump112 Universal MIDI Packet (UMP) Format and MIDI 2.0 Protocol
* @ingroup midi_ump
* @{
* @details Definitions based on the following document
* <a href="https://midi.org/universal-midi-packet-ump-and-midi-2-0-protocol-specification">
* Universal MIDI Packet (UMP) Format and MIDI 2.0 Protocol
* With MIDI 1.0 Protocol in UMP Format - Document version 1.1.2
* (MIDI Association Document: M2-104-UM)
* </a>
* @}
*/

/**
* @brief Universal MIDI Packet container
*/
Expand Down Expand Up @@ -52,13 +63,17 @@ struct midi_ump {
#define UMP_MT_DATA_128 0x05
/** Flex Data Messages */
#define UMP_MT_FLEX_DATA 0x0d
/** UMP Stream Message */
/**
* UMP Stream Message
* @see midi_ump_stream
*/
#define UMP_MT_UMP_STREAM 0x0f
/** @} */

/**
* @brief Message Type field of a Universal MIDI Packet
* @param[in] ump Universal MIDI Packet
* @see midi_ump_mt
*/
#define UMP_MT(ump) \
((ump).data[0] >> 28)
Expand Down Expand Up @@ -86,14 +101,15 @@ struct midi_ump {
* @param[in] ump Universal MIDI Packet
*/
#define UMP_GROUP(ump) \
(((ump).data[0] >> 24) & 0x0f)
(((ump).data[0] >> 24) & BIT_MASK(4))

/**
* @brief Status byte of a MIDI channel voice or system message
* @param[in] ump Universal MIDI Packet (containing a MIDI1 event)
* @see midi_ump_sys
*/
#define UMP_MIDI_STATUS(ump) \
(((ump).data[0] >> 16) & 0xff)
(((ump).data[0] >> 16) & BIT_MASK(8))
/**
* @brief Command of a MIDI channel voice message
* @param[in] ump Universal MIDI Packet (containing a MIDI event)
Expand All @@ -106,19 +122,19 @@ struct midi_ump {
* @param[in] ump Universal MIDI Packet (containing a MIDI event)
*/
#define UMP_MIDI_CHANNEL(ump) \
(UMP_MIDI_STATUS(ump) & 0x0f)
(UMP_MIDI_STATUS(ump) & BIT_MASK(4))
/**
* @brief First parameter of a MIDI1 channel voice or system message
* @param[in] ump Universal MIDI Packet (containing a MIDI1 message)
*/
#define UMP_MIDI1_P1(ump) \
(((ump).data[0] >> 8) & 0x7f)
(((ump).data[0] >> 8) & BIT_MASK(7))
/**
* @brief Second parameter of a MIDI1 channel voice or system message
* @param[in] ump Universal MIDI Packet (containing a MIDI1 message)
*/
#define UMP_MIDI1_P2(ump) \
((ump).data[0] & 0x7f)
((ump).data[0] & BIT_MASK(7))

/**
* @brief Initialize a UMP with a MIDI1 channel voice message
Expand All @@ -143,9 +159,8 @@ struct midi_ump {
* @defgroup midi_ump_cmd MIDI commands
* @ingroup midi_ump
* @see ump112: 7.3 MIDI 1.0 Channel Voice Messages
*
* When UMP_MT(x)=UMP_MT_MIDI1_CHANNEL_VOICE or UMP_MT_MIDI2_CHANNEL_VOICE, then
* UMP_MIDI_COMMAND(x) may be one of:
* @remark When UMP_MT(x)=UMP_MT_MIDI1_CHANNEL_VOICE or UMP_MT_MIDI2_CHANNEL_VOICE,
* then UMP_MIDI_COMMAND(x) may be one of:
* @{
*/
#define UMP_MIDI_NOTE_OFF 0x8 /**< Note Off (p1=note number, p2=velocity) */
Expand Down Expand Up @@ -180,7 +195,8 @@ struct midi_ump {
* @ingroup midi_ump
* @see ump112: 7.6 System Common and System Real Time Messages
*
* When UMP_MT(x)=UMP_MT_SYS_RT_COMMON, UMP_MIDI_STATUS(x) may be one of:
* @remark When UMP_MT(x)=UMP_MT_SYS_RT_COMMON,
* then UMP_MIDI_STATUS(x) may be one of:
* @{
*/
#define UMP_SYS_MIDI_TIME_CODE 0xf1 /**< MIDI Time Code (no param) */
Expand All @@ -195,6 +211,149 @@ struct midi_ump {
#define UMP_SYS_RESET 0xff /**< Reset (no param) */
/** @} */


/**
* @defgroup midi_ump_stream UMP Stream specific fields
* @ingroup midi_ump
* @see ump112: 7.1 UMP Stream Messages
*
* @{
*/

/**
* @brief Format of a UMP Stream message
* @param[in] ump Universal MIDI Packet (containing a UMP Stream message)
* @see midi_ump_stream_format
*/
#define UMP_STREAM_FORMAT(ump) \
(((ump).data[0] >> 26) & BIT_MASK(2))

/**
* @defgroup midi_ump_stream_format UMP Stream format
* @ingroup midi_ump_stream
* @see ump112: 7.1 UMP Stream Messages: Format
* @remark When UMP_MT(x)=UMP_MT_UMP_STREAM,
* then UMP_STREAM_FORMAT(x) may be one of:
* @{
*/

/** Complete message in one UMP */
#define UMP_STREAM_FORMAT_COMPLETE 0x00
/** Start of a message which spans two or more UMPs */
#define UMP_STREAM_FORMAT_START 0x01
/** Continuing a message which spans three or more UMPs.
* There might be multiple Continue UMPs in a single message
*/
#define UMP_STREAM_FORMAT_CONTINUE 0x02
/** End of message which spans two or more UMPs */
#define UMP_STREAM_FORMAT_END 0x03

/** @} */

/**
* @brief Status field of a UMP Stream message
* @param[in] ump Universal MIDI Packet (containing a UMP Stream message)
* @see midi_ump_stream_status
*/
#define UMP_STREAM_STATUS(ump) \
(((ump).data[0] >> 16) & BIT_MASK(10))

/**
* @defgroup midi_ump_stream_status UMP Stream status
* @ingroup midi_ump_stream
* @see ump112: 7.1 UMP Stream Messages
* @remark When UMP_MT(x)=UMP_MT_UMP_STREAM,
* then UMP_STREAM_STATUS(x) may be one of:
* @{
*/

/** Endpoint Discovery Message */
#define UMP_STREAM_STATUS_EP_DISCOVERY 0x00
/** Endpoint Info Notification Message */
#define UMP_STREAM_STATUS_EP_INFO 0x01
/** Device Identity Notification Message */
#define UMP_STREAM_STATUS_DEVICE_IDENT 0x02
/** Endpoint Name Notification */
#define UMP_STREAM_STATUS_EP_NAME 0x03
/** Product Instance Id Notification Message */
#define UMP_STREAM_STATUS_PROD_ID 0x04
/** Stream Configuration Request Message */
#define UMP_STREAM_STATUS_CONF_REQ 0x05
/** Stream Configuration Notification Message */
#define UMP_STREAM_STATUS_CONF_NOTIF 0x06
/** Function Block Discovery Message */
#define UMP_STREAM_STATUS_FB_DISCOVERY 0x10
/** Function Block Info Notification */
#define UMP_STREAM_STATUS_FB_INFO 0x11
/** Function Block Name Notification */
#define UMP_STREAM_STATUS_FB_NAME 0x12
/** @} */

/**
* @brief Filter bitmap of an Endpoint Discovery message
* @param[in] ump Universal MIDI Packet (containing an Endpoint Discovery message)
* @see ump112: 7.1.1 Endpoint Discovery Message
* @see midi_ump_ep_disc
*/
#define UMP_STREAM_EP_DISCOVERY_FILTER(ump) \
((ump).data[1] & BIT_MASK(8))

/**
* @defgroup midi_ump_ep_disc UMP Stream endpoint discovery message filter bits
* @ingroup midi_ump_stream
* @see ump112: 7.1.1 Fig. 12: Endpoint Discovery Message Filter Bitmap Field
* @remark When UMP_MT(x)=UMP_MT_UMP_STREAM and
* UMP_STREAM_STATUS(x)=UMP_STREAM_STATUS_EP_DISCOVERY,
* then UMP_STREAM_EP_DISCOVERY_FILTER(x) may be an ORed combination of:
* @{
*/

/** Requesting an Endpoint Info Notification */
#define UMP_EP_DISC_FILTER_EP_INFO BIT(0)
/** Requesting a Device Identity Notification */
#define UMP_EP_DISC_FILTER_DEVICE_ID BIT(1)
/** Requesting an Endpoint Name Notification */
#define UMP_EP_DISC_FILTER_EP_NAME BIT(2)
/** Requesting a Product Instance Id Notification */
#define UMP_EP_DISC_FILTER_PRODUCT_ID BIT(3)
/** Requesting a Stream Configuration Notification */
#define UMP_EP_DISC_FILTER_STREAM_CFG BIT(4)
/** @} */

/**
* @brief Filter bitmap of a Function Block Discovery message
* @param[in] ump Universal MIDI Packet (containing a Function Block Discovery message)
* @see ump112: 7.1.7 Function Block Discovery Message
* @see midi_ump_fb_disc
*/
#define UMP_STREAM_FB_DISCOVERY_FILTER(ump) \
((ump).data[0] & BIT_MASK(8))

/**
* @brief Block number requested in a Function Block Discovery message
* @param[in] ump Universal MIDI Packet (containing a Function Block Discovery message)
* @see ump112: 7.1.7 Function Block Discovery Message
*/
#define UMP_STREAM_FB_DISCOVERY_NUM(ump) \
(((ump).data[0] >> 8) & BIT_MASK(8))

/**
* @defgroup midi_ump_fb_disc UMP Stream Function Block discovery message filter bits
* @ingroup midi_ump_stream
* @see ump112: 7.1.7 Fig. 21: Function Block Discovery Filter Bitmap Field Format
* @remark When UMP_MT(x)=UMP_MT_UMP_STREAM and
* UMP_STREAM_STATUS(x)=UMP_STREAM_STATUS_FB_DISCOVERY,
* then UMP_STREAM_FB_DISCOVERY_FILTER(x) may be an ORed combination of:
* @{
*/
/** Requesting a Function Block Info Notification */
#define UMP_FB_DISC_FILTER_INFO BIT(0)
/** Requesting a Function Block Name Notification */
#define UMP_FB_DISC_FILTER_NAME BIT(1)
/** @} */

/** @} */

/** @} */

#ifdef __cplusplus
Expand Down
Loading
Loading