Add USB MIDI support for SAMD and nRF.
The API should be identical to using a UART for MIDI. Fixes #672
This commit is contained in:
parent
172311fad8
commit
b5e40f52c2
@ -1 +1 @@
|
|||||||
Subproject commit 3bb53273cd3770328f55ba317af3df0cce4333c1
|
Subproject commit 5804e56e3c2ab4480bf72d94d997f769a645af47
|
@ -89,13 +89,13 @@ BASE_CFLAGS = \
|
|||||||
ifeq ($(CHIP_FAMILY), samd21)
|
ifeq ($(CHIP_FAMILY), samd21)
|
||||||
CFLAGS += -Os -DNDEBUG
|
CFLAGS += -Os -DNDEBUG
|
||||||
# TinyUSB defines
|
# TinyUSB defines
|
||||||
CFLAGS += -DCFG_TUSB_MCU=OPT_MCU_SAMD21 -DCFG_TUD_CDC_RX_BUFSIZE=128 -DCFG_TUD_CDC_TX_BUFSIZE=128 -DCFG_TUD_MSC_BUFSIZE=512
|
CFLAGS += -DCFG_TUSB_MCU=OPT_MCU_SAMD21 -DCFG_TUD_MIDI_RX_BUFSIZE=128 -DCFG_TUD_CDC_RX_BUFSIZE=128 -DCFG_TUD_MIDI_TX_BUFSIZE=128 -DCFG_TUD_CDC_TX_BUFSIZE=128 -DCFG_TUD_MSC_BUFSIZE=512
|
||||||
endif
|
endif
|
||||||
|
|
||||||
ifeq ($(CHIP_FAMILY), samd51)
|
ifeq ($(CHIP_FAMILY), samd51)
|
||||||
CFLAGS += -Os -DNDEBUG
|
CFLAGS += -Os -DNDEBUG
|
||||||
# TinyUSB defines
|
# TinyUSB defines
|
||||||
CFLAGS += -DCFG_TUSB_MCU=OPT_MCU_SAMD51 -DCFG_TUD_CDC_RX_BUFSIZE=256 -DCFG_TUD_CDC_TX_BUFSIZE=256 -DCFG_TUD_MSC_BUFSIZE=1024
|
CFLAGS += -DCFG_TUSB_MCU=OPT_MCU_SAMD51 -DCFG_TUD_MIDI_RX_BUFSIZE=128 -DCFG_TUD_CDC_RX_BUFSIZE=256 -DCFG_TUD_MIDI_TX_BUFSIZE=128 -DCFG_TUD_CDC_TX_BUFSIZE=256 -DCFG_TUD_MSC_BUFSIZE=1024
|
||||||
endif
|
endif
|
||||||
|
|
||||||
#Debugging/Optimization
|
#Debugging/Optimization
|
||||||
@ -103,9 +103,9 @@ ifeq ($(DEBUG), 1)
|
|||||||
# Turn on Python modules useful for debugging (e.g. uheap, ustack).
|
# Turn on Python modules useful for debugging (e.g. uheap, ustack).
|
||||||
CFLAGS += -ggdb
|
CFLAGS += -ggdb
|
||||||
# You may want to disable -flto if it interferes with debugging.
|
# You may want to disable -flto if it interferes with debugging.
|
||||||
CFLAGS += -flto
|
# CFLAGS += -flto
|
||||||
# You may want to enable these flags to make setting breakpoints easier.
|
# You may want to enable these flags to make setting breakpoints easier.
|
||||||
# CFLAGS += -fno-inline -fno-ipa-sra
|
CFLAGS += -fno-inline -fno-ipa-sra
|
||||||
ifeq ($(CHIP_FAMILY), samd21)
|
ifeq ($(CHIP_FAMILY), samd21)
|
||||||
CFLAGS += -DENABLE_MICRO_TRACE_BUFFER
|
CFLAGS += -DENABLE_MICRO_TRACE_BUFFER
|
||||||
endif
|
endif
|
||||||
@ -266,7 +266,6 @@ SRC_C = \
|
|||||||
lib/oofatfs/option/ccsbcs.c \
|
lib/oofatfs/option/ccsbcs.c \
|
||||||
lib/timeutils/timeutils.c \
|
lib/timeutils/timeutils.c \
|
||||||
lib/tinyusb/src/portable/microchip/$(CHIP_FAMILY)/dcd_$(CHIP_FAMILY).c \
|
lib/tinyusb/src/portable/microchip/$(CHIP_FAMILY)/dcd_$(CHIP_FAMILY).c \
|
||||||
lib/tinyusb/src/portable/microchip/$(CHIP_FAMILY)/hal_$(CHIP_FAMILY).c \
|
|
||||||
lib/utils/buffer_helper.c \
|
lib/utils/buffer_helper.c \
|
||||||
lib/utils/context_manager_helpers.c \
|
lib/utils/context_manager_helpers.c \
|
||||||
lib/utils/interrupt_char.c \
|
lib/utils/interrupt_char.c \
|
||||||
|
@ -237,6 +237,7 @@ extern const struct _mp_obj_module_t gamepad_module;
|
|||||||
extern const struct _mp_obj_module_t stage_module;
|
extern const struct _mp_obj_module_t stage_module;
|
||||||
extern const struct _mp_obj_module_t touchio_module;
|
extern const struct _mp_obj_module_t touchio_module;
|
||||||
extern const struct _mp_obj_module_t usb_hid_module;
|
extern const struct _mp_obj_module_t usb_hid_module;
|
||||||
|
extern const struct _mp_obj_module_t usb_midi_module;
|
||||||
extern const struct _mp_obj_module_t network_module;
|
extern const struct _mp_obj_module_t network_module;
|
||||||
extern const struct _mp_obj_module_t socket_module;
|
extern const struct _mp_obj_module_t socket_module;
|
||||||
extern const struct _mp_obj_module_t wiznet_module;
|
extern const struct _mp_obj_module_t wiznet_module;
|
||||||
@ -382,6 +383,7 @@ extern const struct _mp_obj_module_t wiznet_module;
|
|||||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_math), (mp_obj_t)&math_module }, \
|
{ MP_OBJ_NEW_QSTR(MP_QSTR_math), (mp_obj_t)&math_module }, \
|
||||||
{ MP_OBJ_NEW_QSTR(MP_QSTR__time), (mp_obj_t)&time_module }, \
|
{ MP_OBJ_NEW_QSTR(MP_QSTR__time), (mp_obj_t)&time_module }, \
|
||||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_usb_hid),(mp_obj_t)&usb_hid_module }, \
|
{ MP_OBJ_NEW_QSTR(MP_QSTR_usb_hid),(mp_obj_t)&usb_hid_module }, \
|
||||||
|
{ MP_OBJ_NEW_QSTR(MP_QSTR_usb_midi),(mp_obj_t)&usb_midi_module }, \
|
||||||
TOUCHIO_MODULE \
|
TOUCHIO_MODULE \
|
||||||
EXTRA_BUILTIN_MODULES
|
EXTRA_BUILTIN_MODULES
|
||||||
|
|
||||||
@ -410,6 +412,7 @@ extern const struct _mp_obj_module_t wiznet_module;
|
|||||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_math), (mp_obj_t)&math_module }, \
|
{ MP_OBJ_NEW_QSTR(MP_QSTR_math), (mp_obj_t)&math_module }, \
|
||||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_time), (mp_obj_t)&time_module }, \
|
{ MP_OBJ_NEW_QSTR(MP_QSTR_time), (mp_obj_t)&time_module }, \
|
||||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_usb_hid),(mp_obj_t)&usb_hid_module }, \
|
{ MP_OBJ_NEW_QSTR(MP_QSTR_usb_hid),(mp_obj_t)&usb_hid_module }, \
|
||||||
|
{ MP_OBJ_NEW_QSTR(MP_QSTR_usb_midi),(mp_obj_t)&usb_midi_module }, \
|
||||||
TOUCHIO_MODULE \
|
TOUCHIO_MODULE \
|
||||||
EXTRA_BUILTIN_MODULES
|
EXTRA_BUILTIN_MODULES
|
||||||
#endif
|
#endif
|
||||||
|
@ -75,7 +75,7 @@ LDFLAGS += -mthumb -mabi=aapcs -T $(LD_FILE) -L boards/
|
|||||||
LDFLAGS += -Wl,--gc-sections
|
LDFLAGS += -Wl,--gc-sections
|
||||||
|
|
||||||
# TinyUSB defines
|
# TinyUSB defines
|
||||||
CFLAGS += -DCFG_TUSB_MCU=OPT_MCU_NRF5X -DCFG_TUD_CDC_RX_BUFSIZE=1024 -DCFG_TUD_CDC_TX_BUFSIZE=1024 -DCFG_TUD_MSC_BUFSIZE=4096
|
CFLAGS += -DCFG_TUSB_MCU=OPT_MCU_NRF5X -DCFG_TUD_CDC_RX_BUFSIZE=1024 -DCFG_TUD_CDC_TX_BUFSIZE=1024 -DCFG_TUD_MSC_BUFSIZE=4096 -DCFG_TUD_MIDI_RX_BUFSIZE=128 -DCFG_TUD_MIDI_TX_BUFSIZE=128
|
||||||
|
|
||||||
#Debugging/Optimization
|
#Debugging/Optimization
|
||||||
ifeq ($(DEBUG), 1)
|
ifeq ($(DEBUG), 1)
|
||||||
|
@ -175,6 +175,7 @@ extern const struct _mp_obj_module_t supervisor_module;
|
|||||||
extern const struct _mp_obj_module_t gamepad_module;
|
extern const struct _mp_obj_module_t gamepad_module;
|
||||||
extern const struct _mp_obj_module_t neopixel_write_module;
|
extern const struct _mp_obj_module_t neopixel_write_module;
|
||||||
extern const struct _mp_obj_module_t usb_hid_module;
|
extern const struct _mp_obj_module_t usb_hid_module;
|
||||||
|
extern const struct _mp_obj_module_t usb_midi_module;
|
||||||
extern const struct _mp_obj_module_t bleio_module;
|
extern const struct _mp_obj_module_t bleio_module;
|
||||||
|
|
||||||
#if MICROPY_PY_BLEIO
|
#if MICROPY_PY_BLEIO
|
||||||
@ -207,6 +208,7 @@ extern const struct _mp_obj_module_t bleio_module;
|
|||||||
{ MP_OBJ_NEW_QSTR (MP_QSTR_time ), (mp_obj_t)&time_module }, \
|
{ MP_OBJ_NEW_QSTR (MP_QSTR_time ), (mp_obj_t)&time_module }, \
|
||||||
{ MP_OBJ_NEW_QSTR (MP_QSTR_json ), (mp_obj_t)&mp_module_ujson }, \
|
{ MP_OBJ_NEW_QSTR (MP_QSTR_json ), (mp_obj_t)&mp_module_ujson }, \
|
||||||
USBHID_MODULE \
|
USBHID_MODULE \
|
||||||
|
{ MP_OBJ_NEW_QSTR(MP_QSTR_usb_midi),(mp_obj_t)&usb_midi_module }, \
|
||||||
BLEIO_MODULE
|
BLEIO_MODULE
|
||||||
|
|
||||||
// extra built in names to add to the global namespace
|
// extra built in names to add to the global namespace
|
||||||
|
125
shared-bindings/usb_midi/PortIn.c
Normal file
125
shared-bindings/usb_midi/PortIn.c
Normal file
@ -0,0 +1,125 @@
|
|||||||
|
/*
|
||||||
|
* This file is part of the Micro Python project, http://micropython.org/
|
||||||
|
*
|
||||||
|
* The MIT License (MIT)
|
||||||
|
*
|
||||||
|
* Copyright (c) 2018 Scott Shawcroft for Adafruit Industries
|
||||||
|
*
|
||||||
|
* 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 <stdint.h>
|
||||||
|
|
||||||
|
#include "shared-bindings/usb_midi/PortIn.h"
|
||||||
|
#include "shared-bindings/util.h"
|
||||||
|
|
||||||
|
#include "py/ioctl.h"
|
||||||
|
#include "py/objproperty.h"
|
||||||
|
#include "py/runtime.h"
|
||||||
|
#include "py/stream.h"
|
||||||
|
#include "supervisor/shared/translate.h"
|
||||||
|
|
||||||
|
|
||||||
|
//| .. currentmodule:: usb_midi
|
||||||
|
//|
|
||||||
|
//| :class:`PortIn` -- receives midi commands over USB
|
||||||
|
//| ===================================================
|
||||||
|
//|
|
||||||
|
//| .. class:: PortIn()
|
||||||
|
//|
|
||||||
|
//| Not currently dynamically supported.
|
||||||
|
//|
|
||||||
|
|
||||||
|
STATIC mp_obj_t usb_midi_portin_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *pos_args) {
|
||||||
|
return mp_const_none;
|
||||||
|
}
|
||||||
|
|
||||||
|
// These are standard stream methods. Code is in py/stream.c.
|
||||||
|
//
|
||||||
|
//| .. method:: read(nbytes=None)
|
||||||
|
//|
|
||||||
|
//| Read characters. If ``nbytes`` is specified then read at most that many
|
||||||
|
//| bytes. Otherwise, read everything that arrives until the connection
|
||||||
|
//| times out. Providing the number of bytes expected is highly recommended
|
||||||
|
//| because it will be faster.
|
||||||
|
//|
|
||||||
|
//| :return: Data read
|
||||||
|
//| :rtype: bytes or None
|
||||||
|
//|
|
||||||
|
//| .. method:: readinto(buf, nbytes=None)
|
||||||
|
//|
|
||||||
|
//| Read bytes into the ``buf``. If ``nbytes`` is specified then read at most
|
||||||
|
//| that many bytes. Otherwise, read at most ``len(buf)`` bytes.
|
||||||
|
//|
|
||||||
|
//| :return: number of bytes read and stored into ``buf``
|
||||||
|
//| :rtype: bytes or None
|
||||||
|
//|
|
||||||
|
|
||||||
|
// These three methods are used by the shared stream methods.
|
||||||
|
STATIC mp_uint_t usb_midi_portin_read(mp_obj_t self_in, void *buf_in, mp_uint_t size, int *errcode) {
|
||||||
|
usb_midi_portin_obj_t *self = MP_OBJ_TO_PTR(self_in);
|
||||||
|
byte *buf = buf_in;
|
||||||
|
|
||||||
|
// make sure we want at least 1 char
|
||||||
|
if (size == 0) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return common_hal_usb_midi_portin_read(self, buf, size, errcode);
|
||||||
|
}
|
||||||
|
|
||||||
|
STATIC mp_uint_t usb_midi_portin_ioctl(mp_obj_t self_in, mp_uint_t request, mp_uint_t arg, int *errcode) {
|
||||||
|
usb_midi_portin_obj_t *self = MP_OBJ_TO_PTR(self_in);
|
||||||
|
mp_uint_t ret;
|
||||||
|
if (request == MP_IOCTL_POLL) {
|
||||||
|
mp_uint_t flags = arg;
|
||||||
|
ret = 0;
|
||||||
|
if ((flags & MP_IOCTL_POLL_RD) && common_hal_usb_midi_portin_bytes_available(self) > 0) {
|
||||||
|
ret |= MP_IOCTL_POLL_RD;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
*errcode = MP_EINVAL;
|
||||||
|
ret = MP_STREAM_ERROR;
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
STATIC const mp_rom_map_elem_t usb_midi_portin_locals_dict_table[] = {
|
||||||
|
// Standard stream methods.
|
||||||
|
{ MP_OBJ_NEW_QSTR(MP_QSTR_read), MP_ROM_PTR(&mp_stream_read_obj) },
|
||||||
|
{ MP_OBJ_NEW_QSTR(MP_QSTR_readinto), MP_ROM_PTR(&mp_stream_readinto_obj) },
|
||||||
|
};
|
||||||
|
STATIC MP_DEFINE_CONST_DICT(usb_midi_portin_locals_dict, usb_midi_portin_locals_dict_table);
|
||||||
|
|
||||||
|
STATIC const mp_stream_p_t usb_midi_portin_stream_p = {
|
||||||
|
.read = usb_midi_portin_read,
|
||||||
|
.write = NULL,
|
||||||
|
.ioctl = usb_midi_portin_ioctl,
|
||||||
|
.is_text = false,
|
||||||
|
};
|
||||||
|
|
||||||
|
const mp_obj_type_t usb_midi_portin_type = {
|
||||||
|
{ &mp_type_type },
|
||||||
|
.name = MP_QSTR_PortIn,
|
||||||
|
.make_new = usb_midi_portin_make_new,
|
||||||
|
.getiter = mp_identity_getiter,
|
||||||
|
.iternext = mp_stream_unbuffered_iter,
|
||||||
|
.protocol = &usb_midi_portin_stream_p,
|
||||||
|
.locals_dict = (mp_obj_dict_t*)&usb_midi_portin_locals_dict,
|
||||||
|
};
|
44
shared-bindings/usb_midi/PortIn.h
Normal file
44
shared-bindings/usb_midi/PortIn.h
Normal file
@ -0,0 +1,44 @@
|
|||||||
|
/*
|
||||||
|
* This file is part of the Micro Python project, http://micropython.org/
|
||||||
|
*
|
||||||
|
* The MIT License (MIT)
|
||||||
|
*
|
||||||
|
* Copyright (c) 2018 Scott Shawcroft for Adafruit Industries
|
||||||
|
*
|
||||||
|
* 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 MICROPY_INCLUDED_SHARED_BINDINGS_USB_MIDI_PORTIN_H
|
||||||
|
#define MICROPY_INCLUDED_SHARED_BINDINGS_USB_MIDI_PORTIN_H
|
||||||
|
|
||||||
|
#include "shared-module/usb_midi/PortIn.h"
|
||||||
|
|
||||||
|
extern const mp_obj_type_t usb_midi_portin_type;
|
||||||
|
|
||||||
|
// Construct an underlying UART object.
|
||||||
|
extern void common_hal_usb_midi_portin_construct(usb_midi_portin_obj_t *self,
|
||||||
|
uint8_t receiver_buffer_size);
|
||||||
|
// Read characters.
|
||||||
|
extern size_t common_hal_usb_midi_portin_read(usb_midi_portin_obj_t *self,
|
||||||
|
uint8_t *data, size_t len, int *errcode);
|
||||||
|
|
||||||
|
extern uint32_t common_hal_usb_midi_portin_bytes_available(usb_midi_portin_obj_t *self);
|
||||||
|
extern void common_hal_usb_midi_portin_clear_buffer(usb_midi_portin_obj_t *self);
|
||||||
|
|
||||||
|
#endif // MICROPY_INCLUDED_SHARED_BINDINGS_USB_MIDI_PORTIN_H
|
107
shared-bindings/usb_midi/PortOut.c
Normal file
107
shared-bindings/usb_midi/PortOut.c
Normal file
@ -0,0 +1,107 @@
|
|||||||
|
/*
|
||||||
|
* This file is part of the Micro Python project, http://micropython.org/
|
||||||
|
*
|
||||||
|
* The MIT License (MIT)
|
||||||
|
*
|
||||||
|
* Copyright (c) 2018 Scott Shawcroft for Adafruit Industries
|
||||||
|
*
|
||||||
|
* 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 <stdint.h>
|
||||||
|
|
||||||
|
#include "shared-bindings/usb_midi/PortOut.h"
|
||||||
|
#include "shared-bindings/util.h"
|
||||||
|
|
||||||
|
#include "py/ioctl.h"
|
||||||
|
#include "py/objproperty.h"
|
||||||
|
#include "py/runtime.h"
|
||||||
|
#include "py/stream.h"
|
||||||
|
#include "supervisor/shared/translate.h"
|
||||||
|
|
||||||
|
|
||||||
|
//| .. currentmodule:: usb_midi
|
||||||
|
//|
|
||||||
|
//| :class:`PortOut` -- sends midi messages to a computer over USB
|
||||||
|
//| ==============================================================
|
||||||
|
//|
|
||||||
|
//| .. class:: PortOut()
|
||||||
|
//|
|
||||||
|
//| Not currently dynamically supported.
|
||||||
|
//|
|
||||||
|
|
||||||
|
STATIC mp_obj_t usb_midi_portout_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *pos_args) {
|
||||||
|
return mp_const_none;
|
||||||
|
}
|
||||||
|
|
||||||
|
// These are standard stream methods. Code is in py/stream.c.
|
||||||
|
//
|
||||||
|
//| .. method:: write(buf)
|
||||||
|
//|
|
||||||
|
//| Write the buffer of bytes to the bus.
|
||||||
|
//|
|
||||||
|
//| :return: the number of bytes written
|
||||||
|
//| :rtype: int or None
|
||||||
|
//|
|
||||||
|
|
||||||
|
STATIC mp_uint_t usb_midi_portout_write(mp_obj_t self_in, const void *buf_in, mp_uint_t size, int *errcode) {
|
||||||
|
usb_midi_portout_obj_t *self = MP_OBJ_TO_PTR(self_in);
|
||||||
|
const byte *buf = buf_in;
|
||||||
|
|
||||||
|
return common_hal_usb_midi_portout_write(self, buf, size, errcode);
|
||||||
|
}
|
||||||
|
|
||||||
|
STATIC mp_uint_t usb_midi_portout_ioctl(mp_obj_t self_in, mp_uint_t request, mp_uint_t arg, int *errcode) {
|
||||||
|
usb_midi_portout_obj_t *self = MP_OBJ_TO_PTR(self_in);
|
||||||
|
mp_uint_t ret;
|
||||||
|
if (request == MP_IOCTL_POLL) {
|
||||||
|
mp_uint_t flags = arg;
|
||||||
|
ret = 0;
|
||||||
|
if ((flags & MP_IOCTL_POLL_WR) && common_hal_usb_midi_portout_ready_to_tx(self)) {
|
||||||
|
ret |= MP_IOCTL_POLL_WR;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
*errcode = MP_EINVAL;
|
||||||
|
ret = MP_STREAM_ERROR;
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
STATIC const mp_rom_map_elem_t usb_midi_portout_locals_dict_table[] = {
|
||||||
|
// Standard stream methods.
|
||||||
|
{ MP_OBJ_NEW_QSTR(MP_QSTR_write), MP_ROM_PTR(&mp_stream_write_obj) },
|
||||||
|
};
|
||||||
|
STATIC MP_DEFINE_CONST_DICT(usb_midi_portout_locals_dict, usb_midi_portout_locals_dict_table);
|
||||||
|
|
||||||
|
STATIC const mp_stream_p_t usb_midi_portout_stream_p = {
|
||||||
|
.read = NULL,
|
||||||
|
.write = usb_midi_portout_write,
|
||||||
|
.ioctl = usb_midi_portout_ioctl,
|
||||||
|
.is_text = false,
|
||||||
|
};
|
||||||
|
|
||||||
|
const mp_obj_type_t usb_midi_portout_type = {
|
||||||
|
{ &mp_type_type },
|
||||||
|
.name = MP_QSTR_PortOut,
|
||||||
|
.make_new = usb_midi_portout_make_new,
|
||||||
|
.getiter = mp_identity_getiter,
|
||||||
|
.iternext = mp_stream_unbuffered_iter,
|
||||||
|
.protocol = &usb_midi_portout_stream_p,
|
||||||
|
.locals_dict = (mp_obj_dict_t*)&usb_midi_portout_locals_dict,
|
||||||
|
};
|
44
shared-bindings/usb_midi/PortOut.h
Normal file
44
shared-bindings/usb_midi/PortOut.h
Normal file
@ -0,0 +1,44 @@
|
|||||||
|
/*
|
||||||
|
* This file is part of the Micro Python project, http://micropython.org/
|
||||||
|
*
|
||||||
|
* The MIT License (MIT)
|
||||||
|
*
|
||||||
|
* Copyright (c) 2018 Scott Shawcroft for Adafruit Industries
|
||||||
|
*
|
||||||
|
* 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 MICROPY_INCLUDED_SHARED_BINDINGS_USB_MIDI_PORTOUT_H
|
||||||
|
#define MICROPY_INCLUDED_SHARED_BINDINGS_USB_MIDI_PORTOUT_H
|
||||||
|
|
||||||
|
#include "shared-module/usb_midi/PortOut.h"
|
||||||
|
|
||||||
|
extern const mp_obj_type_t usb_midi_portout_type;
|
||||||
|
|
||||||
|
// Construct an underlying UART object.
|
||||||
|
extern void common_hal_usb_midi_portout_construct(usb_midi_portout_obj_t *self,
|
||||||
|
uint8_t receiver_buffer_size);
|
||||||
|
|
||||||
|
// Write characters. len is in characters NOT bytes!
|
||||||
|
extern size_t common_hal_usb_midi_portout_write(usb_midi_portout_obj_t *self,
|
||||||
|
const uint8_t *data, size_t len, int *errcode);
|
||||||
|
|
||||||
|
extern bool common_hal_usb_midi_portout_ready_to_tx(usb_midi_portout_obj_t *self);
|
||||||
|
|
||||||
|
#endif // MICROPY_INCLUDED_SHARED_BINDINGS_USB_MIDI_PORTOUT_H
|
78
shared-bindings/usb_midi/__init__.c
Normal file
78
shared-bindings/usb_midi/__init__.c
Normal file
@ -0,0 +1,78 @@
|
|||||||
|
/*
|
||||||
|
* This file is part of the MicroPython project, http://micropython.org/
|
||||||
|
*
|
||||||
|
* The MIT License (MIT)
|
||||||
|
*
|
||||||
|
* Copyright (c) 2018 Scott Shawcroft for Adafruit Industries
|
||||||
|
*
|
||||||
|
* 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 <stdint.h>
|
||||||
|
|
||||||
|
#include "py/obj.h"
|
||||||
|
#include "py/runtime.h"
|
||||||
|
|
||||||
|
#include "shared-bindings/usb_midi/__init__.h"
|
||||||
|
#include "shared-bindings/usb_midi/PortIn.h"
|
||||||
|
#include "shared-bindings/usb_midi/PortOut.h"
|
||||||
|
|
||||||
|
#include "py/runtime.h"
|
||||||
|
|
||||||
|
//| :mod:`usb_midi` --- MIDI over USB
|
||||||
|
//| =================================================
|
||||||
|
//|
|
||||||
|
//| .. module:: usb_midi
|
||||||
|
//| :synopsis: MIDI over USB
|
||||||
|
//|
|
||||||
|
//| The `usb_midi` module contains classes to transmit and receive MIDI messages over USB
|
||||||
|
//|
|
||||||
|
//| Libraries
|
||||||
|
//|
|
||||||
|
//| .. toctree::
|
||||||
|
//| :maxdepth: 3
|
||||||
|
//|
|
||||||
|
//| PortIn
|
||||||
|
//| PortOut
|
||||||
|
//|
|
||||||
|
//|
|
||||||
|
mp_map_elem_t usb_midi_module_globals_table[] = {
|
||||||
|
{ MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_usb_midi) },
|
||||||
|
{ MP_ROM_QSTR(MP_QSTR_ports), mp_const_empty_tuple },
|
||||||
|
{ MP_ROM_QSTR(MP_QSTR_PortIn), MP_OBJ_FROM_PTR(&usb_midi_portin_type) },
|
||||||
|
{ MP_ROM_QSTR(MP_QSTR_PortOut), MP_OBJ_FROM_PTR(&usb_midi_portout_type) },
|
||||||
|
};
|
||||||
|
|
||||||
|
// This isn't const so we can set ports dynamically.
|
||||||
|
mp_obj_dict_t usb_midi_module_globals = {
|
||||||
|
.base = {&mp_type_dict},
|
||||||
|
.map = {
|
||||||
|
.all_keys_are_qstrs = 1,
|
||||||
|
.is_fixed = 1,
|
||||||
|
.is_ordered = 1,
|
||||||
|
.used = MP_ARRAY_SIZE(usb_midi_module_globals_table),
|
||||||
|
.alloc = MP_ARRAY_SIZE(usb_midi_module_globals_table),
|
||||||
|
.table = usb_midi_module_globals_table,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
const mp_obj_module_t usb_midi_module = {
|
||||||
|
.base = { &mp_type_module },
|
||||||
|
.globals = (mp_obj_dict_t*)&usb_midi_module_globals,
|
||||||
|
};
|
34
shared-bindings/usb_midi/__init__.h
Normal file
34
shared-bindings/usb_midi/__init__.h
Normal file
@ -0,0 +1,34 @@
|
|||||||
|
/*
|
||||||
|
* This file is part of the MicroPython project, http://micropython.org/
|
||||||
|
*
|
||||||
|
* The MIT License (MIT)
|
||||||
|
*
|
||||||
|
* Copyright (c) 2018 Scott Shawcroft
|
||||||
|
*
|
||||||
|
* 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 MICROPY_INCLUDED_SHARED_BINDINGS_USB_MIDI___INIT___H
|
||||||
|
#define MICROPY_INCLUDED_SHARED_BINDINGS_USB_MIDI___INIT___H
|
||||||
|
|
||||||
|
#include "py/obj.h"
|
||||||
|
|
||||||
|
extern mp_obj_dict_t usb_midi_module_globals;
|
||||||
|
|
||||||
|
#endif // MICROPY_INCLUDED_SHARED_BINDINGS_USB_MIDI___INIT___H
|
40
shared-module/usb_midi/PortIn.c
Normal file
40
shared-module/usb_midi/PortIn.c
Normal file
@ -0,0 +1,40 @@
|
|||||||
|
/*
|
||||||
|
* This file is part of the MicroPython project, http://micropython.org/
|
||||||
|
*
|
||||||
|
* The MIT License (MIT)
|
||||||
|
*
|
||||||
|
* Copyright (c) 2018 Scott Shawcroft for Adafruit Industries
|
||||||
|
*
|
||||||
|
* 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 "shared-module/usb_midi/PortIn.h"
|
||||||
|
#include "supervisor/shared/translate.h"
|
||||||
|
#include "tusb.h"
|
||||||
|
|
||||||
|
void common_hal_usb_midi_portin_construct(usb_midi_portin_obj_t *self, uint8_t receiver_buffer_size) {
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t common_hal_usb_midi_portin_read(usb_midi_portin_obj_t *self, uint8_t *data, size_t len, int *errcode) {
|
||||||
|
return tud_midi_read(data, len);
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t common_hal_usb_midi_portin_bytes_available(usb_midi_portin_obj_t *self) {
|
||||||
|
return tud_midi_available();
|
||||||
|
}
|
39
shared-module/usb_midi/PortIn.h
Normal file
39
shared-module/usb_midi/PortIn.h
Normal file
@ -0,0 +1,39 @@
|
|||||||
|
/*
|
||||||
|
* This file is part of the MicroPython project, http://micropython.org/
|
||||||
|
*
|
||||||
|
* The MIT License (MIT)
|
||||||
|
*
|
||||||
|
* Copyright (c) 2018 Scott Shawcroft for Adafruit Industries
|
||||||
|
*
|
||||||
|
* 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 SHARED_MODULE_USB_MIDI_PORTIN_H
|
||||||
|
#define SHARED_MODULE_USB_MIDI_PORTIN_H
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <stdbool.h>
|
||||||
|
|
||||||
|
#include "py/obj.h"
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
mp_obj_base_t base;
|
||||||
|
} usb_midi_portin_obj_t;
|
||||||
|
|
||||||
|
#endif /* SHARED_MODULE_USB_MIDI_PORTIN_H */
|
40
shared-module/usb_midi/PortOut.c
Normal file
40
shared-module/usb_midi/PortOut.c
Normal file
@ -0,0 +1,40 @@
|
|||||||
|
/*
|
||||||
|
* This file is part of the MicroPython project, http://micropython.org/
|
||||||
|
*
|
||||||
|
* The MIT License (MIT)
|
||||||
|
*
|
||||||
|
* Copyright (c) 2018 Scott Shawcroft for Adafruit Industries
|
||||||
|
*
|
||||||
|
* 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 "shared-module/usb_midi/PortOut.h"
|
||||||
|
#include "supervisor/shared/translate.h"
|
||||||
|
#include "tusb.h"
|
||||||
|
|
||||||
|
void common_hal_usb_midi_portout_construct(usb_midi_portout_obj_t *self) {
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t common_hal_usb_midi_portout_write(usb_midi_portout_obj_t *self, const uint8_t *data, size_t len, int *errcode) {
|
||||||
|
return tud_midi_write(0, data, len);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool common_hal_usb_midi_portout_ready_to_tx(usb_midi_portout_obj_t *self) {
|
||||||
|
return tud_midi_connected();
|
||||||
|
}
|
39
shared-module/usb_midi/PortOut.h
Normal file
39
shared-module/usb_midi/PortOut.h
Normal file
@ -0,0 +1,39 @@
|
|||||||
|
/*
|
||||||
|
* This file is part of the MicroPython project, http://micropython.org/
|
||||||
|
*
|
||||||
|
* The MIT License (MIT)
|
||||||
|
*
|
||||||
|
* Copyright (c) 2018 Scott Shawcroft for Adafruit Industries
|
||||||
|
*
|
||||||
|
* 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 SHARED_MODULE_USB_MIDI_PORTOUT_H
|
||||||
|
#define SHARED_MODULE_USB_MIDI_PORTOUT_H
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <stdbool.h>
|
||||||
|
|
||||||
|
#include "py/obj.h"
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
mp_obj_base_t base;
|
||||||
|
} usb_midi_portout_obj_t;
|
||||||
|
|
||||||
|
#endif /* SHARED_MODULE_USB_MIDI_PORTOUT_H */
|
70
shared-module/usb_midi/__init__.c
Normal file
70
shared-module/usb_midi/__init__.c
Normal file
@ -0,0 +1,70 @@
|
|||||||
|
/*
|
||||||
|
* This file is part of the MicroPython project, http://micropython.org/
|
||||||
|
*
|
||||||
|
* The MIT License (MIT)
|
||||||
|
*
|
||||||
|
* Copyright (c) 2018 hathach for Adafruit Industries
|
||||||
|
*
|
||||||
|
* 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 "shared-bindings/usb_midi/__init__.h"
|
||||||
|
|
||||||
|
#include "genhdr/autogen_usb_descriptor.h"
|
||||||
|
#include "py/obj.h"
|
||||||
|
#include "py/mphal.h"
|
||||||
|
#include "py/runtime.h"
|
||||||
|
#include "py/objtuple.h"
|
||||||
|
#include "shared-bindings/usb_midi/PortIn.h"
|
||||||
|
#include "shared-bindings/usb_midi/PortOut.h"
|
||||||
|
#include "supervisor/memory.h"
|
||||||
|
#include "tusb.h"
|
||||||
|
|
||||||
|
supervisor_allocation* usb_midi_allocation;
|
||||||
|
|
||||||
|
static inline uint16_t word_align(uint16_t size) {
|
||||||
|
if (size % 4 != 0) {
|
||||||
|
return (size & 0xfffc) + 0x4;
|
||||||
|
}
|
||||||
|
return size;
|
||||||
|
}
|
||||||
|
|
||||||
|
void usb_midi_init(void) {
|
||||||
|
// TODO(tannewt): Make this dynamic.
|
||||||
|
uint16_t tuple_size = word_align(sizeof(mp_obj_tuple_t) + sizeof(mp_obj_t*) * 2);
|
||||||
|
uint16_t portin_size = word_align(sizeof(usb_midi_portin_obj_t));
|
||||||
|
uint16_t portout_size = word_align(sizeof(usb_midi_portout_obj_t));
|
||||||
|
|
||||||
|
// For each embedded MIDI Jack in the descriptor we create a Port
|
||||||
|
usb_midi_allocation = allocate_memory(tuple_size + portin_size + portout_size, false);
|
||||||
|
|
||||||
|
mp_obj_tuple_t *ports = (mp_obj_tuple_t *) usb_midi_allocation->ptr;
|
||||||
|
ports->base.type = &mp_type_tuple;
|
||||||
|
ports->len = 2;
|
||||||
|
|
||||||
|
usb_midi_portin_obj_t* in = (usb_midi_portin_obj_t *) (usb_midi_allocation->ptr + tuple_size / 4);
|
||||||
|
in->base.type = &usb_midi_portin_type;
|
||||||
|
ports->items[0] = MP_OBJ_FROM_PTR(in);
|
||||||
|
|
||||||
|
usb_midi_portout_obj_t* out = (usb_midi_portout_obj_t *) (usb_midi_allocation->ptr + tuple_size / 4 + portin_size / 4);
|
||||||
|
out->base.type = &usb_midi_portout_type;
|
||||||
|
ports->items[1] = MP_OBJ_FROM_PTR(out);
|
||||||
|
|
||||||
|
mp_map_lookup(&usb_midi_module_globals.map, MP_ROM_QSTR(MP_QSTR_ports), MP_MAP_LOOKUP)->value = MP_OBJ_FROM_PTR(ports);
|
||||||
|
}
|
32
shared-module/usb_midi/__init__.h
Normal file
32
shared-module/usb_midi/__init__.h
Normal file
@ -0,0 +1,32 @@
|
|||||||
|
/*
|
||||||
|
* This file is part of the MicroPython project, http://micropython.org/
|
||||||
|
*
|
||||||
|
* The MIT License (MIT)
|
||||||
|
*
|
||||||
|
* Copyright (c) 2018 Scott Shawcroft for Adafruit Industries
|
||||||
|
*
|
||||||
|
* 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 SHARED_MODULE_USB_MIDI___INIT___H
|
||||||
|
#define SHARED_MODULE_USB_MIDI___INIT___H
|
||||||
|
|
||||||
|
void usb_midi_init(void);
|
||||||
|
|
||||||
|
#endif /* SHARED_MODULE_USB_MIDI___INIT___H */
|
@ -75,6 +75,7 @@
|
|||||||
#define CFG_TUD_CDC 1
|
#define CFG_TUD_CDC 1
|
||||||
#define CFG_TUD_MSC 1
|
#define CFG_TUD_MSC 1
|
||||||
#define CFG_TUD_HID 1
|
#define CFG_TUD_HID 1
|
||||||
|
#define CFG_TUD_MIDI 1
|
||||||
#define CFG_TUD_CUSTOM_CLASS 0
|
#define CFG_TUD_CUSTOM_CLASS 0
|
||||||
|
|
||||||
/*------------------------------------------------------------------*/
|
/*------------------------------------------------------------------*/
|
||||||
|
@ -26,6 +26,7 @@
|
|||||||
|
|
||||||
#include "tick.h"
|
#include "tick.h"
|
||||||
#include "shared-bindings/microcontroller/Processor.h"
|
#include "shared-bindings/microcontroller/Processor.h"
|
||||||
|
#include "shared-module/usb_midi/__init__.h"
|
||||||
#include "supervisor/port.h"
|
#include "supervisor/port.h"
|
||||||
#include "supervisor/usb.h"
|
#include "supervisor/usb.h"
|
||||||
#include "lib/utils/interrupt_char.h"
|
#include "lib/utils/interrupt_char.h"
|
||||||
@ -71,11 +72,13 @@ void usb_init(void) {
|
|||||||
// This callback always got invoked regardless of mp_interrupt_char value since we only set it once here
|
// This callback always got invoked regardless of mp_interrupt_char value since we only set it once here
|
||||||
tud_cdc_set_wanted_char(CHAR_CTRL_C);
|
tud_cdc_set_wanted_char(CHAR_CTRL_C);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
usb_midi_init();
|
||||||
}
|
}
|
||||||
|
|
||||||
void usb_background(void) {
|
void usb_background(void) {
|
||||||
if (usb_enabled()) {
|
if (usb_enabled()) {
|
||||||
tusb_task();
|
tud_task();
|
||||||
tud_cdc_write_flush();
|
tud_cdc_write_flush();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -49,6 +49,7 @@ else
|
|||||||
lib/tinyusb/src/class/msc/msc_device.c \
|
lib/tinyusb/src/class/msc/msc_device.c \
|
||||||
lib/tinyusb/src/class/cdc/cdc_device.c \
|
lib/tinyusb/src/class/cdc/cdc_device.c \
|
||||||
lib/tinyusb/src/class/hid/hid_device.c \
|
lib/tinyusb/src/class/hid/hid_device.c \
|
||||||
|
lib/tinyusb/src/class/midi/midi_device.c \
|
||||||
lib/tinyusb/src/tusb.c \
|
lib/tinyusb/src/tusb.c \
|
||||||
supervisor/shared/serial.c \
|
supervisor/shared/serial.c \
|
||||||
supervisor/usb.c \
|
supervisor/usb.c \
|
||||||
@ -57,8 +58,14 @@ else
|
|||||||
supervisor/shared/usb/usb_msc_flash.c \
|
supervisor/shared/usb/usb_msc_flash.c \
|
||||||
shared-bindings/usb_hid/__init__.c \
|
shared-bindings/usb_hid/__init__.c \
|
||||||
shared-bindings/usb_hid/Device.c \
|
shared-bindings/usb_hid/Device.c \
|
||||||
|
shared-bindings/usb_midi/__init__.c \
|
||||||
|
shared-bindings/usb_midi/PortIn.c \
|
||||||
|
shared-bindings/usb_midi/PortOut.c \
|
||||||
shared-module/usb_hid/__init__.c \
|
shared-module/usb_hid/__init__.c \
|
||||||
shared-module/usb_hid/Device.c \
|
shared-module/usb_hid/Device.c \
|
||||||
|
shared-module/usb_midi/__init__.c \
|
||||||
|
shared-module/usb_midi/PortIn.c \
|
||||||
|
shared-module/usb_midi/PortOut.c \
|
||||||
$(BUILD)/autogen_usb_descriptor.c
|
$(BUILD)/autogen_usb_descriptor.c
|
||||||
CFLAGS += -DUSB_AVAILABLE
|
CFLAGS += -DUSB_AVAILABLE
|
||||||
endif
|
endif
|
||||||
|
@ -176,16 +176,33 @@ hid_interfaces = [
|
|||||||
]
|
]
|
||||||
|
|
||||||
# Audio!
|
# Audio!
|
||||||
midi_in_jack = midi.InJackDescriptor(
|
# In and out here are relative to CircuitPython
|
||||||
description="MIDI PC <- CircuitPython internals",
|
|
||||||
|
# USB OUT -> midi_in_jack_emb -> midi_out_jack_ext -> CircuitPython
|
||||||
|
midi_in_jack_emb = midi.InJackDescriptor(
|
||||||
|
description="MIDI PC -> CircuitPython",
|
||||||
bJackType=midi.JACK_TYPE_EMBEDDED,
|
bJackType=midi.JACK_TYPE_EMBEDDED,
|
||||||
iJack=0)
|
iJack=StringIndex.index("CircuitPython usb_midi.ports[0]"))
|
||||||
midi_out_jack = midi.OutJackDescriptor(
|
midi_out_jack_ext = midi.OutJackDescriptor(
|
||||||
description="MIDI PC -> CircuitPython internals",
|
description="MIDI data out to user code.",
|
||||||
|
bJackType=midi.JACK_TYPE_EXTERNAL,
|
||||||
|
input_pins=[(midi_in_jack_emb, 1)],
|
||||||
|
iJack=0)
|
||||||
|
|
||||||
|
# USB IN <- midi_out_jack_emb <- midi_in_jack_ext <- CircuitPython
|
||||||
|
midi_in_jack_ext = midi.InJackDescriptor(
|
||||||
|
description="MIDI data in from user code.",
|
||||||
|
bJackType=midi.JACK_TYPE_EXTERNAL,
|
||||||
|
iJack=0)
|
||||||
|
midi_out_jack_emb = midi.OutJackDescriptor(
|
||||||
|
description="MIDI PC <- CircuitPython",
|
||||||
bJackType=midi.JACK_TYPE_EMBEDDED,
|
bJackType=midi.JACK_TYPE_EMBEDDED,
|
||||||
iJack=0)
|
input_pins=[(midi_in_jack_ext, 1)],
|
||||||
|
iJack=StringIndex.index("CircuitPython usb_midi.ports[1]"))
|
||||||
|
|
||||||
|
|
||||||
audio_midi_interface = standard.InterfaceDescriptor(
|
audio_midi_interface = standard.InterfaceDescriptor(
|
||||||
description="All the audio",
|
description="Midi goodness",
|
||||||
bInterfaceClass=audio.AUDIO_CLASS_DEVICE,
|
bInterfaceClass=audio.AUDIO_CLASS_DEVICE,
|
||||||
bInterfaceSubClass=audio.AUDIO_SUBCLASS_MIDI_STREAMING,
|
bInterfaceSubClass=audio.AUDIO_SUBCLASS_MIDI_STREAMING,
|
||||||
bInterfaceProtocol=audio.AUDIO_PROTOCOL_V1,
|
bInterfaceProtocol=audio.AUDIO_PROTOCOL_V1,
|
||||||
@ -193,26 +210,23 @@ audio_midi_interface = standard.InterfaceDescriptor(
|
|||||||
subdescriptors=[
|
subdescriptors=[
|
||||||
midi.Header(
|
midi.Header(
|
||||||
jacks_and_elements=[
|
jacks_and_elements=[
|
||||||
midi_in_jack,
|
midi_in_jack_emb,
|
||||||
midi.InJackDescriptor(
|
midi_in_jack_ext,
|
||||||
description="MIDI data in from user code.",
|
midi_out_jack_emb,
|
||||||
bJackType=midi.JACK_TYPE_EXTERNAL, iJack=0),
|
midi_out_jack_ext
|
||||||
midi_out_jack,
|
],
|
||||||
midi.OutJackDescriptor(
|
|
||||||
description="MIDI data out to user code.",
|
|
||||||
bJackType=midi.JACK_TYPE_EXTERNAL, iJack=0),
|
|
||||||
]
|
|
||||||
),
|
),
|
||||||
standard.EndpointDescriptor(
|
standard.EndpointDescriptor(
|
||||||
description="MIDI data out",
|
description="MIDI data out to CircuitPython",
|
||||||
bEndpointAddress=0x0 | standard.EndpointDescriptor.DIRECTION_OUT,
|
bEndpointAddress=0x0 | standard.EndpointDescriptor.DIRECTION_OUT,
|
||||||
bmAttributes=standard.EndpointDescriptor.TYPE_BULK),
|
bmAttributes=standard.EndpointDescriptor.TYPE_BULK),
|
||||||
midi.DataEndpointDescriptor(baAssocJack=[midi_out_jack]),
|
midi.DataEndpointDescriptor(baAssocJack=[midi_in_jack_emb]),
|
||||||
standard.EndpointDescriptor(
|
standard.EndpointDescriptor(
|
||||||
description="MIDI data in",
|
description="MIDI data in from CircuitPython",
|
||||||
bEndpointAddress=0x0 | standard.EndpointDescriptor.DIRECTION_IN,
|
bEndpointAddress=0x0 | standard.EndpointDescriptor.DIRECTION_IN,
|
||||||
bmAttributes=standard.EndpointDescriptor.TYPE_BULK),
|
bmAttributes=standard.EndpointDescriptor.TYPE_BULK,
|
||||||
midi.DataEndpointDescriptor(baAssocJack=[midi_in_jack]),
|
bInterval = 0x0),
|
||||||
|
midi.DataEndpointDescriptor(baAssocJack=[midi_out_jack_emb]),
|
||||||
])
|
])
|
||||||
|
|
||||||
cs_ac_interface = audio10.AudioControlInterface(
|
cs_ac_interface = audio10.AudioControlInterface(
|
||||||
@ -234,12 +248,12 @@ audio_control_interface = standard.InterfaceDescriptor(
|
|||||||
])
|
])
|
||||||
|
|
||||||
# Audio streaming interfaces must occur before MIDI ones.
|
# Audio streaming interfaces must occur before MIDI ones.
|
||||||
# audio_interfaces = [audio_control_interface] + cs_ac_interface.audio_streaming_interfaces + cs_ac_interface.midi_streaming_interfaces
|
audio_interfaces = [audio_control_interface] + cs_ac_interface.audio_streaming_interfaces + cs_ac_interface.midi_streaming_interfaces
|
||||||
|
|
||||||
# This will renumber the endpoints to make them unique across descriptors,
|
# This will renumber the endpoints to make them unique across descriptors,
|
||||||
# and renumber the interfaces in order. But we still need to fix up certain
|
# and renumber the interfaces in order. But we still need to fix up certain
|
||||||
# interface cross-references.
|
# interface cross-references.
|
||||||
interfaces = util.join_interfaces(cdc_interfaces, msc_interfaces, hid_interfaces)
|
interfaces = util.join_interfaces(cdc_interfaces, msc_interfaces, hid_interfaces, audio_interfaces)
|
||||||
|
|
||||||
# Now adjust the CDC interface cross-references.
|
# Now adjust the CDC interface cross-references.
|
||||||
|
|
||||||
@ -256,21 +270,11 @@ cdc_iad = standard.InterfaceAssociationDescriptor(
|
|||||||
bFunctionSubClass=cdc.CDC_SUBCLASS_ACM, # Abstract control model
|
bFunctionSubClass=cdc.CDC_SUBCLASS_ACM, # Abstract control model
|
||||||
bFunctionProtocol=cdc.CDC_PROTOCOL_NONE)
|
bFunctionProtocol=cdc.CDC_PROTOCOL_NONE)
|
||||||
|
|
||||||
# audio_iad = standard.InterfaceAssociationDescriptor(
|
|
||||||
# description="Audio IAD",
|
|
||||||
# bFirstInterface=audio_control_interface.bInterfaceNumber,
|
|
||||||
# bInterfaceCount=len(audio_interfaces),
|
|
||||||
# bFunctionClass=audio.AUDIO_CLASS_DEVICE,
|
|
||||||
# bFunctionSubClass=audio.AUDIO_SUBCLASS_UNKNOWN,
|
|
||||||
# bFunctionProtocol=audio.AUDIO_PROTOCOL_V1)
|
|
||||||
|
|
||||||
|
|
||||||
descriptor_list = []
|
descriptor_list = []
|
||||||
descriptor_list.append(cdc_iad)
|
descriptor_list.append(cdc_iad)
|
||||||
# descriptor_list.append(audio_iad)
|
|
||||||
descriptor_list.extend(cdc_interfaces)
|
descriptor_list.extend(cdc_interfaces)
|
||||||
descriptor_list.extend(msc_interfaces)
|
descriptor_list.extend(msc_interfaces)
|
||||||
# descriptor_list.append(audio_control_interface)
|
descriptor_list.append(audio_control_interface)
|
||||||
# Put the CDC IAD just before the CDC interfaces.
|
# Put the CDC IAD just before the CDC interfaces.
|
||||||
# There appears to be a bug in the Windows composite USB driver that requests the
|
# There appears to be a bug in the Windows composite USB driver that requests the
|
||||||
# HID report descriptor with the wrong interface number if the HID interface is not given
|
# HID report descriptor with the wrong interface number if the HID interface is not given
|
||||||
|
@ -1 +1 @@
|
|||||||
Subproject commit 57bf602dac9cba8c4226f764c286cbc60103d67d
|
Subproject commit e2e79566a807b7230dddbc53a103c19b2f65e2cb
|
Loading…
Reference in New Issue
Block a user