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
59 changes: 58 additions & 1 deletion Source/Devices/PortController.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,64 @@ int PortController::configureDevice()
{
if (deviceContext == nullptr || !deviceContext->isInitialized()) return 1;

return deviceContext->writeRegister(deviceIdx, (uint32_t)PortControllerRegister::ENABLE, 1);
return deviceContext->writeRegister(deviceIdx, (uint32_t)PortControllerRegister::ENABLE, 1u);
}

bool PortController::resetLinkFlags()
{
if (deviceContext == nullptr || !deviceContext->isInitialized()) return false;

int rc = deviceContext->writeRegister(deviceIdx, (uint32_t)PortControllerRegister::LINKFLAGS, 0b11);
if (rc != ONI_ESUCCESS)
{
Onix1::showWarningMessageBoxAsync("Port Controller Error", "Unable to set the link flags for " + getName());
return false;
}

return true;
}

uint32_t PortController::getLinkFlags()
{
uint32_t linkFlags;
int rc = deviceContext->readRegister(deviceIdx, (uint32_t)PortControllerRegister::LINKFLAGS, &linkFlags);

if (rc != ONI_ESUCCESS)
{
Onix1::showWarningMessageBoxAsync("Port Controller Error", "Unable to read the link flags for " + getName());
return false;
}

return linkFlags;
}

bool PortController::updateSettings()
{
return getLinkFlags() == 0;
}

void PortController::addSourceBuffers(OwnedArray<DataBuffer>& sourceBuffers)
{
}

std::string PortController::getPortNameString() const
{
return OnixDevice::getPortName(port);
}

PortName PortController::getPort() const
{
return port;
}

bool PortController::getErrorFlag()
{
return errorFlag;
}

double PortController::getLastVoltageSet() const
{
return lastVoltageSet;
}

void PortController::startAcquisition()
Expand Down
31 changes: 17 additions & 14 deletions Source/Devices/PortController.h
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,8 @@ namespace OnixSourcePlugin
DESPWR = 2,
PORTVOLTAGE = 3,
SAVEVOLTAGE = 4,
LINKSTATE = 5
LINKSTATE = 5,
LINKFLAGS = 7,
};

enum class PortStatusCode : uint32_t
Expand Down Expand Up @@ -83,18 +84,12 @@ namespace OnixSourcePlugin
PortController(PortName port_, std::shared_ptr<Onix1> ctx_);

int configureDevice() override;

bool updateSettings() override { return true; }

bool updateSettings() override;
void startAcquisition() override;

void stopAcquisition() override;

void addFrame(oni_frame_t*) override;

void processFrames() override;

void addSourceBuffers(OwnedArray<DataBuffer>& sourceBuffers) override {};
void addSourceBuffers(OwnedArray<DataBuffer>& sourceBuffers) override;

void updateDiscoveryParameters(DiscoveryParameters parameters);

Expand All @@ -110,12 +105,20 @@ namespace OnixSourcePlugin

static DiscoveryParameters getHeadstageDiscoveryParameters(std::string headstage);

std::string getPortName() const { return OnixDevice::getPortName(port); }
std::string getPortNameString() const;

PortName getPort() const;

/** Check if the port status changed during acquisition and there is an error reported */
bool getErrorFlag();

double getLastVoltageSet() const;

/** Check if the port status changed and there is an error reported */
bool getErrorFlag() { return errorFlag; }
/** Writes to the link flags register to reset the flags. This should be called after headstages are locked. */
bool resetLinkFlags();

double getLastVoltageSet() const { return lastVoltageSet; }
/** Returns the link flags value, which is zero unless the lock or pass was lost outside of acquisition */
uint32_t getLinkFlags();

private:
Array<oni_frame_t*, CriticalSection, 10> frameArray;
Expand All @@ -140,7 +143,7 @@ namespace OnixSourcePlugin
{
public:
ConfigureVoltageWithProgressBar(DiscoveryParameters params, PortController* port)
: ThreadWithProgressWindow("Configuring voltage on " + port->getPortName(), true, false)
: ThreadWithProgressWindow("Configuring voltage on " + port->getPortNameString(), true, false)
{
m_params = params;
m_port = port;
Expand Down
9 changes: 2 additions & 7 deletions Source/OnixDevice.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -153,9 +153,9 @@ int OnixDevice::getPortOffset(PortName port)
return (uint32_t)port << 8;
}

std::string OnixDevice::getPortName(int offset)
std::string OnixDevice::getPortName(oni_dev_idx_t index)
{
switch (offset)
switch (getOffset(index))
{
case 0:
return "";
Expand All @@ -173,11 +173,6 @@ std::string OnixDevice::getPortName(PortName port)
return getPortName(getPortOffset(port));
}

std::string OnixDevice::getPortName(oni_dev_idx_t index)
{
return getPortName(getOffset(index));
}

PortName OnixDevice::getPortFromIndex(oni_dev_idx_t index)
{
return index & (1 << 8) ? PortName::PortA : PortName::PortB;
Expand Down
1 change: 0 additions & 1 deletion Source/OnixDevice.h
Original file line number Diff line number Diff line change
Expand Up @@ -185,7 +185,6 @@ namespace OnixSourcePlugin
void setHubName(std::string hubName) { m_hubName = hubName; }

static int getPortOffset(PortName port);
static std::string getPortName(int offset);
static std::string getPortName(PortName port);
static std::string getPortName(oni_dev_idx_t index);
static PortName getPortFromIndex(oni_dev_idx_t index);
Expand Down
89 changes: 81 additions & 8 deletions Source/OnixSource.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -250,6 +250,33 @@ bool OnixSource::configurePort(PortName port)
return true;
}

bool OnixSource::resetPortLinkFlags()
{
if (context == nullptr || !context->isInitialized())
return false;

return portA->resetLinkFlags() != ONI_ESUCCESS || portB->resetLinkFlags() != ONI_ESUCCESS;
}

bool OnixSource::resetPortLinkFlags(PortName port)
{
if (context == nullptr || !context->isInitialized())
return false;

if (port == PortName::PortA)
{
if (portA->resetLinkFlags() != ONI_ESUCCESS)
return false;
}
else if (port == PortName::PortB)
{
if (portB->resetLinkFlags() != ONI_ESUCCESS)
return false;
}

return true;
}

bool OnixSource::checkHubFirmwareCompatibility(std::shared_ptr<Onix1> context, device_map_t deviceTable)
{
auto hubIds = context->getHubIds(deviceTable);
Expand Down Expand Up @@ -988,6 +1015,25 @@ bool OnixSource::foundInputSource()
return devicesFound;
}

bool OnixSource::checkPortControllerStatus(OnixSourceEditor* editor, std::shared_ptr<PortController> port)
{
if (editor->isHeadstageSelected(port->getPort()))
{
if (!port->checkLinkState())
{
Onix1::showWarningMessageBoxAsync("Port Controller Error", port->getName() + " is not currently connected.");
return false;
}
else if (port->getLinkFlags() != 0)
{
Onix1::showWarningMessageBoxAsync("Port Controller Error", port->getName() + " was disconnected, and must be reconnected.");
return false;
}
}

return true;
}

bool OnixSource::isReady()
{
if (context == nullptr || !devicesFound)
Expand All @@ -999,8 +1045,11 @@ bool OnixSource::isReady()
return false;
}

if (editor->isHeadstageSelected(PortName::PortA) && !portA->checkLinkState()) return false;
if (editor->isHeadstageSelected(PortName::PortB) && !portB->checkLinkState()) return false;
if (!checkPortControllerStatus(editor, portA) || !checkPortControllerStatus(editor, portB))
{
editor->setConnectedStatus(false); // NB: If either port controller lost lock, disconnect all devices
return false;
}

for (const auto& source : sources)
{
Expand Down Expand Up @@ -1039,6 +1088,18 @@ bool OnixSource::startAcquisition()
return true;
}

void OnixSource::disconnectDevicesAfterAcquisition(OnixSourceEditor* editor)
{
while (CoreServices::getAcquisitionStatus())
std::this_thread::sleep_for(50ms);

if (editor != nullptr)
{
const MessageManagerLock mmLock;
editor->setConnectedStatus(false);
}
}

bool OnixSource::stopAcquisition()
{
if (isThreadRunning())
Expand All @@ -1063,21 +1124,33 @@ bool OnixSource::stopAcquisition()

if (portA->getErrorFlag() || portB->getErrorFlag())
{
std::string msg = "";

if (portA->getErrorFlag())
{
LOGE("Port A lost communication lock. Reconnect hardware to continue.");
CoreServices::sendStatusMessage("Port A lost communication lock");
msg += "Port A";
}

if (portA->getErrorFlag() && portB->getErrorFlag())
{
msg += " and ";
}

if (portB->getErrorFlag())
{
LOGE("Port B lost communication lock. Reconnect hardware to continue.");
CoreServices::sendStatusMessage("Port B lost communication lock");
msg += "Port B";
}

devicesFound = false;
msg += " lost communication lock during acquisition. Inspect hardware connections and port switch before reconnecting.";

Onix1::showWarningMessageBoxAsync("Port Communication Lock Lost", "The port communication lock was lost during acquisition. Inspect hardware connections and port switch. \n\nTo continue, press disconnect in the GUI, then press connect.");
std::thread t(disconnectDevicesAfterAcquisition, editor);
t.detach(); // NB: Detach to allow the current thread to finish, stopping acquisition and allowing the called thread to complete

Onix1::showWarningMessageBoxAsync(
"Port Communication Lock Lost",
msg);

return false;
}

return true;
Expand Down
7 changes: 7 additions & 0 deletions Source/OnixSource.h
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,8 @@ namespace OnixSourcePlugin
static bool enablePassthroughMode(std::shared_ptr<Onix1>, bool, bool);

bool configurePort(PortName);
bool resetPortLinkFlags();
bool resetPortLinkFlags(PortName);

static bool checkHubFirmwareCompatibility(std::shared_ptr<Onix1>, device_map_t);

Expand Down Expand Up @@ -132,6 +134,8 @@ namespace OnixSourcePlugin

void setBlockReadSize(uint32_t);

static bool checkPortControllerStatus(OnixSourceEditor* editor, std::shared_ptr<PortController> port);

private:

/** Available data sources */
Expand Down Expand Up @@ -172,6 +176,9 @@ namespace OnixSourcePlugin

static bool writeBlockReadSize(std::shared_ptr<Onix1>, uint32_t, uint32_t);

/** This method is expected to be called in a separate thread, and waits for acquisition to stop before gracefully disconnecting all devices */
static void disconnectDevicesAfterAcquisition(OnixSourceEditor* editor);

JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(OnixSource);
};
}
21 changes: 16 additions & 5 deletions Source/OnixSourceEditor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -269,12 +269,23 @@ void OnixSourceEditor::setConnectedStatus(bool connected)
return;
}

// NB: Check if headstages were not discovered, and then removed
if (!isHeadstageSelected(PortName::PortA) && source->getLastVoltageSet(PortName::PortA) > 0)
setPortStatusAndVoltageValue(PortName::PortA, 0.0, fillDisconnected, lastVoltageSetA.get(), portStatusA.get());
if (source->getLastVoltageSet(PortName::PortA) > 0)
{
if (!isHeadstageSelected(PortName::PortA))
setPortStatusAndVoltageValue(PortName::PortA, 0.0, fillDisconnected, lastVoltageSetA.get(), portStatusA.get());

if (!isHeadstageSelected(PortName::PortB) && source->getLastVoltageSet(PortName::PortB) > 0)
setPortStatusAndVoltageValue(PortName::PortB, 0.0, fillDisconnected, lastVoltageSetB.get(), portStatusB.get());
else
source->resetPortLinkFlags(PortName::PortA);
}

if (source->getLastVoltageSet(PortName::PortB) > 0)
{
if (!isHeadstageSelected(PortName::PortB))
setPortStatusAndVoltageValue(PortName::PortB, 0.0, fillDisconnected, lastVoltageSetB.get(), portStatusB.get());

else
source->resetPortLinkFlags(PortName::PortB);
}

connectButton->setLabel("DISCONNECT");

Expand Down