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

Create MIDI "root complex" abstraction. #3157

Draft
wants to merge 3 commits into
base: community
Choose a base branch
from
Draft
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
8 changes: 3 additions & 5 deletions src/RZA1/usb/r_usb_basic/src/driver/r_usb_hlibusbip.c
Original file line number Diff line number Diff line change
Expand Up @@ -38,10 +38,10 @@
#include "RZA1/usb/userdef/r_usb_hmidi_config.h"

#include "definitions.h"
#include "deluge/io/midi/midi_device_manager.h"

#include "deluge/drivers/uart/uart.h"
#include "deluge/io/midi/midi_device_manager.h"
#include "deluge/io/midi/midi_engine.h"
#include "deluge/io/usb/usb_state.h"

#if ((USB_CFG_DTC == USB_CFG_ENABLE) || (USB_CFG_DMA == USB_CFG_ENABLE))
#include "drivers/usb/r_usb_basic/src/hw/inc/r_usb_dmac.h"
Expand Down Expand Up @@ -954,7 +954,7 @@ void usb_hstd_receive_start(usb_utr_t* ptr, uint16_t pipe)
// I now just call the PSTD one instead of this - it does the same.
/***********************************************************************************************************************
Function Name : usb_hstd_read_data
Description : Request to read data from USB FIFO, and manage the size of
Description : Request to read data from USB FIFO, and manage the size of
: the data read.
Arguments : usb_utr_t *ptr : Pointer to usb_utr_t structure.
: uint16_t pipe : Pipe number.
Expand Down Expand Up @@ -1186,8 +1186,6 @@ void usb_hstd_data_end(usb_utr_t* ptr, uint16_t pipe, uint16_t status)
}
} /* End of function usb_hstd_data_end() */

extern usb_utr_t g_usb_midi_recv_utr[][MAX_NUM_USB_MIDI_DEVICES];

// For when data has been received, as host. Hub stuff is on PIPE9
void usb_hstd_brdy_pipe_process_rohan_midi_and_hub(usb_utr_t* ptr, uint16_t bitsts)
{
Expand Down
1 change: 1 addition & 0 deletions src/RZA1/usb/r_usb_basic/src/driver/r_usb_plibusbip.c
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@
#include "deluge/drivers/usb/userdef/r_usb_pmidi_config.h"
#include "deluge/io/midi/midi_device_manager.h"
#include "deluge/io/midi/midi_engine.h"
#include "deluge/io/usb/usb_state.h"

#if ((USB_CFG_DTC == USB_CFG_ENABLE) || (USB_CFG_DMA == USB_CFG_ENABLE))
#include "RZA1/usb/r_usb_basic/src/hw/inc/r_usb_dmac.h"
Expand Down
3 changes: 1 addition & 2 deletions src/RZA1/usb/r_usb_hmidi/src/r_usb_hmidi_driver.c
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@

#include "deluge/deluge.h"
#include "deluge/drivers/uart/uart.h"
#include "deluge/io/usb/usb_state.h"

/******************************************************************************
Exported global variables
Expand All @@ -61,8 +62,6 @@ static void usb_hmidi_check_result(usb_utr_t* ptr, uint16_t unused, uint16_t sta
static usb_er_t usb_hhid_data_trans(usb_utr_t* ptr, uint16_t pipe, uint32_t size, uint8_t* table, usb_cb_t complete);
static void usb_hmidi_enumeration_sequence(usb_utr_t* mess);

extern uint8_t currentDeviceNumWithSendPipe[];

/******************************************************************************
Exported global variables (to be accessed by other files)
******************************************************************************/
Expand Down
2 changes: 2 additions & 0 deletions src/definitions_cxx.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -493,6 +493,8 @@ enum class Error {
INSUFFICIENT_RAM_FOR_FOLDER_CONTENTS_SIZE,
SD_CARD_NOT_PRESENT,
SD_CARD_NO_FILESYSTEM,
OUT_OF_BUFFER_SPACE,
INVALID_SYSEX_FORMAT,
};

enum class SampleRepeatMode {
Expand Down
45 changes: 22 additions & 23 deletions src/deluge/deluge.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@

#include "RZA1/sdhi/inc/sdif.h"
#include "definitions_cxx.hpp"
#include "deluge/io/usb//usb_state.h"
#include "drivers/pic/pic.h"
#include "gui/ui/audio_recorder.h"
#include "gui/ui/browser/browser.h"
Expand Down Expand Up @@ -48,6 +49,8 @@
#include "io/midi/midi_device_manager.h"
#include "io/midi/midi_engine.h"
#include "io/midi/midi_follow.h"
#include "io/midi/root_complex/usb_hosted.h"
#include "io/midi/root_complex/usb_peripheral.h"
#include "lib/printf.h" // IWYU pragma: keep this over rides printf with a non allocating version
#include "memory/general_memory_allocator.h"
#include "model/clip/instrument_clip.h"
Expand Down Expand Up @@ -242,14 +245,6 @@ bool readButtonsAndPads() {
usbInitializationPeriodComplete = 1;
}

/*
if (!inSDRoutine && !closedPeripheral && !anythingInitiallyAttachedAsUSBHost && AudioEngine::audioSampleTimer >=
(44100 << 1)) { D_PRINTLN("closing peripheral"); closeUSBPeripheral(); D_PRINTLN("switching back to host");
openUSBHost();
closedPeripheral = true;
}
*/

if (waitingForSDRoutineToEnd) {
if (sdRoutineLock) {
return false;
Expand Down Expand Up @@ -553,8 +548,6 @@ void setupOLED() {
extern "C" void usb_pstd_pcd_task(void);
extern "C" void usb_cstd_usb_task(void);

extern "C" volatile uint32_t usbLock;

extern "C" void usb_main_host(void);

void registerTasks() {
Expand Down Expand Up @@ -847,20 +840,26 @@ extern "C" int32_t deluge_main(void) {
deluge::hid::display::swapDisplayType();
}

usbLock = 1;
openUSBHost();

// If nothing was plugged in to us as host, we'll go peripheral
// Ideally I'd like to repeatedly switch between host and peripheral mode anytime there's no USB connection.
// To do that, I'd really need to know at any point in time whether the user had just made a connection, just then,
// that hadn't fully initialized yet. I think I sorta have that for host, but not for peripheral yet.
if (!anythingInitiallyAttachedAsUSBHost) {
D_PRINTLN("switching from host to peripheral");
closeUSBHost();
openUSBPeripheral();
}
{
deluge::io::usb::USBAutoLock lock;
openUSBHost();

usbLock = 0;
if (anythingInitiallyAttachedAsUSBHost) {
MIDIDeviceManager::setUSBRoot(new MIDIRootComplexUSBHosted());
}
else {
// If nothing was plugged in to us as host, we'll go peripheral
// Ideally I'd like to repeatedly switch between host and peripheral mode anytime there's no USB connection.
// To do that, I'd really need to know at any point in time whether the user had just made a connection,
// just then, that hadn't fully initialized yet. I think I sorta have that for host, but not for peripheral
// yet.
D_PRINTLN("switching from host to peripheral");
closeUSBHost();
openUSBPeripheral();

// configuredAsPeripheral will set the root complex.
}
}

// Hopefully we can read these files now
runtimeFeatureSettings.readSettingsFromFile();
Expand Down
58 changes: 38 additions & 20 deletions src/deluge/gui/menu_item/midi/devices.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,9 @@
#include "io/midi/cable_types/usb_hosted.h"
#include "io/midi/midi_device.h"
#include "io/midi/midi_device_manager.h"
#include "io/midi/midi_root_complex.h"
#include "io/midi/root_complex/usb_hosted.h"
#include "io/midi/root_complex/usb_peripheral.h"
#include "util/container/static_vector.hpp"
#include <string_view>

Expand All @@ -37,7 +40,12 @@ static constexpr int32_t lowestDeviceNum = -3;
void Devices::beginSession(MenuItem* navigatedBackwardFrom) {
bool found = false;
if (navigatedBackwardFrom != nullptr) {
for (int32_t idx = lowestDeviceNum; idx < MIDIDeviceManager::hostedMIDIDevices.getNumElements(); idx++) {
// This will technically do the wrong thing when we're in peripheral mode (it'll set the max index to 2 instead
// of 0, which would be accurate) but it should be harmless -- `Devices::getCable` should just return nullptr in
// that case which we handle fine already anyway.
auto maxIndex =
(MIDIDeviceManager::rootUSB != nullptr) ? MIDIDeviceManager::rootUSB->getNumCables() : lowestDeviceNum + 1;
for (int32_t idx = lowestDeviceNum; idx < maxIndex; idx++) {
if (getCable(idx) == soundEditor.currentMIDICable) {
found = true;
this->setValue(idx);
Expand All @@ -62,10 +70,12 @@ void Devices::beginSession(MenuItem* navigatedBackwardFrom) {
void Devices::selectEncoderAction(int32_t offset) {
offset = std::clamp<int32_t>(offset, -1, 1);

auto maxIndex = (MIDIDeviceManager::rootUSB == nullptr) ? 0 : MIDIDeviceManager::rootUSB->getNumCables();

do {
int32_t newValue = this->getValue() + offset;

if (newValue >= MIDIDeviceManager::hostedMIDIDevices.getNumElements()) {
if (newValue >= maxIndex) {
if (display->haveOLED()) {
return;
}
Expand All @@ -75,14 +85,14 @@ void Devices::selectEncoderAction(int32_t offset) {
if (display->haveOLED()) {
return;
}
newValue = MIDIDeviceManager::hostedMIDIDevices.getNumElements() - 1;
newValue = maxIndex - 1;
}

this->setValue(newValue);

soundEditor.currentMIDICable = getCable(this->getValue());

} while (!soundEditor.currentMIDICable->connectionFlags);
} while (soundEditor.currentMIDICable == nullptr && soundEditor.currentMIDICable->connectionFlags == 0);
// Don't show devices which aren't connected. Sometimes we won't even have a name to display for them.

if (display->haveOLED()) {
Expand Down Expand Up @@ -115,24 +125,31 @@ void Devices::selectEncoderAction(int32_t offset) {
}

MIDICable* Devices::getCable(int32_t deviceIndex) {
if (deviceIndex < lowestDeviceNum || deviceIndex >= MIDIDeviceManager::hostedMIDIDevices.getNumElements()) {
if (deviceIndex < lowestDeviceNum) {
D_PRINTLN("impossible device request");
return nullptr;
}
switch (deviceIndex) {
case -3: {
return &MIDIDeviceManager::dinMIDIPorts;
}
case -2: {
return &MIDIDeviceManager::upstreamUSBMIDICable1;
}
case -1: {
return &MIDIDeviceManager::upstreamUSBMIDICable2;
}
default: {
return static_cast<MIDICable*>(MIDIDeviceManager::hostedMIDIDevices.getElement(deviceIndex));

if (deviceIndex == -3) {
return &MIDIDeviceManager::rootDin.cable;
}

if (MIDIDeviceManager::rootUSB != nullptr) {
auto& rootUSB = *MIDIDeviceManager::rootUSB;
if (deviceIndex < 0) {
if (rootUSB.getType() == RootComplexType::RC_USB_PERIPHERAL && deviceIndex >= -2) {
return rootUSB.getCable(deviceIndex + 2);
}
return nullptr;
}

if (rootUSB.getType() == RootComplexType::RC_USB_HOST) {
auto& usb = static_cast<MIDIRootComplexUSBHosted&>(rootUSB);
return usb.getCable(deviceIndex);
}
}

return nullptr;
}

void Devices::drawValue() {
Expand All @@ -154,11 +171,12 @@ void Devices::drawPixelsForOled() {

int32_t selectedRow = -1;

int32_t device_idx = currentScroll;
auto device_idx = currentScroll;
size_t row = 0;
while (row < kOLEDMenuNumOptionsVisible && device_idx < MIDIDeviceManager::hostedMIDIDevices.getNumElements()) {
auto max_index = (MIDIDeviceManager::rootUSB == nullptr) ? 0 : MIDIDeviceManager::rootUSB->getNumCables();
while (row < kOLEDMenuNumOptionsVisible && device_idx < static_cast<ptrdiff_t>(max_index)) {
MIDICable* cable = getCable(device_idx);
if (cable && cable->connectionFlags != 0u) {
if (cable != nullptr && cable->connectionFlags != 0u) {
itemNames.push_back(cable->getDisplayName());
if (device_idx == this->getValue()) {
selectedRow = static_cast<int32_t>(row);
Expand Down
2 changes: 1 addition & 1 deletion src/deluge/gui/menu_item/midi/devices.h
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ class Devices final : public Value<int32_t> {
void drawPixelsForOled();

private:
size_t currentScroll;
ptrdiff_t currentScroll;
};

extern Devices devicesMenu;
Expand Down
Loading
Loading