From 72ba1d5963a5718cce71a53fa88fe42432bc3743 Mon Sep 17 00:00:00 2001 From: bparks13 Date: Fri, 18 Apr 2025 12:37:12 -0400 Subject: [PATCH 01/15] Add namespace to files --- Source/Devices/AnalogIO.cpp | 2 + Source/Devices/AnalogIO.h | 249 ++-- Source/Devices/Bno055.cpp | 4 +- Source/Devices/Bno055.h | 82 +- Source/Devices/DS90UB9x.h | 243 ++-- Source/Devices/DigitalIO.cpp | 2 + Source/Devices/DigitalIO.h | 153 +-- Source/Devices/HarpSyncInput.cpp | 2 + Source/Devices/HarpSyncInput.h | 85 +- Source/Devices/HeadStageEEPROM.cpp | 2 + Source/Devices/HeadStageEEPROM.h | 24 +- Source/Devices/Heartbeat.cpp | 2 + Source/Devices/Heartbeat.h | 59 +- Source/Devices/MemoryMonitor.cpp | 2 + Source/Devices/MemoryMonitor.h | 141 +-- Source/Devices/Neuropixels2e.cpp | 4 +- Source/Devices/Neuropixels2e.h | 389 +++--- Source/Devices/Neuropixels_1.cpp | 4 +- Source/Devices/Neuropixels_1.h | 423 +++---- Source/Devices/OutputClock.cpp | 2 + Source/Devices/OutputClock.h | 99 +- Source/Devices/PolledBno055.cpp | 4 +- Source/Devices/PolledBno055.h | 98 +- Source/Devices/PortController.cpp | 53 +- Source/Devices/PortController.h | 234 ++-- Source/Formats/ProbeInterface.h | 219 ++-- Source/FrameReader.cpp | 2 + Source/FrameReader.h | 21 +- Source/I2CRegisterContext.cpp | 2 + Source/I2CRegisterContext.h | 29 +- Source/NeuropixComponents.h | 389 +++--- Source/Onix1.cpp | 2 + Source/Onix1.h | 137 +-- Source/OnixDevice.cpp | 66 + Source/OnixDevice.h | 297 ++--- Source/OnixSource.cpp | 4 +- Source/OnixSource.h | 157 +-- Source/OnixSourceCanvas.cpp | 13 +- Source/OnixSourceCanvas.h | 142 +-- Source/OnixSourceEditor.cpp | 15 +- Source/OnixSourceEditor.h | 143 +-- Source/OpenEphysLib.cpp | 1 + Source/UI/ActivityView.h | 217 ++-- Source/UI/AnalogIOInterface.cpp | 2 + Source/UI/AnalogIOInterface.h | 49 +- Source/UI/Bno055Interface.cpp | 2 + Source/UI/Bno055Interface.h | 31 +- Source/UI/ColourScheme.cpp | 2 + Source/UI/ColourScheme.h | 65 +- Source/UI/CustomTabButton.h | 45 +- Source/UI/CustomTabComponent.h | 45 +- Source/UI/CustomViewport.h | 111 +- Source/UI/DigitalIOInterface.cpp | 2 + Source/UI/DigitalIOInterface.h | 31 +- Source/UI/HarpSyncInputInterface.cpp | 2 + Source/UI/HarpSyncInputInterface.h | 31 +- Source/UI/NeuropixV1Interface.cpp | 3 + Source/UI/NeuropixV1Interface.h | 175 +-- Source/UI/NeuropixelsV1fProbeBrowser.h | 27 +- Source/UI/NeuropixelsV2eInterface.cpp | 2 + Source/UI/NeuropixelsV2eInterface.h | 47 +- Source/UI/NeuropixelsV2eProbeBrowser.h | 27 +- Source/UI/NeuropixelsV2eProbeInterface.cpp | 3 + Source/UI/NeuropixelsV2eProbeInterface.h | 133 +- Source/UI/OutputClockInterface.cpp | 2 + Source/UI/OutputClockInterface.h | 59 +- Source/UI/PolledBno055Interface.cpp | 2 + Source/UI/PolledBno055Interface.h | 31 +- Source/UI/ProbeBrowser.h | 1271 ++++++++++---------- Source/UI/SettingsInterface.h | 151 +-- 70 files changed, 3376 insertions(+), 3193 deletions(-) diff --git a/Source/Devices/AnalogIO.cpp b/Source/Devices/AnalogIO.cpp index 8343bdc..23fdcf7 100644 --- a/Source/Devices/AnalogIO.cpp +++ b/Source/Devices/AnalogIO.cpp @@ -22,6 +22,8 @@ #include "AnalogIO.h" +using namespace OnixSourcePlugin; + AnalogIO::AnalogIO(String name, const oni_dev_idx_t deviceIdx_, std::shared_ptr oni_ctx) : OnixDevice(name, BREAKOUT_BOARD_NAME, OnixDeviceType::ANALOGIO, deviceIdx_, oni_ctx) { diff --git a/Source/Devices/AnalogIO.h b/Source/Devices/AnalogIO.h index e21eacb..e591ae7 100644 --- a/Source/Devices/AnalogIO.h +++ b/Source/Devices/AnalogIO.h @@ -24,168 +24,171 @@ #include "../OnixDevice.h" -enum class AnalogIORegisters : uint32_t +namespace OnixSourcePlugin { - ENABLE = 0, - CHDIR = 1, - CH00_IN_RANGE = 2, - CH01_IN_RANGE = 3, - CH02_IN_RANGE = 4, - CH03_IN_RANGE = 5, - CH04_IN_RANGE = 6, - CH05_IN_RANGE = 7, - CH06_IN_RANGE = 8, - CH07_IN_RANGE = 9, - CH08_IN_RANGE = 10, - CH09_IN_RANGE = 11, - CH10_IN_RANGE = 12, - CH11_IN_RANGE = 13, -}; - -enum class AnalogIOVoltageRange : uint32_t -{ - TenVolts = 0, - TwoPointFiveVolts = 1, - FiveVolts = 2 -}; - -enum class AnalogIODirection : uint32_t -{ - Input = 0, - Output = 1 -}; + enum class AnalogIORegisters : uint32_t + { + ENABLE = 0, + CHDIR = 1, + CH00_IN_RANGE = 2, + CH01_IN_RANGE = 3, + CH02_IN_RANGE = 4, + CH03_IN_RANGE = 5, + CH04_IN_RANGE = 6, + CH05_IN_RANGE = 7, + CH06_IN_RANGE = 8, + CH07_IN_RANGE = 9, + CH08_IN_RANGE = 10, + CH09_IN_RANGE = 11, + CH10_IN_RANGE = 12, + CH11_IN_RANGE = 13, + }; + + enum class AnalogIOVoltageRange : uint32_t + { + TenVolts = 0, + TwoPointFiveVolts = 1, + FiveVolts = 2 + }; -enum class AnalogIODataType : uint32_t -{ - S16 = 0, - Volts = 1 -}; + enum class AnalogIODirection : uint32_t + { + Input = 0, + Output = 1 + }; -/* - Configures and streams data from an AnalogIO device on a Breakout Board -*/ -class AnalogIO : public OnixDevice -{ -public: - AnalogIO(String name, const oni_dev_idx_t, std::shared_ptr oni_ctx); + enum class AnalogIODataType : uint32_t + { + S16 = 0, + Volts = 1 + }; + + /* + Configures and streams data from an AnalogIO device on a Breakout Board + */ + class AnalogIO : public OnixDevice + { + public: + AnalogIO(String name, const oni_dev_idx_t, std::shared_ptr oni_ctx); - /** Configures the device so that it is ready to stream with default settings */ - int configureDevice() override; + /** Configures the device so that it is ready to stream with default settings */ + int configureDevice() override; - /** Update the settings of the device */ - bool updateSettings() override; + /** Update the settings of the device */ + bool updateSettings() override; - /** Starts probe data streaming */ - void startAcquisition() override; + /** Starts probe data streaming */ + void startAcquisition() override; - /** Stops probe data streaming*/ - void stopAcquisition() override; + /** Stops probe data streaming*/ + void stopAcquisition() override; - /** Given the sourceBuffers from OnixSource, add all streams for the current device to the array */ - void addSourceBuffers(OwnedArray& sourceBuffers) override; + /** Given the sourceBuffers from OnixSource, add all streams for the current device to the array */ + void addSourceBuffers(OwnedArray& sourceBuffers) override; - void addFrame(oni_frame_t*) override; + void addFrame(oni_frame_t*) override; - void processFrames() override; + void processFrames() override; - AnalogIODirection getChannelDirection(int channelNumber) - { - if (channelNumber > numChannels || channelNumber < 0) + AnalogIODirection getChannelDirection(int channelNumber) { - LOGE("Channel number must be between 0 and " + String(channelNumber)); - return AnalogIODirection::Input; - } + if (channelNumber > numChannels || channelNumber < 0) + { + LOGE("Channel number must be between 0 and " + String(channelNumber)); + return AnalogIODirection::Input; + } - return channelDirection[channelNumber]; - } + return channelDirection[channelNumber]; + } - static String getChannelDirection(AnalogIODirection direction) - { - switch (direction) + static String getChannelDirection(AnalogIODirection direction) { - case AnalogIODirection::Input: - return "Input"; - case AnalogIODirection::Output: - return "Output"; - default: - return ""; + switch (direction) + { + case AnalogIODirection::Input: + return "Input"; + case AnalogIODirection::Output: + return "Output"; + default: + return ""; + } } - } - void setChannelDirection(int channelNumber, AnalogIODirection direction) - { - if (channelNumber > numChannels || channelNumber < 0) + void setChannelDirection(int channelNumber, AnalogIODirection direction) { - LOGE("Channel number must be between 0 and " + String(channelNumber)); - return; - } + if (channelNumber > numChannels || channelNumber < 0) + { + LOGE("Channel number must be between 0 and " + String(channelNumber)); + return; + } - channelDirection[channelNumber] = direction; - } + channelDirection[channelNumber] = direction; + } - AnalogIOVoltageRange getChannelVoltageRange(int channelNumber) - { - if (channelNumber > numChannels || channelNumber < 0) + AnalogIOVoltageRange getChannelVoltageRange(int channelNumber) { - LOGE("Channel number must be between 0 and " + String(channelNumber)); - return AnalogIOVoltageRange::FiveVolts; - } + if (channelNumber > numChannels || channelNumber < 0) + { + LOGE("Channel number must be between 0 and " + String(channelNumber)); + return AnalogIOVoltageRange::FiveVolts; + } - return channelVoltageRange[channelNumber]; - } + return channelVoltageRange[channelNumber]; + } - AnalogIODataType getDataType() const { return dataType; } + void setChannelVoltageRange(int channelNumber, AnalogIOVoltageRange direction) + { + if (channelNumber > numChannels || channelNumber < 0) + { + LOGE("Channel number must be between 0 and " + String(channelNumber)); + return; + } - int getNumChannels() { return numChannels; } + channelVoltageRange[channelNumber] = direction; + } -private: + AnalogIODataType getDataType() const { return dataType; } - DataBuffer* analogInputBuffer = nullptr; + void setDataType(AnalogIODataType type) { dataType = type; } - static const int AnalogIOFrequencyHz = 100000; + int getNumChannels() { return numChannels; } - static const int numFrames = 25; - static const int framesToAverage = 4; // NB: Downsampling from 100 kHz to 25 kHz - static const int numChannels = 12; + private: - static const int numberOfDivisions = 1 << 16; - const int dacMidScale = 1 << 15; + DataBuffer* analogInputBuffer = nullptr; - std::array channelDirection; - std::array channelVoltageRange; + static const int AnalogIOFrequencyHz = 100000; - AnalogIODataType dataType = AnalogIODataType::Volts; + static const int numFrames = 25; + static const int framesToAverage = 4; // NB: Downsampling from 100 kHz to 25 kHz + static const int numChannels = 12; - Array frameArray; + static const int numberOfDivisions = 1 << 16; + const int dacMidScale = 1 << 15; - unsigned short currentFrame = 0; - unsigned short currentAverageFrame = 0; - int sampleNumber = 0; + std::array channelDirection; + std::array channelVoltageRange; - bool shouldAddToBuffer = false; + AnalogIODataType dataType = AnalogIODataType::Volts; - std::array analogInputSamples; + Array frameArray; - double timestamps[numFrames]; - int64 sampleNumbers[numFrames]; - uint64 eventCodes[numFrames]; + unsigned short currentFrame = 0; + unsigned short currentAverageFrame = 0; + int sampleNumber = 0; - std::array voltsPerDivision; + bool shouldAddToBuffer = false; - static float getVoltsPerDivision(AnalogIOVoltageRange voltageRange); + std::array analogInputSamples; - void setChannelVoltageRange(int channelNumber, AnalogIOVoltageRange direction) - { - if (channelNumber > numChannels || channelNumber < 0) - { - LOGE("Channel number must be between 0 and " + String(channelNumber)); - return; - } + double timestamps[numFrames]; + int64 sampleNumbers[numFrames]; + uint64 eventCodes[numFrames]; - channelVoltageRange[channelNumber] = direction; - } + std::array voltsPerDivision; - void setDataType(AnalogIODataType type) { dataType = type; } + static float getVoltsPerDivision(AnalogIOVoltageRange voltageRange); - JUCE_LEAK_DETECTOR(AnalogIO); -}; + JUCE_LEAK_DETECTOR(AnalogIO); + }; +} diff --git a/Source/Devices/Bno055.cpp b/Source/Devices/Bno055.cpp index b387004..b45b079 100644 --- a/Source/Devices/Bno055.cpp +++ b/Source/Devices/Bno055.cpp @@ -22,12 +22,14 @@ #include "Bno055.h" +using namespace OnixSourcePlugin; + Bno055::Bno055(String name, String headstageName, const oni_dev_idx_t deviceIdx_, std::shared_ptr ctx) : OnixDevice(name, headstageName, OnixDeviceType::BNO, deviceIdx_, ctx) { auto streamIdentifier = getStreamIdentifier(); - String port = PortController::getPortName(PortController::getPortFromIndex(deviceIdx)); + String port = getPortNameFromIndex(deviceIdx); StreamInfo eulerAngleStream = StreamInfo( OnixDevice::createStreamName({ port, getHeadstageName(), getName(), "Euler" }), "Bosch Bno055 9-axis inertial measurement unit (IMU) Euler angle", diff --git a/Source/Devices/Bno055.h b/Source/Devices/Bno055.h index 7948475..d40d77c 100644 --- a/Source/Devices/Bno055.h +++ b/Source/Devices/Bno055.h @@ -23,65 +23,67 @@ #pragma once #include "../OnixDevice.h" -#include "PortController.h" -enum class Bno055Registers +namespace OnixSourcePlugin { - ENABLE = 0x00 -}; + enum class Bno055Registers + { + ENABLE = 0x00 + }; -/* - Configures and streams data from a BNO055 device -*/ -class Bno055 : public OnixDevice -{ -public: + /* + Configures and streams data from a BNO055 device + */ + class Bno055 : public OnixDevice + { + public: - /** Constructor */ - Bno055(String name, String headstageName, const oni_dev_idx_t, std::shared_ptr ctx); + /** Constructor */ + Bno055(String name, String headstageName, const oni_dev_idx_t, std::shared_ptr ctx); - int configureDevice() override; + int configureDevice() override; - /** Update the settings of the device */ - bool updateSettings() override; + /** Update the settings of the device */ + bool updateSettings() override; - /** Starts probe data streaming */ - void startAcquisition() override; + /** Starts probe data streaming */ + void startAcquisition() override; - /** Stops probe data streaming*/ - void stopAcquisition() override; + /** Stops probe data streaming*/ + void stopAcquisition() override; - void addFrame(oni_frame_t*) override; + void addFrame(oni_frame_t*) override; - void processFrames() override; + void processFrames() override; - void addSourceBuffers(OwnedArray& sourceBuffers) override; + void addSourceBuffers(OwnedArray& sourceBuffers) override; -private: + private: - DataBuffer* bnoBuffer; + DataBuffer* bnoBuffer; - const float eulerAngleScale = 1.0f / 16; // 1 degree = 16 LSB - const float quaternionScale = 1.0f / (1 << 14); // 1 = 2^14 LSB - const float accelerationScale = 1.0f / 100; // 1m / s^2 = 100 LSB + const float eulerAngleScale = 1.0f / 16; // 1 degree = 16 LSB + const float quaternionScale = 1.0f / (1 << 14); // 1 = 2^14 LSB + const float accelerationScale = 1.0f / 100; // 1m / s^2 = 100 LSB - static const int numFrames = 2; + static const int numFrames = 2; - Array frameArray; + Array frameArray; - bool shouldAddToBuffer = false; + bool shouldAddToBuffer = false; - static const int numberOfChannels = 3 + 3 + 4 + 3 + 1; - static constexpr float sampleRate = 100.0f; + static const int numberOfChannels = 3 + 3 + 4 + 3 + 1; + static constexpr float sampleRate = 100.0f; - float bnoSamples[numberOfChannels * numFrames]; + float bnoSamples[numberOfChannels * numFrames]; - double bnoTimestamps[numFrames]; - int64 sampleNumbers[numFrames]; - uint64 eventCodes[numFrames]; + double bnoTimestamps[numFrames]; + int64 sampleNumbers[numFrames]; + uint64 eventCodes[numFrames]; - unsigned short currentFrame = 0; - int sampleNumber = 0; + unsigned short currentFrame = 0; + int sampleNumber = 0; - JUCE_LEAK_DETECTOR(Bno055); -}; + JUCE_LEAK_DETECTOR(Bno055); + }; +} diff --git a/Source/Devices/DS90UB9x.h b/Source/Devices/DS90UB9x.h index 7e44719..040c7d6 100644 --- a/Source/Devices/DS90UB9x.h +++ b/Source/Devices/DS90UB9x.h @@ -1,22 +1,22 @@ /* - ------------------------------------------------------------------ + ------------------------------------------------------------------ - Copyright (C) Open Ephys + Copyright (C) Open Ephys - ------------------------------------------------------------------ + ------------------------------------------------------------------ - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. - You should have received a copy of the GNU General Public License - along with this program. If not, see . + You should have received a copy of the GNU General Public License + along with this program. If not, see . */ @@ -24,111 +24,114 @@ #include -static class DS90UB9x +namespace OnixSourcePlugin { -public: - // managed registers - static const uint32_t ENABLE = 0x8000; - static const uint32_t READSZ = 0x8001; - static const uint32_t TRIGGER = 0x8002; - static const uint32_t TRIGGEROFF = 0x8003; - static const uint32_t DATAGATE = 0x8004; - static const uint32_t SYNCBITS = 0x8005; - static const uint32_t MARK = 0x8006; - static const uint32_t MAGIC_MASK = 0x8007; - static const uint32_t MAGIC = 0x8008; - static const uint32_t MAGIC_WAIT = 0x8009; - static const uint32_t DATAMODE = 0x800A; - static const uint32_t DATALINES0 = 0x800B; - static const uint32_t DATALINES1 = 0x800C; - - // reserved registers - static const uint32_t GPIO_DIR = 0x8010; - static const uint32_t GPIO_VAL = 0x8011; - static const uint32_t LINKSTATUS = 0x8012; - static const uint32_t LASTI2CL = 0x8013; - static const uint32_t LASTI2CH = 0x8014; - - // unmanaged default serializer / deserializer I2C addresses - static const uint32_t DES_ADDR = 0x30; - static const uint32_t SER_ADDR = 0x58; - - enum class DS90UB9xTriggerMode : uint32_t - { - Continuous = 0, - HsyncEdgePositive = 0b0001, - HsyncEdgeNegative = 0b1001, - HsyncLevelPositive = 0b0101, - HsyncLevelNegative = 0b1101, - VsyncEdgePositive = 0b0011, - VsyncEdgeNegative = 0b1011, - VsyncLevelPositive = 0b0111, - VsyncLevelNegative = 0b1111, - }; - - enum class DS90UB9xDataGate : uint32_t - { - Disabled = 0, - HsyncPositive = 0b001, - HsyncNegative = 0b101, - VsyncPositive = 0b011, - VsyncNegative = 0b111, - }; - - enum class DS90UB9xMarkMode : uint32_t - { - Disabled = 0, - HsyncRising = 0b001, - HsyncFalling = 0b101, - VsyncRising = 0b011, - VsyncFalling = 0b111, - }; - - enum class DS90UB9xDeserializerI2CRegister : uint32_t - { - PortMode = 0x6D, - PortSel = 0x4C, - I2CConfig = 0x58, - GpioCtrl0 = 0x6E, - GpioCtrl1 = 0x6F, - - SerAlias = 0x5C, - - SlaveID1 = 0x5E, - SlaveID2 = 0x5F, - SlaveID3 = 0x60, - SlaveID4 = 0x61, - SlaveID5 = 0x62, - SlaveID6 = 0x63, - SlaveID7 = 0x64, - - SlaveAlias1 = 0x66, - SlaveAlias2 = 0x67, - SlaveAlias3 = 0x68, - SlaveAlias4 = 0x69, - SlaveAlias5 = 0x6A, - SlaveAlias6 = 0x6B, - SlaveAlias7 = 0x6C, - }; - - enum class DS90UB9xSerializerI2CRegister : uint32_t - { - GPIO10 = 0x0D, - GPIO32 = 0x0E, - SCLHIGH = 0x0A, - SCLLOW = 0x0B - }; - - enum class DS90UB9xMode : uint32_t - { - Raw12BitLowFrequency = 1, - Raw12BitHighFrequency = 2, - Raw10Bit = 3, - }; - - enum class DS90UB9xDirection : uint32_t - { - Input = 0, - Output = 1 - }; -}; + static class DS90UB9x + { + public: + // managed registers + static const uint32_t ENABLE = 0x8000; + static const uint32_t READSZ = 0x8001; + static const uint32_t TRIGGER = 0x8002; + static const uint32_t TRIGGEROFF = 0x8003; + static const uint32_t DATAGATE = 0x8004; + static const uint32_t SYNCBITS = 0x8005; + static const uint32_t MARK = 0x8006; + static const uint32_t MAGIC_MASK = 0x8007; + static const uint32_t MAGIC = 0x8008; + static const uint32_t MAGIC_WAIT = 0x8009; + static const uint32_t DATAMODE = 0x800A; + static const uint32_t DATALINES0 = 0x800B; + static const uint32_t DATALINES1 = 0x800C; + + // reserved registers + static const uint32_t GPIO_DIR = 0x8010; + static const uint32_t GPIO_VAL = 0x8011; + static const uint32_t LINKSTATUS = 0x8012; + static const uint32_t LASTI2CL = 0x8013; + static const uint32_t LASTI2CH = 0x8014; + + // unmanaged default serializer / deserializer I2C addresses + static const uint32_t DES_ADDR = 0x30; + static const uint32_t SER_ADDR = 0x58; + + enum class DS90UB9xTriggerMode : uint32_t + { + Continuous = 0, + HsyncEdgePositive = 0b0001, + HsyncEdgeNegative = 0b1001, + HsyncLevelPositive = 0b0101, + HsyncLevelNegative = 0b1101, + VsyncEdgePositive = 0b0011, + VsyncEdgeNegative = 0b1011, + VsyncLevelPositive = 0b0111, + VsyncLevelNegative = 0b1111, + }; + + enum class DS90UB9xDataGate : uint32_t + { + Disabled = 0, + HsyncPositive = 0b001, + HsyncNegative = 0b101, + VsyncPositive = 0b011, + VsyncNegative = 0b111, + }; + + enum class DS90UB9xMarkMode : uint32_t + { + Disabled = 0, + HsyncRising = 0b001, + HsyncFalling = 0b101, + VsyncRising = 0b011, + VsyncFalling = 0b111, + }; + + enum class DS90UB9xDeserializerI2CRegister : uint32_t + { + PortMode = 0x6D, + PortSel = 0x4C, + I2CConfig = 0x58, + GpioCtrl0 = 0x6E, + GpioCtrl1 = 0x6F, + + SerAlias = 0x5C, + + SlaveID1 = 0x5E, + SlaveID2 = 0x5F, + SlaveID3 = 0x60, + SlaveID4 = 0x61, + SlaveID5 = 0x62, + SlaveID6 = 0x63, + SlaveID7 = 0x64, + + SlaveAlias1 = 0x66, + SlaveAlias2 = 0x67, + SlaveAlias3 = 0x68, + SlaveAlias4 = 0x69, + SlaveAlias5 = 0x6A, + SlaveAlias6 = 0x6B, + SlaveAlias7 = 0x6C, + }; + + enum class DS90UB9xSerializerI2CRegister : uint32_t + { + GPIO10 = 0x0D, + GPIO32 = 0x0E, + SCLHIGH = 0x0A, + SCLLOW = 0x0B + }; + + enum class DS90UB9xMode : uint32_t + { + Raw12BitLowFrequency = 1, + Raw12BitHighFrequency = 2, + Raw10Bit = 3, + }; + + enum class DS90UB9xDirection : uint32_t + { + Input = 0, + Output = 1 + }; + }; +} diff --git a/Source/Devices/DigitalIO.cpp b/Source/Devices/DigitalIO.cpp index df9f87e..57b2abe 100644 --- a/Source/Devices/DigitalIO.cpp +++ b/Source/Devices/DigitalIO.cpp @@ -22,6 +22,8 @@ #include "DigitalIO.h" +using namespace OnixSourcePlugin; + DigitalIO::DigitalIO(String name, const oni_dev_idx_t deviceIdx_, std::shared_ptr oni_ctx) : OnixDevice(name, BREAKOUT_BOARD_NAME, OnixDeviceType::DIGITALIO, deviceIdx_, oni_ctx) { diff --git a/Source/Devices/DigitalIO.h b/Source/Devices/DigitalIO.h index 3e9d02c..13f6f77 100644 --- a/Source/Devices/DigitalIO.h +++ b/Source/Devices/DigitalIO.h @@ -24,79 +24,82 @@ #include "../OnixDevice.h" -enum class DigitalIORegisters : uint32_t +namespace OnixSourcePlugin { - ENABLE = 0 -}; - -enum class DigitalPortState : uint16_t -{ - Pin0 = 0x1, - Pin1 = 0x2, - Pin2 = 0x4, - Pin3 = 0x8, - Pin4 = 0x10, - Pin5 = 0x20, - Pin6 = 0x40, - Pin7 = 0x80 -}; - -enum class BreakoutButtonState : uint16_t -{ - Moon = 0x1, - Triangle = 0x2, - X = 0x4, - Check = 0x8, - Circle = 0x10, - Square = 0x20, - Reserved0 = 0x40, - Reserved1 = 0x80, - PortDOn = 0x100, - PortCOn = 0x200, - PortBOn = 0x400, - PortAOn = 0x800 -}; - -/* - Configures and streams data from an AnalogIO device on a Breakout Board -*/ -class DigitalIO : public OnixDevice -{ -public: - DigitalIO(String name, const oni_dev_idx_t, std::shared_ptr oni_ctx); - - /** Configures the device so that it is ready to stream with default settings */ - int configureDevice() override; - - /** Update the settings of the device */ - bool updateSettings() override; - - /** Starts probe data streaming */ - void startAcquisition() override; - - /** Stops probe data streaming*/ - void stopAcquisition() override; - - /** Given the sourceBuffers from OnixSource, add all streams for the current device to the array */ - void addSourceBuffers(OwnedArray& sourceBuffers) override {}; - - EventChannel::Settings getEventChannelSettings(); - - void addFrame(oni_frame_t*) override; - - void processFrames() override; - - uint64_t getEventWord(); - - bool hasEventWord(); - -private: - - static const int numDigitalInputs = 8; - static const int numButtons = 6; - - Array frameArray; - Array eventWords; - - JUCE_LEAK_DETECTOR(DigitalIO); -}; + enum class DigitalIORegisters : uint32_t + { + ENABLE = 0 + }; + + enum class DigitalPortState : uint16_t + { + Pin0 = 0x1, + Pin1 = 0x2, + Pin2 = 0x4, + Pin3 = 0x8, + Pin4 = 0x10, + Pin5 = 0x20, + Pin6 = 0x40, + Pin7 = 0x80 + }; + + enum class BreakoutButtonState : uint16_t + { + Moon = 0x1, + Triangle = 0x2, + X = 0x4, + Check = 0x8, + Circle = 0x10, + Square = 0x20, + Reserved0 = 0x40, + Reserved1 = 0x80, + PortDOn = 0x100, + PortCOn = 0x200, + PortBOn = 0x400, + PortAOn = 0x800 + }; + + /* + Configures and streams data from an AnalogIO device on a Breakout Board + */ + class DigitalIO : public OnixDevice + { + public: + DigitalIO(String name, const oni_dev_idx_t, std::shared_ptr oni_ctx); + + /** Configures the device so that it is ready to stream with default settings */ + int configureDevice() override; + + /** Update the settings of the device */ + bool updateSettings() override; + + /** Starts probe data streaming */ + void startAcquisition() override; + + /** Stops probe data streaming*/ + void stopAcquisition() override; + + /** Given the sourceBuffers from OnixSource, add all streams for the current device to the array */ + void addSourceBuffers(OwnedArray& sourceBuffers) override {}; + + EventChannel::Settings getEventChannelSettings(); + + void addFrame(oni_frame_t*) override; + + void processFrames() override; + + uint64_t getEventWord(); + + bool hasEventWord(); + + private: + + static const int numDigitalInputs = 8; + static const int numButtons = 6; + + Array frameArray; + Array eventWords; + + JUCE_LEAK_DETECTOR(DigitalIO); + }; +} diff --git a/Source/Devices/HarpSyncInput.cpp b/Source/Devices/HarpSyncInput.cpp index d0a522f..8bde66a 100644 --- a/Source/Devices/HarpSyncInput.cpp +++ b/Source/Devices/HarpSyncInput.cpp @@ -22,6 +22,8 @@ #include "HarpSyncInput.h" +using namespace OnixSourcePlugin; + HarpSyncInput::HarpSyncInput(String name, const oni_dev_idx_t deviceIdx_, std::shared_ptr oni_ctx) : OnixDevice(name, BREAKOUT_BOARD_NAME, OnixDeviceType::HARPSYNCINPUT, deviceIdx_, oni_ctx) { diff --git a/Source/Devices/HarpSyncInput.h b/Source/Devices/HarpSyncInput.h index cabdc2d..a06ba76 100644 --- a/Source/Devices/HarpSyncInput.h +++ b/Source/Devices/HarpSyncInput.h @@ -24,63 +24,66 @@ #include "../OnixDevice.h" -enum class HarpSyncInputRegisters : uint32_t +namespace OnixSourcePlugin { - ENABLE = 0, - SOURCE = 1 -}; + enum class HarpSyncInputRegisters : uint32_t + { + ENABLE = 0, + SOURCE = 1 + }; -enum class HarpSyncSource : uint32_t -{ - Breakout = 0, - ClockAdapter = 1 -}; + enum class HarpSyncSource : uint32_t + { + Breakout = 0, + ClockAdapter = 1 + }; -/* - Configures and streams data from a HarpSyncInput device on a Breakout Board -*/ -class HarpSyncInput : public OnixDevice -{ -public: - HarpSyncInput(String name, const oni_dev_idx_t, std::shared_ptr oni_ctx); + /* + Configures and streams data from a HarpSyncInput device on a Breakout Board + */ + class HarpSyncInput : public OnixDevice + { + public: + HarpSyncInput(String name, const oni_dev_idx_t, std::shared_ptr oni_ctx); - /** Configures the device so that it is ready to stream with default settings */ - int configureDevice() override; + /** Configures the device so that it is ready to stream with default settings */ + int configureDevice() override; - /** Update the settings of the device */ - bool updateSettings() override; + /** Update the settings of the device */ + bool updateSettings() override; - /** Starts probe data streaming */ - void startAcquisition() override; + /** Starts probe data streaming */ + void startAcquisition() override; - /** Stops probe data streaming*/ - void stopAcquisition() override; + /** Stops probe data streaming*/ + void stopAcquisition() override; - /** Given the sourceBuffers from OnixSource, add all streams for the current device to the array */ - void addSourceBuffers(OwnedArray& sourceBuffers) override; + /** Given the sourceBuffers from OnixSource, add all streams for the current device to the array */ + void addSourceBuffers(OwnedArray& sourceBuffers) override; - void addFrame(oni_frame_t* frame) override; + void addFrame(oni_frame_t* frame) override; - void processFrames() override; + void processFrames() override; -private: + private: - DataBuffer* harpTimeBuffer; + DataBuffer* harpTimeBuffer; - static const int numFrames = 2; + static const int numFrames = 2; - Array frameArray; + Array frameArray; - unsigned short currentFrame = 0; - int sampleNumber = 0; + unsigned short currentFrame = 0; + int sampleNumber = 0; - bool shouldAddToBuffer = false; + bool shouldAddToBuffer = false; - float harpTimeSamples[numFrames]; + float harpTimeSamples[numFrames]; - double timestamps[numFrames]; - int64 sampleNumbers[numFrames]; - uint64 eventCodes[numFrames]; + double timestamps[numFrames]; + int64 sampleNumbers[numFrames]; + uint64 eventCodes[numFrames]; - JUCE_LEAK_DETECTOR(HarpSyncInput); -}; + JUCE_LEAK_DETECTOR(HarpSyncInput); + }; +} diff --git a/Source/Devices/HeadStageEEPROM.cpp b/Source/Devices/HeadStageEEPROM.cpp index 7d28807..f6ec487 100644 --- a/Source/Devices/HeadStageEEPROM.cpp +++ b/Source/Devices/HeadStageEEPROM.cpp @@ -24,6 +24,8 @@ #include "DS90UB9x.h" #include +using namespace OnixSourcePlugin; + HeadStageEEPROM::HeadStageEEPROM(const oni_dev_idx_t dev_id, std::shared_ptr ctx) : I2CRegisterContext(HeadStageEEPROM::EEPROM_ADDRESS, dev_id, ctx) { diff --git a/Source/Devices/HeadStageEEPROM.h b/Source/Devices/HeadStageEEPROM.h index c211a0c..0c93714 100644 --- a/Source/Devices/HeadStageEEPROM.h +++ b/Source/Devices/HeadStageEEPROM.h @@ -28,18 +28,20 @@ #include #include -class HeadStageEEPROM : - public I2CRegisterContext +namespace OnixSourcePlugin { -public: - HeadStageEEPROM(const oni_dev_idx_t, std::shared_ptr); + class HeadStageEEPROM : + public I2CRegisterContext + { + public: + HeadStageEEPROM(const oni_dev_idx_t, std::shared_ptr); - uint32_t GetHeadStageID(); + uint32_t GetHeadStageID(); -private: - static const uint32_t EEPROM_ADDRESS = 0x51; - static const uint32_t DEVID_START_ADDR = 18; - - JUCE_LEAK_DETECTOR(HeadStageEEPROM); -}; + private: + static const uint32_t EEPROM_ADDRESS = 0x51; + static const uint32_t DEVID_START_ADDR = 18; + JUCE_LEAK_DETECTOR(HeadStageEEPROM); + }; +} diff --git a/Source/Devices/Heartbeat.cpp b/Source/Devices/Heartbeat.cpp index 664ab26..c587372 100644 --- a/Source/Devices/Heartbeat.cpp +++ b/Source/Devices/Heartbeat.cpp @@ -22,6 +22,8 @@ #include "Heartbeat.h" +using namespace OnixSourcePlugin; + Heartbeat::Heartbeat(String name, const oni_dev_idx_t deviceIdx_, std::shared_ptr oni_ctx) : OnixDevice(name, BREAKOUT_BOARD_NAME, OnixDeviceType::HEARTBEAT, deviceIdx_, oni_ctx) { diff --git a/Source/Devices/Heartbeat.h b/Source/Devices/Heartbeat.h index 7819de3..aac303a 100644 --- a/Source/Devices/Heartbeat.h +++ b/Source/Devices/Heartbeat.h @@ -24,43 +24,46 @@ #include "../OnixDevice.h" -enum class HeartbeatRegisters : uint32_t +namespace OnixSourcePlugin { - ENABLE = 0, - CLK_DIV = 1, - CLK_HZ = 2 -}; + enum class HeartbeatRegisters : uint32_t + { + ENABLE = 0, + CLK_DIV = 1, + CLK_HZ = 2 + }; -/* - Configures and streams data from a Heartbeat device on a Breakout Board -*/ -class Heartbeat : public OnixDevice -{ -public: - Heartbeat(String name, const oni_dev_idx_t, std::shared_ptr oni_ctx); + /* + Configures a Heartbeat device on a Breakout Board + */ + class Heartbeat : public OnixDevice + { + public: + Heartbeat(String name, const oni_dev_idx_t, std::shared_ptr oni_ctx); - /** Configures the device so that it is ready to stream with default settings */ - int configureDevice() override; + /** Configures the device so that it is ready to stream with default settings */ + int configureDevice() override; - /** Update the settings of the device */ - bool updateSettings() override; + /** Update the settings of the device */ + bool updateSettings() override; - /** Starts probe data streaming */ - void startAcquisition() override {}; + /** Starts probe data streaming */ + void startAcquisition() override {}; - /** Stops probe data streaming*/ - void stopAcquisition() override {}; + /** Stops probe data streaming*/ + void stopAcquisition() override {}; - /** Given the sourceBuffers from OnixSource, add all streams for the current device to the array */ - void addSourceBuffers(OwnedArray& sourceBuffers) override {}; + /** Given the sourceBuffers from OnixSource, add all streams for the current device to the array */ + void addSourceBuffers(OwnedArray& sourceBuffers) override {}; - void addFrame(oni_frame_t* frame) override { oni_destroy_frame(frame); } + void addFrame(oni_frame_t* frame) override { oni_destroy_frame(frame); } - void processFrames() override {}; + void processFrames() override {}; -private: + private: - const uint32_t beatsPerSecond = 100; + const uint32_t beatsPerSecond = 100; - JUCE_LEAK_DETECTOR(Heartbeat); -}; + JUCE_LEAK_DETECTOR(Heartbeat); + }; +} diff --git a/Source/Devices/MemoryMonitor.cpp b/Source/Devices/MemoryMonitor.cpp index 6c40c17..b5fe3a0 100644 --- a/Source/Devices/MemoryMonitor.cpp +++ b/Source/Devices/MemoryMonitor.cpp @@ -23,6 +23,8 @@ #include "MemoryMonitor.h" #include "DigitalIO.h" +using namespace OnixSourcePlugin; + MemoryMonitorUsage::MemoryMonitorUsage(GenericProcessor* p) : LevelMonitor(p) { diff --git a/Source/Devices/MemoryMonitor.h b/Source/Devices/MemoryMonitor.h index add5cab..1c7060a 100644 --- a/Source/Devices/MemoryMonitor.h +++ b/Source/Devices/MemoryMonitor.h @@ -24,107 +24,110 @@ #include "../OnixDevice.h" -class DigitalIO; - -enum class MemoryMonitorRegisters : uint32_t +namespace OnixSourcePlugin { - ENABLE = 0, - CLK_DIV = 1, - CLK_HZ = 2, - TOTAL_MEM = 3 -}; + class DigitalIO; -/* - Configures and streams data from a MemoryMonitor device on a Breakout Board -*/ -class MemoryMonitor : public OnixDevice -{ -public: - MemoryMonitor(String name, const oni_dev_idx_t, std::shared_ptr oni_ctx); + enum class MemoryMonitorRegisters : uint32_t + { + ENABLE = 0, + CLK_DIV = 1, + CLK_HZ = 2, + TOTAL_MEM = 3 + }; - /** Configures the device so that it is ready to stream with default settings */ - int configureDevice() override; + /* + Configures and streams data from a MemoryMonitor device on a Breakout Board + */ + class MemoryMonitor : public OnixDevice + { + public: + MemoryMonitor(String name, const oni_dev_idx_t, std::shared_ptr oni_ctx); - /** Update the settings of the device */ - bool updateSettings() override; + /** Configures the device so that it is ready to stream with default settings */ + int configureDevice() override; - /** Starts probe data streaming */ - void startAcquisition() override; + /** Update the settings of the device */ + bool updateSettings() override; - /** Stops probe data streaming*/ - void stopAcquisition() override; + /** Starts probe data streaming */ + void startAcquisition() override; - /** Given the sourceBuffers from OnixSource, add all streams for the current device to the array */ - void addSourceBuffers(OwnedArray& sourceBuffers) override; + /** Stops probe data streaming*/ + void stopAcquisition() override; - void addFrame(oni_frame_t*) override; + /** Given the sourceBuffers from OnixSource, add all streams for the current device to the array */ + void addSourceBuffers(OwnedArray& sourceBuffers) override; - void processFrames() override; + void addFrame(oni_frame_t*) override; - float getLastPercentUsedValue(); + void processFrames() override; - void setDigitalIO(std::shared_ptr digitalIO) { m_digitalIO = digitalIO; } + float getLastPercentUsedValue(); -private: + void setDigitalIO(std::shared_ptr digitalIO) { m_digitalIO = digitalIO; } - DataBuffer* percentUsedBuffer; + private: - std::shared_ptr m_digitalIO; + DataBuffer* percentUsedBuffer; - uint64_t prevWord = 0; + std::shared_ptr m_digitalIO; - static const int numFrames = 10; + uint64_t prevWord = 0; - Array frameArray; + static const int numFrames = 10; - unsigned short currentFrame = 0; - int sampleNumber = 0; + Array frameArray; - /** The frequency at which memory use is recorded in Hz. */ - const uint32_t samplesPerSecond = 100; + unsigned short currentFrame = 0; + int sampleNumber = 0; - bool shouldAddToBuffer = false; + /** The frequency at which memory use is recorded in Hz. */ + const uint32_t samplesPerSecond = 100; - float percentUsedSamples[numFrames]; - float bytesUsedSamples[numFrames]; + bool shouldAddToBuffer = false; - double timestamps[numFrames]; - int64_t sampleNumbers[numFrames]; - uint64_t eventCodes[numFrames]; + float percentUsedSamples[numFrames]; + float bytesUsedSamples[numFrames]; - /** The total amount of memory, in 32-bit words, on the hardware that is available for data buffering*/ - uint32_t totalMemory; + double timestamps[numFrames]; + int64_t sampleNumbers[numFrames]; + uint64_t eventCodes[numFrames]; - std::atomic lastPercentUsedValue = 0.0f; + /** The total amount of memory, in 32-bit words, on the hardware that is available for data buffering*/ + uint32_t totalMemory; - JUCE_LEAK_DETECTOR(MemoryMonitor); -}; + std::atomic lastPercentUsedValue = 0.0f; -/* - Tracks the MemoryMonitor usage while data acquisition is running -*/ -class MemoryMonitorUsage : public LevelMonitor -{ -public: - MemoryMonitorUsage(GenericProcessor*); + JUCE_LEAK_DETECTOR(MemoryMonitor); + }; + + /* + Tracks the MemoryMonitor usage while data acquisition is running + */ + class MemoryMonitorUsage : public LevelMonitor + { + public: + MemoryMonitorUsage(GenericProcessor*); - void timerCallback() override; + void timerCallback() override; - void setMemoryMonitor(std::shared_ptr memoryMonitor); + void setMemoryMonitor(std::shared_ptr memoryMonitor); - void startAcquisition(); + void startAcquisition(); - void stopAcquisition(); + void stopAcquisition(); -private: + private: - std::shared_ptr device; + std::shared_ptr device; - // NB: Calculate the maximum logarithmic value to convert from linear scale (x: 0-100) to logarithmic scale (y: 0-1) - // using the following equation: y = log_e(x + 1) / log_e(x_max + 1); - const float maxLogarithmicValue = std::log(101); + // NB: Calculate the maximum logarithmic value to convert from linear scale (x: 0-100) to logarithmic scale (y: 0-1) + // using the following equation: y = log_e(x + 1) / log_e(x_max + 1); + const float maxLogarithmicValue = std::log(101); - const int TimerFrequencyHz = 10; + const int TimerFrequencyHz = 10; - JUCE_LEAK_DETECTOR(MemoryMonitorUsage); -}; + JUCE_LEAK_DETECTOR(MemoryMonitorUsage); + }; +} diff --git a/Source/Devices/Neuropixels2e.cpp b/Source/Devices/Neuropixels2e.cpp index 7fded7e..aa6f118 100644 --- a/Source/Devices/Neuropixels2e.cpp +++ b/Source/Devices/Neuropixels2e.cpp @@ -22,6 +22,8 @@ #include "Neuropixels2e.h" +using namespace OnixSourcePlugin; + Neuropixels2e::Neuropixels2e(String name, const oni_dev_idx_t deviceIdx_, std::shared_ptr ctx_) : OnixDevice(name, NEUROPIXELSV2E_HEADSTAGE_NAME, OnixDeviceType::NEUROPIXELSV2E, deviceIdx_, ctx_), I2CRegisterContext(ProbeI2CAddress, deviceIdx_, ctx_), @@ -42,7 +44,7 @@ Neuropixels2e::Neuropixels2e(String name, const oni_dev_idx_t deviceIdx_, std::s void Neuropixels2e::createDataStream(int n) { StreamInfo apStream = StreamInfo( - OnixDevice::createStreamName({ PortController::getPortName(PortController::getPortFromIndex(deviceIdx)), getHeadstageName(), "Probe" + String(n) }), + OnixDevice::createStreamName({ getPortNameFromIndex(getDeviceIdx()), getHeadstageName(), "Probe" + String(n) }), "Neuropixels 2.0 data stream", getStreamIdentifier(), numberOfChannels, diff --git a/Source/Devices/Neuropixels2e.h b/Source/Devices/Neuropixels2e.h index 563e1ca..4103f42 100644 --- a/Source/Devices/Neuropixels2e.h +++ b/Source/Devices/Neuropixels2e.h @@ -28,239 +28,242 @@ #include "DS90UB9x.h" #include "PortController.h" -enum class NeuropixelsV2Reference : uint32_t +namespace OnixSourcePlugin { - External, - Tip1, - Tip2, - Tip3, - Tip4 -}; - -enum class NeuropixelsV2Status : uint32_t -{ - SR_OK = 1 << 7 -}; - -/* - Configures and streams data from a Neuropixels 2.0e device -*/ -class Neuropixels2e : public INeuropixel, - public OnixDevice, - public I2CRegisterContext -{ -public: - Neuropixels2e(String name, const oni_dev_idx_t, std::shared_ptr); - - ~Neuropixels2e() + enum class NeuropixelsV2Reference : uint32_t { - if (serializer != nullptr) - serializer->WriteByte((uint32_t)DS90UB9x::DS90UB9xSerializerI2CRegister::GPIO10, DefaultGPO10Config); - - if (i2cContext != nullptr) - selectProbe(NoProbeSelected); - - if (deviceContext != nullptr && deviceContext->isInitialized()) - deviceContext->setOption(ONIX_OPT_PASSTHROUGH, 0); - } - - int configureDevice() override; - - /** Update the settings of the device */ - bool updateSettings() override; - - /** Starts probe data streaming */ - void startAcquisition() override; - - /** Stops probe data streaming*/ - void stopAcquisition() override; + External, + Tip1, + Tip2, + Tip3, + Tip4 + }; - void addFrame(oni_frame_t*) override; + enum class NeuropixelsV2Status : uint32_t + { + SR_OK = 1 << 7 + }; - void processFrames() override; + /* + Configures and streams data from a Neuropixels 2.0e device + */ + class Neuropixels2e : public INeuropixel, + public OnixDevice, + public I2CRegisterContext + { + public: + Neuropixels2e(String name, const oni_dev_idx_t, std::shared_ptr); - void addSourceBuffers(OwnedArray& sourceBuffers) override; + ~Neuropixels2e() + { + if (serializer != nullptr) + serializer->WriteByte((uint32_t)DS90UB9x::DS90UB9xSerializerI2CRegister::GPIO10, DefaultGPO10Config); - int getNumProbes() const; + if (i2cContext != nullptr) + selectProbe(NoProbeSelected); - static const int baseBitsPerChannel = 4; - static const int configurationBitCount = NeuropixelsV2eValues::numberOfChannels * baseBitsPerChannel / 2; + if (deviceContext != nullptr && deviceContext->isInitialized()) + deviceContext->setOption(ONIX_OPT_PASSTHROUGH, 0); + } - static const int referencePixelCount = 4; - static const int dummyPixelCount = 4; - static const int registersPerShank = NeuropixelsV2eValues::electrodesPerShank + referencePixelCount + dummyPixelCount; + int configureDevice() override; - using BaseBitsArray = std::array, 2>; - using ShankBitsArray = std::array, 4>; + /** Update the settings of the device */ + bool updateSettings() override; - BaseBitsArray static makeBaseBits(NeuropixelsV2Reference reference); - ShankBitsArray static makeShankBits(NeuropixelsV2Reference reference, std::array channelMap); + /** Starts probe data streaming */ + void startAcquisition() override; - template - void writeShiftRegister(uint32_t srAddress, std::bitset bits); + /** Stops probe data streaming*/ + void stopAcquisition() override; - void setGainCorrectionFile(int index, String filename); + void addFrame(oni_frame_t*) override; - String getGainCorrectionFile(int index); + void processFrames() override; - // INeuropixel Methods + void addSourceBuffers(OwnedArray& sourceBuffers) override; - std::vector selectElectrodeConfiguration(String config) override; + int getNumProbes() const; - uint64_t getProbeSerialNumber(int index) override; + static const int baseBitsPerChannel = 4; + static const int configurationBitCount = NeuropixelsV2eValues::numberOfChannels * baseBitsPerChannel / 2; - void defineMetadata(ProbeSettings*, int); + static const int referencePixelCount = 4; + static const int dummyPixelCount = 4; + static const int registersPerShank = NeuropixelsV2eValues::electrodesPerShank + referencePixelCount + dummyPixelCount; - void setSettings(ProbeSettings* settings_, int index) override; + using BaseBitsArray = std::array, 2>; + using ShankBitsArray = std::array, 4>; -private: - DataBuffer* amplifierBuffer[2]; + BaseBitsArray static makeBaseBits(NeuropixelsV2Reference reference); + ShankBitsArray static makeShankBits(NeuropixelsV2Reference reference, std::array channelMap); - std::array probeSN; - std::array gainCorrection; - std::array gainCorrectionFilePath; + template + void writeShiftRegister(uint32_t srAddress, std::bitset bits); - void createDataStream(int n); + void setGainCorrectionFile(int index, String filename); - uint64_t getProbeSN(uint8_t probeSelect); - void configureSerDes(); - void setProbeSupply(bool); - void resetProbes(); + String getGainCorrectionFile(int index); - void selectProbe(uint8_t probeSelect); - void configureProbeStreaming(); - void writeConfiguration(ProbeSettings*); + // INeuropixel Methods - NeuropixelsV2Reference getReference(int); - static String getShankName(uint32_t shiftRegisterAddress); + std::vector selectElectrodeConfiguration(String config) override; - int m_numProbes = 0; + uint64_t getProbeSerialNumber(int index) override; - const float sampleRate = 30000.0f; - static const int numFrames = 10; - static const int numSamples = numberOfChannels * numFrames; + void defineMetadata(ProbeSettings*, int); - std::array samples; + void setSettings(ProbeSettings* settings_, int index) override; - int64 sampleNumbers[numFrames]; - double timestamps[numFrames]; - uint64 eventCodes[numFrames]; + private: + DataBuffer* amplifierBuffer[2]; - bool shouldAddToBuffer = false; - int frameCount = 0; - int sampleNumber = 0; + std::array probeSN; + std::array gainCorrection; + std::array gainCorrectionFilePath; - bool singleProbe = false; + void createDataStream(int n); - std::unique_ptr serializer; - std::unique_ptr deserializer; - std::unique_ptr flex; - std::unique_ptr probeControl; + uint64_t getProbeSN(uint8_t probeSelect); + void configureSerDes(); + void setProbeSupply(bool); + void resetProbes(); - static const int ProbeI2CAddress = 0x10; - static const int FlexAddress = 0x50; + void selectProbe(uint8_t probeSelect); + void configureProbeStreaming(); + void writeConfiguration(ProbeSettings*); - static const int ProbeAddress = 0x10; - static const int FlexEEPROMAddress = 0x50; + NeuropixelsV2Reference getReference(int); + static String getShankName(uint32_t shiftRegisterAddress); - static const uint32_t GPO10SupplyMask = 1 << 3; // Used to turn on VDDA analog supply - static const uint32_t GPO10ResetMask = 1 << 7; // Used to issue full reset commands to probes - static const uint8_t DefaultGPO10Config = 0b00010001; // NPs in reset, VDDA not enabled - static const uint8_t NoProbeSelected = 0b00010001; // No probes selected - static const uint8_t ProbeASelected = 0b00011001; // TODO: Changes in Rev. B of headstage - static const uint8_t ProbeBSelected = 0b10011001; - - static const int FramesPerSuperFrame = 16; - static const int AdcsPerProbe = 24; - static const int ChannelCount = 384; - static const int FrameWords = 36; // TRASH TRASH TRASH 0 ADC0 ADC8 ADC16 0 ADC1 ADC9 ADC17 0 ... ADC7 ADC15 ADC23 0 - - // unmanaged register map - static const uint32_t OP_MODE = 0x00; - static const uint32_t REC_MODE = 0x01; - static const uint32_t CAL_MODE = 0x02; - static const uint32_t ADC_CONFIG = 0x03; - static const uint32_t TEST_CONFIG1 = 0x04; - static const uint32_t TEST_CONFIG2 = 0x05; - static const uint32_t TEST_CONFIG3 = 0x06; - static const uint32_t TEST_CONFIG4 = 0x07; - static const uint32_t TEST_CONFIG5 = 0x08; - static const uint32_t STATUS = 0x09; - static const uint32_t SUPERSYNC0 = 0x0A; - static const uint32_t SUPERSYNC1 = 0x0B; - static const uint32_t SUPERSYNC2 = 0x0C; - static const uint32_t SUPERSYNC3 = 0x0D; - static const uint32_t SUPERSYNC4 = 0x0E; - static const uint32_t SUPERSYNC5 = 0x0F; - static const uint32_t SUPERSYNC6 = 0x10; - static const uint32_t SUPERSYNC7 = 0x11; - static const uint32_t SUPERSYNC8 = 0x12; - static const uint32_t SUPERSYNC9 = 0x13; - static const uint32_t SUPERSYNC10 = 0x14; - static const uint32_t SUPERSYNC11 = 0x15; - static const uint32_t SR_CHAIN6 = 0x16; // Odd channel base config - static const uint32_t SR_CHAIN5 = 0x17; // Even channel base config - static const uint32_t SR_CHAIN4 = 0x18; // Shank 4 - static const uint32_t SR_CHAIN3 = 0x19; // Shank 3 - static const uint32_t SR_CHAIN2 = 0x1A; // Shank 2 - static const uint32_t SR_CHAIN1 = 0x1B; // Shank 1 - static const uint32_t SR_LENGTH2 = 0x1C; - static const uint32_t SR_LENGTH1 = 0x1D; - static const uint32_t PROBE_ID = 0x1E; - static const uint32_t SOFT_RESET = 0x1F; - - const uint32_t OFFSET_PROBE_SN = 0x00; - const uint32_t OFFSET_FLEX_VERSION = 0x10; - const uint32_t OFFSET_FLEX_REVISION = 0x11; - const uint32_t OFFSET_FLEX_PN = 0x20; - const uint32_t OFFSET_PROBE_PN = 0x40; - - Array frameArray; - - static inline const std::array adcIndices = { - 0, 1, 2, - 4, 5, 6, - 8, 9, 10, - 12, 13, 14, - 16, 17, 18, - 20, 21, 22, - 24, 25, 26, - 28, 29, 30 - }; + int m_numProbes = 0; - static inline const std::array, AdcsPerProbe> rawToChannel = { { - { 0, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30 }, // Data Index 9, ADC 0 - { 128, 130, 132, 134, 136, 138, 140, 142, 144, 146, 148, 150, 152, 154, 156, 158 }, // Data Index 10, ADC 8 - { 256, 258, 260, 262, 264, 266, 268, 270, 272, 274, 276, 278, 280, 282, 284, 286 }, // Data Index 11, ADC 16 + const float sampleRate = 30000.0f; + static const int numFrames = 10; + static const int numSamples = numberOfChannels * numFrames; - { 1, 3, 5, 7, 9, 11, 13, 15, 17, 19, 21, 23, 25, 27, 29, 31 }, // Data Index 13, ADC 1 - { 129, 131, 133, 135, 137, 139, 141, 143, 145, 147, 149, 151, 153, 155, 157, 159 }, // Data Index 14, ADC 9 - { 257, 259, 261, 263, 265, 267, 269, 271, 273, 275, 277, 279, 281, 283, 285, 287 }, // Data Index 15, ADC 17 + std::array samples; - { 32, 34, 36, 38, 40, 42, 44, 46, 48, 50, 52, 54, 56, 58, 60, 62 }, // Data Index 17, ADC 2 - { 160, 162, 164, 166, 168, 170, 172, 174, 176, 178, 180, 182, 184, 186, 188, 190 }, // Data Index 18, ADC 10 - { 288, 290, 292, 294, 296, 298, 300, 302, 304, 306, 308, 310, 312, 314, 316, 318 }, // Data Index 19, ADC 18 + int64 sampleNumbers[numFrames]; + double timestamps[numFrames]; + uint64 eventCodes[numFrames]; - { 33, 35, 37, 39, 41, 43, 45, 47, 49, 51, 53, 55, 57, 59, 61, 63 }, // Data Index 21, ADC 3 - { 161, 163, 165, 167, 169, 171, 173, 175, 177, 179, 181, 183, 185, 187, 189, 191 }, // Data Index 22, ADC 11 - { 289, 291, 293, 295, 297, 299, 301, 303, 305, 307, 309, 311, 313, 315, 317, 319 }, // Data Index 23, ADC 19 + bool shouldAddToBuffer = false; + int frameCount = 0; + int sampleNumber = 0; - { 64, 66, 68, 70, 72, 74, 76, 78, 80, 82, 84, 86, 88, 90, 92, 94 }, // Data Index 25, ADC 4 - { 192, 194, 196, 198, 200, 202, 204, 206, 208, 210, 212, 214, 216, 218, 220, 222 }, // Data Index 26, ADC 12 - { 320, 322, 324, 326, 328, 330, 332, 334, 336, 338, 340, 342, 344, 346, 348, 350 }, // Data Index 27, ADC 20 + bool singleProbe = false; - { 65, 67, 69, 71, 73, 75, 77, 79, 81, 83, 85, 87, 89, 91, 93, 95 }, // Data Index 29, ADC 5 - { 193, 195, 197, 199, 201, 203, 205, 207, 209, 211, 213, 215, 217, 219, 221, 223 }, // Data Index 30, ADC 13 - { 321, 323, 325, 327, 329, 331, 333, 335, 337, 339, 341, 343, 345, 347, 349, 351 }, // Data Index 31, ADC 21 + std::unique_ptr serializer; + std::unique_ptr deserializer; + std::unique_ptr flex; + std::unique_ptr probeControl; - { 96, 98, 100, 102, 104, 106, 108, 110, 112, 114, 116, 118, 120, 122, 124, 126 }, // Data Index 33, ADC 6 - { 224, 226, 228, 230, 232, 234, 236, 238, 240, 242, 244, 246, 248, 250, 252, 254 }, // Data Index 34, ADC 14 - { 352, 354, 356, 358, 360, 362, 364, 366, 368, 370, 372, 374, 376, 378, 380, 382 }, // Data Index 35, ADC 22 + static const int ProbeI2CAddress = 0x10; + static const int FlexAddress = 0x50; - { 97, 99, 101, 103, 105, 107, 109, 111, 113, 115, 117, 119, 121, 123, 125, 127 }, // Data Index 37, ADC 7 - { 225, 227, 229, 231, 233, 235, 237, 239, 241, 243, 245, 247, 249, 251, 253, 255 }, // Data Index 38, ADC 15 - { 353, 355, 357, 359, 361, 363, 365, 367, 369, 371, 373, 375, 377, 379, 381, 383 }, // Data Index 39, ADC 23 - } }; + static const int ProbeAddress = 0x10; + static const int FlexEEPROMAddress = 0x50; - JUCE_LEAK_DETECTOR(Neuropixels2e); -}; + static const uint32_t GPO10SupplyMask = 1 << 3; // Used to turn on VDDA analog supply + static const uint32_t GPO10ResetMask = 1 << 7; // Used to issue full reset commands to probes + static const uint8_t DefaultGPO10Config = 0b00010001; // NPs in reset, VDDA not enabled + static const uint8_t NoProbeSelected = 0b00010001; // No probes selected + static const uint8_t ProbeASelected = 0b00011001; // TODO: Changes in Rev. B of headstage + static const uint8_t ProbeBSelected = 0b10011001; + + static const int FramesPerSuperFrame = 16; + static const int AdcsPerProbe = 24; + static const int ChannelCount = 384; + static const int FrameWords = 36; // TRASH TRASH TRASH 0 ADC0 ADC8 ADC16 0 ADC1 ADC9 ADC17 0 ... ADC7 ADC15 ADC23 0 + + // unmanaged register map + static const uint32_t OP_MODE = 0x00; + static const uint32_t REC_MODE = 0x01; + static const uint32_t CAL_MODE = 0x02; + static const uint32_t ADC_CONFIG = 0x03; + static const uint32_t TEST_CONFIG1 = 0x04; + static const uint32_t TEST_CONFIG2 = 0x05; + static const uint32_t TEST_CONFIG3 = 0x06; + static const uint32_t TEST_CONFIG4 = 0x07; + static const uint32_t TEST_CONFIG5 = 0x08; + static const uint32_t STATUS = 0x09; + static const uint32_t SUPERSYNC0 = 0x0A; + static const uint32_t SUPERSYNC1 = 0x0B; + static const uint32_t SUPERSYNC2 = 0x0C; + static const uint32_t SUPERSYNC3 = 0x0D; + static const uint32_t SUPERSYNC4 = 0x0E; + static const uint32_t SUPERSYNC5 = 0x0F; + static const uint32_t SUPERSYNC6 = 0x10; + static const uint32_t SUPERSYNC7 = 0x11; + static const uint32_t SUPERSYNC8 = 0x12; + static const uint32_t SUPERSYNC9 = 0x13; + static const uint32_t SUPERSYNC10 = 0x14; + static const uint32_t SUPERSYNC11 = 0x15; + static const uint32_t SR_CHAIN6 = 0x16; // Odd channel base config + static const uint32_t SR_CHAIN5 = 0x17; // Even channel base config + static const uint32_t SR_CHAIN4 = 0x18; // Shank 4 + static const uint32_t SR_CHAIN3 = 0x19; // Shank 3 + static const uint32_t SR_CHAIN2 = 0x1A; // Shank 2 + static const uint32_t SR_CHAIN1 = 0x1B; // Shank 1 + static const uint32_t SR_LENGTH2 = 0x1C; + static const uint32_t SR_LENGTH1 = 0x1D; + static const uint32_t PROBE_ID = 0x1E; + static const uint32_t SOFT_RESET = 0x1F; + + const uint32_t OFFSET_PROBE_SN = 0x00; + const uint32_t OFFSET_FLEX_VERSION = 0x10; + const uint32_t OFFSET_FLEX_REVISION = 0x11; + const uint32_t OFFSET_FLEX_PN = 0x20; + const uint32_t OFFSET_PROBE_PN = 0x40; + + Array frameArray; + + static inline const std::array adcIndices = { + 0, 1, 2, + 4, 5, 6, + 8, 9, 10, + 12, 13, 14, + 16, 17, 18, + 20, 21, 22, + 24, 25, 26, + 28, 29, 30 + }; + + static inline const std::array, AdcsPerProbe> rawToChannel = { { + { 0, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30 }, // Data Index 9, ADC 0 + { 128, 130, 132, 134, 136, 138, 140, 142, 144, 146, 148, 150, 152, 154, 156, 158 }, // Data Index 10, ADC 8 + { 256, 258, 260, 262, 264, 266, 268, 270, 272, 274, 276, 278, 280, 282, 284, 286 }, // Data Index 11, ADC 16 + + { 1, 3, 5, 7, 9, 11, 13, 15, 17, 19, 21, 23, 25, 27, 29, 31 }, // Data Index 13, ADC 1 + { 129, 131, 133, 135, 137, 139, 141, 143, 145, 147, 149, 151, 153, 155, 157, 159 }, // Data Index 14, ADC 9 + { 257, 259, 261, 263, 265, 267, 269, 271, 273, 275, 277, 279, 281, 283, 285, 287 }, // Data Index 15, ADC 17 + + { 32, 34, 36, 38, 40, 42, 44, 46, 48, 50, 52, 54, 56, 58, 60, 62 }, // Data Index 17, ADC 2 + { 160, 162, 164, 166, 168, 170, 172, 174, 176, 178, 180, 182, 184, 186, 188, 190 }, // Data Index 18, ADC 10 + { 288, 290, 292, 294, 296, 298, 300, 302, 304, 306, 308, 310, 312, 314, 316, 318 }, // Data Index 19, ADC 18 + + { 33, 35, 37, 39, 41, 43, 45, 47, 49, 51, 53, 55, 57, 59, 61, 63 }, // Data Index 21, ADC 3 + { 161, 163, 165, 167, 169, 171, 173, 175, 177, 179, 181, 183, 185, 187, 189, 191 }, // Data Index 22, ADC 11 + { 289, 291, 293, 295, 297, 299, 301, 303, 305, 307, 309, 311, 313, 315, 317, 319 }, // Data Index 23, ADC 19 + + { 64, 66, 68, 70, 72, 74, 76, 78, 80, 82, 84, 86, 88, 90, 92, 94 }, // Data Index 25, ADC 4 + { 192, 194, 196, 198, 200, 202, 204, 206, 208, 210, 212, 214, 216, 218, 220, 222 }, // Data Index 26, ADC 12 + { 320, 322, 324, 326, 328, 330, 332, 334, 336, 338, 340, 342, 344, 346, 348, 350 }, // Data Index 27, ADC 20 + + { 65, 67, 69, 71, 73, 75, 77, 79, 81, 83, 85, 87, 89, 91, 93, 95 }, // Data Index 29, ADC 5 + { 193, 195, 197, 199, 201, 203, 205, 207, 209, 211, 213, 215, 217, 219, 221, 223 }, // Data Index 30, ADC 13 + { 321, 323, 325, 327, 329, 331, 333, 335, 337, 339, 341, 343, 345, 347, 349, 351 }, // Data Index 31, ADC 21 + + { 96, 98, 100, 102, 104, 106, 108, 110, 112, 114, 116, 118, 120, 122, 124, 126 }, // Data Index 33, ADC 6 + { 224, 226, 228, 230, 232, 234, 236, 238, 240, 242, 244, 246, 248, 250, 252, 254 }, // Data Index 34, ADC 14 + { 352, 354, 356, 358, 360, 362, 364, 366, 368, 370, 372, 374, 376, 378, 380, 382 }, // Data Index 35, ADC 22 + + { 97, 99, 101, 103, 105, 107, 109, 111, 113, 115, 117, 119, 121, 123, 125, 127 }, // Data Index 37, ADC 7 + { 225, 227, 229, 231, 233, 235, 237, 239, 241, 243, 245, 247, 249, 251, 253, 255 }, // Data Index 38, ADC 15 + { 353, 355, 357, 359, 361, 363, 365, 367, 369, 371, 373, 375, 377, 379, 381, 383 }, // Data Index 39, ADC 23 + } }; + + JUCE_LEAK_DETECTOR(Neuropixels2e); + }; +} diff --git a/Source/Devices/Neuropixels_1.cpp b/Source/Devices/Neuropixels_1.cpp index 6162746..478e721 100644 --- a/Source/Devices/Neuropixels_1.cpp +++ b/Source/Devices/Neuropixels_1.cpp @@ -22,6 +22,8 @@ #include "Neuropixels_1.h" +using namespace OnixSourcePlugin; + BackgroundUpdaterWithProgressWindow::BackgroundUpdaterWithProgressWindow(Neuropixels_1* d) : ThreadWithProgressWindow("Writing calibration files to Neuropixels Probe: " + d->getName(), true, false) { @@ -173,7 +175,7 @@ Neuropixels_1::Neuropixels_1(String name, const oni_dev_idx_t deviceIdx_, std::s I2CRegisterContext(ProbeI2CAddress, deviceIdx_, ctx_), INeuropixel(NeuropixelsV1fValues::numberOfSettings, NeuropixelsV1fValues::numberOfShanks) { - String port = PortController::getPortName(PortController::getPortFromIndex(deviceIdx)); + String port = getPortNameFromIndex(deviceIdx); auto streamIdentifier = getStreamIdentifier(); StreamInfo apStream = StreamInfo( diff --git a/Source/Devices/Neuropixels_1.h b/Source/Devices/Neuropixels_1.h index e543926..fba6c33 100644 --- a/Source/Devices/Neuropixels_1.h +++ b/Source/Devices/Neuropixels_1.h @@ -26,269 +26,272 @@ #include "../NeuropixComponents.h" #include "PortController.h" -enum class NeuropixelsRegisters : uint32_t +namespace OnixSourcePlugin { - OP_MODE = 0x00, - REC_MOD = 0x01, - CAL_MOD = 0x02, - STATUS = 0X08, - SYNC = 0X09 -}; - -enum class CalMode : uint32_t -{ - CAL_OFF = 0, - OSC_ACTIVE = 1 << 4, // 0 = external osc inactive, 1 = activate the external calibration oscillator - ADC_CAL = 1 << 5, // Enable ADC calibration - CH_CAL = 1 << 6, // Enable channel gain calibration - PIX_CAL = 1 << 7, // Enable pixel + channel gain calibration - - // Useful combinations - OSC_ACTIVE_AND_ADC_CAL = OSC_ACTIVE | ADC_CAL, - OSC_ACTIVE_AND_CH_CAL = OSC_ACTIVE | CH_CAL, - OSC_ACTIVE_AND_PIX_CAL = OSC_ACTIVE | PIX_CAL, -}; - -enum class OpMode : uint32_t -{ - TEST = 1 << 3, // Enable Test mode - DIG_TEST = 1 << 4, // Enable Digital Test mode - CALIBRATE = 1 << 5, // Enable calibration mode - RECORD = 1 << 6, // Enable recording mode - POWER_DOWN = 1 << 7, // Enable power down mode -}; - -enum class RecMod : uint32_t -{ - DIG_AND_CH_RESET = 0, - RESET_ALL = 1 << 5, // 1 = Set analog SR chains to default values - DIG_NRESET = 1 << 6, // 0 = Reset the MUX, ADC, and PSB counter, 1 = Disable reset - CH_NRESET = 1 << 7, // 0 = Reset channel pseudo-registers, 1 = Disable reset - - // Useful combinations - SR_RESET = RESET_ALL | CH_NRESET | DIG_NRESET, - DIG_RESET = CH_NRESET, // Yes, this is actually correct - CH_RESET = DIG_NRESET, // Yes, this is actually correct - ACTIVE = DIG_NRESET | CH_NRESET -}; - -enum class NeuropixelsV1Reference : unsigned char -{ - External = 0b001, - Tip = 0b010 -}; - -enum class NeuropixelsGain : unsigned char -{ - Gain50 = 0b000, - Gain125 = 0b001, - Gain250 = 0b010, - Gain500 = 0b011, - Gain1000 = 0b100, - Gain1500 = 0b101, - Gain2000 = 0b110, - Gain3000 = 0b111 -}; - -enum class ShiftRegisters : uint32_t -{ - SR_CHAIN1 = 0X0E, - SR_CHAIN3 = 0X0C, - SR_CHAIN2 = 0X0D, - SR_LENGTH2 = 0X0F, - SR_LENGTH1 = 0X10, - SOFT_RESET = 0X11 -}; - -// ADC number to frame index mapping -static const int adcToFrameIndex[] = { - 0, 7 , 14, 21, 28, - 1, 8 , 15, 22, 29, - 2, 9 , 16, 23, 30, - 3, 10, 17, 24, 31, - 4, 11, 18, 25, 32, - 5, 12, 19, 26, 33, - 6, 13 -}; - -// ADC to muxed channel mapping -static const int adcToChannel[] = { - 0, 1, 24, 25, 48, 49, 72, 73, 96, 97, - 120, 121, 144, 145, 168, 169, 192, 193, - 216, 217, 240, 241, 264, 265, 288, 289, - 312, 313, 336, 337, 360, 361 -}; - -struct NeuropixelsV1Adc -{ -public: - const int compP; - const int compN; - const int slope; - const int coarse; - const int fine; - const int cfix; - const int offset; - const int threshold; - - NeuropixelsV1Adc(int compP_ = 16, int compN_ = 16, int slope_ = 0, int coarse_ = 0, int fine_ = 0, int cfix_ = 0, int offset_ = 0, int threshold_ = 512) - : compP(compP_), compN(compN_), slope(slope_), coarse(coarse_), fine(fine_), cfix(cfix_), offset(offset_), threshold(threshold_) + enum class NeuropixelsRegisters : uint32_t { - } -}; - -/** - - Configures and streams data from a Neuropixels 1.0f device + OP_MODE = 0x00, + REC_MOD = 0x01, + CAL_MOD = 0x02, + STATUS = 0X08, + SYNC = 0X09 + }; + + enum class CalMode : uint32_t + { + CAL_OFF = 0, + OSC_ACTIVE = 1 << 4, // 0 = external osc inactive, 1 = activate the external calibration oscillator + ADC_CAL = 1 << 5, // Enable ADC calibration + CH_CAL = 1 << 6, // Enable channel gain calibration + PIX_CAL = 1 << 7, // Enable pixel + channel gain calibration + + // Useful combinations + OSC_ACTIVE_AND_ADC_CAL = OSC_ACTIVE | ADC_CAL, + OSC_ACTIVE_AND_CH_CAL = OSC_ACTIVE | CH_CAL, + OSC_ACTIVE_AND_PIX_CAL = OSC_ACTIVE | PIX_CAL, + }; + + enum class OpMode : uint32_t + { + TEST = 1 << 3, // Enable Test mode + DIG_TEST = 1 << 4, // Enable Digital Test mode + CALIBRATE = 1 << 5, // Enable calibration mode + RECORD = 1 << 6, // Enable recording mode + POWER_DOWN = 1 << 7, // Enable power down mode + }; + + enum class RecMod : uint32_t + { + DIG_AND_CH_RESET = 0, + RESET_ALL = 1 << 5, // 1 = Set analog SR chains to default values + DIG_NRESET = 1 << 6, // 0 = Reset the MUX, ADC, and PSB counter, 1 = Disable reset + CH_NRESET = 1 << 7, // 0 = Reset channel pseudo-registers, 1 = Disable reset + + // Useful combinations + SR_RESET = RESET_ALL | CH_NRESET | DIG_NRESET, + DIG_RESET = CH_NRESET, // Yes, this is actually correct + CH_RESET = DIG_NRESET, // Yes, this is actually correct + ACTIVE = DIG_NRESET | CH_NRESET + }; + + enum class NeuropixelsV1Reference : unsigned char + { + External = 0b001, + Tip = 0b010 + }; -*/ -class Neuropixels_1 : public INeuropixel, - public OnixDevice, - public I2CRegisterContext -{ -public: - /** Constructor */ - Neuropixels_1(String name, const oni_dev_idx_t, std::shared_ptr); + enum class NeuropixelsGain : unsigned char + { + Gain50 = 0b000, + Gain125 = 0b001, + Gain250 = 0b010, + Gain500 = 0b011, + Gain1000 = 0b100, + Gain1500 = 0b101, + Gain2000 = 0b110, + Gain3000 = 0b111 + }; + + enum class ShiftRegisters : uint32_t + { + SR_CHAIN1 = 0X0E, + SR_CHAIN3 = 0X0C, + SR_CHAIN2 = 0X0D, + SR_LENGTH2 = 0X0F, + SR_LENGTH1 = 0X10, + SOFT_RESET = 0X11 + }; + + // ADC number to frame index mapping + static const int adcToFrameIndex[] = { + 0, 7 , 14, 21, 28, + 1, 8 , 15, 22, 29, + 2, 9 , 16, 23, 30, + 3, 10, 17, 24, 31, + 4, 11, 18, 25, 32, + 5, 12, 19, 26, 33, + 6, 13 + }; + + // ADC to muxed channel mapping + static const int adcToChannel[] = { + 0, 1, 24, 25, 48, 49, 72, 73, 96, 97, + 120, 121, 144, 145, 168, 169, 192, 193, + 216, 217, 240, 241, 264, 265, 288, 289, + 312, 313, 336, 337, 360, 361 + }; + + struct NeuropixelsV1Adc + { + public: + const int compP; + const int compN; + const int slope; + const int coarse; + const int fine; + const int cfix; + const int offset; + const int threshold; + + NeuropixelsV1Adc(int compP_ = 16, int compN_ = 16, int slope_ = 0, int coarse_ = 0, int fine_ = 0, int cfix_ = 0, int offset_ = 0, int threshold_ = 512) + : compP(compP_), compN(compN_), slope(slope_), coarse(coarse_), fine(fine_), cfix(cfix_), offset(offset_), threshold(threshold_) + { + } + }; + + /** + + Configures and streams data from a Neuropixels 1.0f device + + */ + class Neuropixels_1 : public INeuropixel, + public OnixDevice, + public I2CRegisterContext + { + public: + /** Constructor */ + Neuropixels_1(String name, const oni_dev_idx_t, std::shared_ptr); - /** Configures the device so that it is ready to stream with default settings */ - int configureDevice() override; + /** Configures the device so that it is ready to stream with default settings */ + int configureDevice() override; - /** Update the settings of the device by writing to hardware */ - bool updateSettings() override; + /** Update the settings of the device by writing to hardware */ + bool updateSettings() override; - /** Starts probe data streaming */ - void startAcquisition() override; + /** Starts probe data streaming */ + void startAcquisition() override; - /** Stops probe data streaming*/ - void stopAcquisition() override; + /** Stops probe data streaming*/ + void stopAcquisition() override; - /** Given the sourceBuffers from OnixSource, add all streams for the current device to the array */ - void addSourceBuffers(OwnedArray& sourceBuffers) override; + /** Given the sourceBuffers from OnixSource, add all streams for the current device to the array */ + void addSourceBuffers(OwnedArray& sourceBuffers) override; - void addFrame(oni_frame_t*) override; + void addFrame(oni_frame_t*) override; - void processFrames() override; + void processFrames() override; - NeuropixelsGain getGainEnum(int index); + NeuropixelsGain getGainEnum(int index); - int getGainValue(NeuropixelsGain); + int getGainValue(NeuropixelsGain); - NeuropixelsV1Reference getReference(int index); + NeuropixelsV1Reference getReference(int index); - static const int shankConfigurationBitCount = 968; - static const int BaseConfigurationBitCount = 2448; + static const int shankConfigurationBitCount = 968; + static const int BaseConfigurationBitCount = 2448; - using ShankBitset = std::bitset; - using CongigBitsArray = std::array, 2>; + using ShankBitset = std::bitset; + using CongigBitsArray = std::array, 2>; - String adcCalibrationFilePath; - String gainCalibrationFilePath; + String adcCalibrationFilePath; + String gainCalibrationFilePath; - bool getCorrectOffset() const { return correctOffset; } + bool getCorrectOffset() const { return correctOffset; } - void setCorrectOffset(bool value) { correctOffset = value; } + void setCorrectOffset(bool value) { correctOffset = value; } - ShankBitset static makeShankBits(NeuropixelsV1Reference reference, std::array channelMap); + ShankBitset static makeShankBits(NeuropixelsV1Reference reference, std::array channelMap); - CongigBitsArray static makeConfigBits(NeuropixelsV1Reference reference, NeuropixelsGain spikeAmplifierGain, NeuropixelsGain lfpAmplifierGain, bool spikeFilterEnabled, Array adcs); + CongigBitsArray static makeConfigBits(NeuropixelsV1Reference reference, NeuropixelsGain spikeAmplifierGain, NeuropixelsGain lfpAmplifierGain, bool spikeFilterEnabled, Array adcs); - void writeShiftRegisters(ShankBitset shankBits, CongigBitsArray configBits, Array adcs, double lfpGainCorrection, double apGainCorrection); + void writeShiftRegisters(ShankBitset shankBits, CongigBitsArray configBits, Array adcs, double lfpGainCorrection, double apGainCorrection); - // INeuropixels methods - void setSettings(ProbeSettings* settings_, int index = 0) override; + // INeuropixels methods + void setSettings(ProbeSettings* settings_, int index = 0) override; - void defineMetadata(ProbeSettings* settings) override; + void defineMetadata(ProbeSettings* settings) override; - uint64_t getProbeSerialNumber(int index = 0) override { return probeNumber; } + uint64_t getProbeSerialNumber(int index = 0) override { return probeNumber; } - /** Select a preset electrode configuration */ - std::vector selectElectrodeConfiguration(String config) override; + /** Select a preset electrode configuration */ + std::vector selectElectrodeConfiguration(String config) override; -private: + private: - DataBuffer* apBuffer; - DataBuffer* lfpBuffer; + DataBuffer* apBuffer; + DataBuffer* lfpBuffer; - const uint32_t ENABLE = 0x8000; + const uint32_t ENABLE = 0x8000; - static const int superFramesPerUltraFrame = 12; - static const int framesPerSuperFrame = 13; - static const int framesPerUltraFrame = superFramesPerUltraFrame * framesPerSuperFrame; - static const int numUltraFrames = 12; - static const int dataOffset = 1; + static const int superFramesPerUltraFrame = 12; + static const int framesPerSuperFrame = 13; + static const int framesPerUltraFrame = superFramesPerUltraFrame * framesPerSuperFrame; + static const int numUltraFrames = 12; + static const int dataOffset = 1; - static const int secondsToSettle = 5; - static const int samplesToAverage = 100; + static const int secondsToSettle = 5; + static const int samplesToAverage = 100; - static const uint32_t numLfpSamples = 384 * numUltraFrames; - static const uint32_t numApSamples = 384 * numUltraFrames * superFramesPerUltraFrame; + static const uint32_t numLfpSamples = 384 * numUltraFrames; + static const uint32_t numApSamples = 384 * numUltraFrames * superFramesPerUltraFrame; - static constexpr float lfpSampleRate = 2500.0f; - static constexpr float apSampleRate = 30000.0f; + static constexpr float lfpSampleRate = 2500.0f; + static constexpr float apSampleRate = 30000.0f; - bool lfpOffsetCalculated = false; - bool apOffsetCalculated = false; + bool lfpOffsetCalculated = false; + bool apOffsetCalculated = false; - bool correctOffset = true; + bool correctOffset = true; - std::array apOffsets; - std::array lfpOffsets; + std::array apOffsets; + std::array lfpOffsets; - std::vector> apOffsetValues; - std::vector> lfpOffsetValues; + std::vector> apOffsetValues; + std::vector> lfpOffsetValues; - void updateLfpOffsets(std::array&, int64); - void updateApOffsets(std::array&, int64); + void updateLfpOffsets(std::array&, int64); + void updateApOffsets(std::array&, int64); - static const int ProbeI2CAddress = 0x70; + static const int ProbeI2CAddress = 0x70; - Array frameArray; + Array frameArray; - uint64_t probeNumber = 0; + uint64_t probeNumber = 0; - std::array lfpSamples; - std::array apSamples; + std::array lfpSamples; + std::array apSamples; - int64 apSampleNumbers[numUltraFrames * superFramesPerUltraFrame]; - double apTimestamps[numUltraFrames * superFramesPerUltraFrame]; - uint64 apEventCodes[numUltraFrames * superFramesPerUltraFrame]; + int64 apSampleNumbers[numUltraFrames * superFramesPerUltraFrame]; + double apTimestamps[numUltraFrames * superFramesPerUltraFrame]; + uint64 apEventCodes[numUltraFrames * superFramesPerUltraFrame]; - int64 lfpSampleNumbers[numUltraFrames]; - double lfpTimestamps[numUltraFrames]; - uint64 lfpEventCodes[numUltraFrames]; + int64 lfpSampleNumbers[numUltraFrames]; + double lfpTimestamps[numUltraFrames]; + uint64 lfpEventCodes[numUltraFrames]; - bool shouldAddToBuffer = false; - int superFrameCount = 0; - int ultraFrameCount = 0; + bool shouldAddToBuffer = false; + int superFrameCount = 0; + int ultraFrameCount = 0; - int apSampleNumber = 0; - int lfpSampleNumber = 0; + int apSampleNumber = 0; + int lfpSampleNumber = 0; - int apGain = 1000; - int lfpGain = 50; + int apGain = 1000; + int lfpGain = 50; - JUCE_LEAK_DETECTOR(Neuropixels_1); -}; + JUCE_LEAK_DETECTOR(Neuropixels_1); + }; -/* + /* - A thread that updates probe settings in the background and shows a progress bar + A thread that updates probe settings in the background and shows a progress bar -*/ -class BackgroundUpdaterWithProgressWindow : public ThreadWithProgressWindow -{ -public: - BackgroundUpdaterWithProgressWindow(Neuropixels_1* d); + */ + class BackgroundUpdaterWithProgressWindow : public ThreadWithProgressWindow + { + public: + BackgroundUpdaterWithProgressWindow(Neuropixels_1* d); - void run() override; + void run() override; - bool updateSettings(); + bool updateSettings(); -private: + private: - Neuropixels_1* device; + Neuropixels_1* device; - std::atomic result = false; + std::atomic result = false; - JUCE_LEAK_DETECTOR(BackgroundUpdaterWithProgressWindow); -}; + JUCE_LEAK_DETECTOR(BackgroundUpdaterWithProgressWindow); + }; +} diff --git a/Source/Devices/OutputClock.cpp b/Source/Devices/OutputClock.cpp index de56efa..2f4dead 100644 --- a/Source/Devices/OutputClock.cpp +++ b/Source/Devices/OutputClock.cpp @@ -22,6 +22,8 @@ #include "OutputClock.h" +using namespace OnixSourcePlugin; + OutputClock::OutputClock(String name, const oni_dev_idx_t deviceIdx_, std::shared_ptr oni_ctx) : OnixDevice(name, BREAKOUT_BOARD_NAME, OnixDeviceType::OUTPUTCLOCK, deviceIdx_, oni_ctx) { diff --git a/Source/Devices/OutputClock.h b/Source/Devices/OutputClock.h index 08a45a3..209eccb 100644 --- a/Source/Devices/OutputClock.h +++ b/Source/Devices/OutputClock.h @@ -24,73 +24,76 @@ #include "../OnixDevice.h" -enum class OutputClockRegisters : uint32_t +namespace OnixSourcePlugin { - NULL_REGISTER = 0, - CLOCK_GATE = 1, - HIGH_CYCLES = 2, - LOW_CYCLES = 3, - DELAY_CYCLES = 4, - GATE_RUN = 5, - BASE_FREQ_HZ = 6 -}; + enum class OutputClockRegisters : uint32_t + { + NULL_REGISTER = 0, + CLOCK_GATE = 1, + HIGH_CYCLES = 2, + LOW_CYCLES = 3, + DELAY_CYCLES = 4, + GATE_RUN = 5, + BASE_FREQ_HZ = 6 + }; -/* - Configures an OutputClock device on a Breakout Board -*/ -class OutputClock : public OnixDevice -{ -public: - OutputClock(String name, const oni_dev_idx_t, std::shared_ptr oni_ctx); + /* + Configures an OutputClock device on a Breakout Board + */ + class OutputClock : public OnixDevice + { + public: + OutputClock(String name, const oni_dev_idx_t, std::shared_ptr oni_ctx); - /** Device is always enabled */ - int configureDevice() override { setEnabled(true); return 0; }; + /** Device is always enabled */ + int configureDevice() override { setEnabled(true); return 0; }; - /** Update the settings of the device */ - bool updateSettings() override; + /** Update the settings of the device */ + bool updateSettings() override; - /** Starts probe data streaming */ - void startAcquisition() override {}; + /** Starts probe data streaming */ + void startAcquisition() override {}; - /** Stops probe data streaming*/ - void stopAcquisition() override {}; + /** Stops probe data streaming*/ + void stopAcquisition() override {}; - /** Given the sourceBuffers from OnixSource, add all streams for the current device to the array */ - void addSourceBuffers(OwnedArray& sourceBuffers) override {}; + /** Given the sourceBuffers from OnixSource, add all streams for the current device to the array */ + void addSourceBuffers(OwnedArray& sourceBuffers) override {}; - void addFrame(oni_frame_t* frame) override { oni_destroy_frame(frame); } + void addFrame(oni_frame_t* frame) override { oni_destroy_frame(frame); } - void processFrames() override {}; + void processFrames() override {}; - double getFrequencyHz() const { return frequencyHz; } + double getFrequencyHz() const { return frequencyHz; } - void setFrequencyHz(double frequency) { frequencyHz = frequency; } + void setFrequencyHz(double frequency) { frequencyHz = frequency; } - int32_t getDutyCycle() const { return dutyCycle; } + int32_t getDutyCycle() const { return dutyCycle; } - void setDutyCycle(int32_t dutyCycle_) { dutyCycle = dutyCycle_; } + void setDutyCycle(int32_t dutyCycle_) { dutyCycle = dutyCycle_; } - int32_t getDelay() const { return delay; } + int32_t getDelay() const { return delay; } - void setDelay(int32_t delay_) { delay = delay_; } + void setDelay(int32_t delay_) { delay = delay_; } - bool getGateRun() const { return gateRun; } + bool getGateRun() const { return gateRun; } - void setGateRun(bool gate, bool writeToRegister = false) - { - gateRun = gate; - if (writeToRegister) writeGateRunRegister(); - } + void setGateRun(bool gate, bool writeToRegister = false) + { + gateRun = gate; + if (writeToRegister) writeGateRunRegister(); + } -private: + private: - double frequencyHz = 1e6; - int32_t dutyCycle = 50; - int32_t delay = 0; + double frequencyHz = 1e6; + int32_t dutyCycle = 50; + int32_t delay = 0; - bool gateRun = true; + bool gateRun = true; - void writeGateRunRegister() { deviceContext->writeRegister(deviceIdx, (oni_reg_addr_t)OutputClockRegisters::GATE_RUN, gateRun ? 1 : 0); } + void writeGateRunRegister() { deviceContext->writeRegister(deviceIdx, (oni_reg_addr_t)OutputClockRegisters::GATE_RUN, gateRun ? 1 : 0); } - JUCE_LEAK_DETECTOR(OutputClock); -}; + JUCE_LEAK_DETECTOR(OutputClock); + }; +} diff --git a/Source/Devices/PolledBno055.cpp b/Source/Devices/PolledBno055.cpp index ff192f7..799b261 100644 --- a/Source/Devices/PolledBno055.cpp +++ b/Source/Devices/PolledBno055.cpp @@ -22,13 +22,15 @@ #include "PolledBno055.h" +using namespace OnixSourcePlugin; + PolledBno055::PolledBno055(String name, String headstageName, const oni_dev_idx_t deviceIdx_, std::shared_ptr ctx) : OnixDevice(name, headstageName, OnixDeviceType::POLLEDBNO, deviceIdx_, ctx), I2CRegisterContext(Bno055Address, deviceIdx_, ctx) { auto streamIdentifier = getStreamIdentifier(); - String port = PortController::getPortName(PortController::getPortFromIndex(deviceIdx)); + String port = getPortNameFromIndex(deviceIdx); StreamInfo eulerAngleStream = StreamInfo( OnixDevice::createStreamName({ port, getHeadstageName(), getName(), "Euler" }), "Bosch Bno055 9-axis inertial measurement unit (IMU) Euler angle", diff --git a/Source/Devices/PolledBno055.h b/Source/Devices/PolledBno055.h index dd2a2fe..f2e10af 100644 --- a/Source/Devices/PolledBno055.h +++ b/Source/Devices/PolledBno055.h @@ -29,38 +29,40 @@ #include -class PolledBno055 : public OnixDevice, - public I2CRegisterContext, - public HighResolutionTimer +namespace OnixSourcePlugin { -public: + class PolledBno055 : public OnixDevice, + public I2CRegisterContext, + public HighResolutionTimer + { + public: - /** Constructor */ - PolledBno055(String name, String headstageName, const oni_dev_idx_t, std::shared_ptr ctx); + /** Constructor */ + PolledBno055(String name, String headstageName, const oni_dev_idx_t, std::shared_ptr ctx); - ~PolledBno055() - { - stopTimer(); - } + ~PolledBno055() + { + stopTimer(); + } - int configureDevice() override; + int configureDevice() override; - /** Update the settings of the device */ - bool updateSettings() override; + /** Update the settings of the device */ + bool updateSettings() override; - /** Starts probe data streaming */ - void startAcquisition() override; + /** Starts probe data streaming */ + void startAcquisition() override; - /** Stops probe data streaming*/ - void stopAcquisition() override; + /** Stops probe data streaming*/ + void stopAcquisition() override; - void addFrame(oni_frame_t*) override; + void addFrame(oni_frame_t*) override; - void processFrames() override {}; + void processFrames() override {}; - void addSourceBuffers(OwnedArray& sourceBuffers) override; + void addSourceBuffers(OwnedArray& sourceBuffers) override; - void hiResTimerCallback() override; + void hiResTimerCallback() override; enum class Bno055AxisMap : uint32_t { @@ -101,39 +103,39 @@ class PolledBno055 : public OnixDevice, std::unique_ptr deserializer; - enum class PolledBno055Registers : int32_t - { - EulerAngle = 0x1, // Specifies that the Euler angles will be polled. - Quaternion = 0x2, // Specifies that the quaternion will be polled. - Acceleration = 0x4, // Specifies that the linear acceleration will be polled. - Gravity = 0x8, // Specifies that the gravity vector will be polled. - Temperature = 0x10, // Specifies that the temperature measurement will be polled. - Calibration = 0x20, // Specifies that the sensor calibration status will be polled. - All = EulerAngle | Quaternion | Acceleration | Gravity | Temperature | Calibration, // Specifies that all sensor measurements and calibration status will be polled. - }; - - Bno055AxisMap axisMap = Bno055AxisMap::XYZ; - Bno055AxisSign axisSign = Bno055AxisSign::Default; + enum class PolledBno055Registers : int32_t + { + EulerAngle = 0x1, // Specifies that the Euler angles will be polled. + Quaternion = 0x2, // Specifies that the quaternion will be polled. + Acceleration = 0x4, // Specifies that the linear acceleration will be polled. + Gravity = 0x8, // Specifies that the gravity vector will be polled. + Temperature = 0x10, // Specifies that the temperature measurement will be polled. + Calibration = 0x20, // Specifies that the sensor calibration status will be polled. + All = EulerAngle | Quaternion | Acceleration | Gravity | Temperature | Calibration, // Specifies that all sensor measurements and calibration status will be polled. + }; - static const int numberOfChannels = 3 + 3 + 4 + 3 + 1 + 1; - static constexpr double sampleRate = 30.0; + Bno055AxisMap axisMap = Bno055AxisMap::XYZ; + Bno055AxisSign axisSign = Bno055AxisSign::Default; - static const int timerIntervalInMilliseconds = (int)(1e3 * (1 / sampleRate)); + static const int numberOfChannels = 3 + 3 + 4 + 3 + 1 + 1; + static constexpr double sampleRate = 30.0; - static const int numFrames = 2; + static const int timerIntervalInMilliseconds = (int)(1e3 * (1 / sampleRate)); - std::array bnoSamples; + static const int numFrames = 2; - double bnoTimestamps[numFrames]; - int64 sampleNumbers[numFrames]; - uint64 eventCodes[numFrames]; + std::array bnoSamples; - unsigned short currentFrame = 0; - int sampleNumber = 0; + double bnoTimestamps[numFrames]; + int64 sampleNumbers[numFrames]; + uint64 eventCodes[numFrames]; - // Given the starting address (i.e., the LSB), read two bytes and convert to an int16_t - int16_t readInt16(uint32_t); + unsigned short currentFrame = 0; + int sampleNumber = 0; - JUCE_LEAK_DETECTOR(PolledBno055); -}; + // Given the starting address (i.e., the LSB), read two bytes and convert to an int16_t + int16_t readInt16(uint32_t); + JUCE_LEAK_DETECTOR(PolledBno055); + }; +} diff --git a/Source/Devices/PortController.cpp b/Source/Devices/PortController.cpp index 07133ac..7c334a7 100644 --- a/Source/Devices/PortController.cpp +++ b/Source/Devices/PortController.cpp @@ -22,8 +22,10 @@ #include "PortController.h" +using namespace OnixSourcePlugin; + PortController::PortController(PortName port_, std::shared_ptr ctx_) : - OnixDevice(getPortName(port_), BREAKOUT_BOARD_NAME, OnixDeviceType::PORT_CONTROL, (oni_dev_idx_t)port_, ctx_), + OnixDevice(OnixDevice::getPortName(port_), BREAKOUT_BOARD_NAME, OnixDeviceType::PORT_CONTROL, (oni_dev_idx_t)port_, ctx_), port(port_) { } @@ -96,21 +98,6 @@ DiscoveryParameters PortController::getHeadstageDiscoveryParameters(String heads return DiscoveryParameters(); } -String PortController::getPortName(int offset) -{ - switch (offset) - { - case 0: - return ""; - case HubAddressPortA: - return "Port A"; - case HubAddressPortB: - return "Port B"; - default: - return ""; - } -} - bool PortController::configureVoltage(double voltage) { if (voltage == defaultVoltage) @@ -180,37 +167,3 @@ bool PortController::checkLinkState() const else if ((linkState & LINKSTATE_SL) == 0) { LOGD("Unable to acquire communication lock."); return false; } else return true; } - -PortName PortController::getPortFromIndex(oni_dev_idx_t index) -{ - return index & (1 << 8) ? PortName::PortA : PortName::PortB; -} - -int PortController::getOffsetFromIndex(oni_dev_idx_t index) -{ - return index & 0b1100000000; -} - -Array PortController::getUniqueOffsetsFromIndices(std::vector indices) -{ - Array offsets; - - for (auto index : indices) - { - offsets.addIfNotAlreadyThere(getOffsetFromIndex(index)); - } - - return offsets; -} - -Array PortController::getUniquePortsFromIndices(std::vector indices) -{ - Array ports; - - for (auto index : indices) - { - ports.addIfNotAlreadyThere(PortController::getPortFromIndex(index)); - } - - return ports; -} diff --git a/Source/Devices/PortController.h b/Source/Devices/PortController.h index 211a748..d03d5d5 100644 --- a/Source/Devices/PortController.h +++ b/Source/Devices/PortController.h @@ -30,173 +30,159 @@ using namespace std::this_thread; -enum class PortControllerRegister : uint32_t +namespace OnixSourcePlugin { - ENABLE = 0, - GPOSTATE = 1, - DESPWR = 2, - PORTVOLTAGE = 3, - SAVEVOLTAGE = 4, - LINKSTATE = 5 -}; - -enum class PortStatusCode : uint32_t -{ - SerdesLock = 0x0001, - SerdesParityPass = 0x0002, - CrcError = 0x0100, - TooManyDevices = 0x0200, - InitializationError = 0x0400, - BadPacketFormat = 0x0800, - InitializationCrcError = 0x1000, -}; - -class DiscoveryParameters -{ -public: - double minVoltage = 0.0; - double maxVoltage = 0.0; - double voltageOffset = 0.0; - double voltageIncrement = 0.0; - - DiscoveryParameters() {}; - - DiscoveryParameters(double minVoltage_, double maxVoltage_, double voltageOffset_, double voltageIncrement_) + enum class PortControllerRegister : uint32_t { - minVoltage = minVoltage_; - maxVoltage = maxVoltage_; - voltageOffset = voltageOffset_; - voltageIncrement = voltageIncrement_; - } - - bool operator==(const DiscoveryParameters& rhs) const + ENABLE = 0, + GPOSTATE = 1, + DESPWR = 2, + PORTVOLTAGE = 3, + SAVEVOLTAGE = 4, + LINKSTATE = 5 + }; + + enum class PortStatusCode : uint32_t { - return rhs.minVoltage == minVoltage && rhs.maxVoltage == maxVoltage && rhs.voltageOffset == voltageOffset && rhs.voltageIncrement == voltageIncrement; - } -}; - -class PortController : public OnixDevice -{ -public: - PortController(PortName port_, std::shared_ptr ctx_); - - int configureDevice() override; - - bool updateSettings() override { return true; } - - void startAcquisition() override; - - void stopAcquisition() override; - - void addFrame(oni_frame_t*) override; + SerdesLock = 0x0001, + SerdesParityPass = 0x0002, + CrcError = 0x0100, + TooManyDevices = 0x0200, + InitializationError = 0x0400, + BadPacketFormat = 0x0800, + InitializationCrcError = 0x1000, + }; + + class DiscoveryParameters + { + public: + double minVoltage = 0.0; + double maxVoltage = 0.0; + double voltageOffset = 0.0; + double voltageIncrement = 0.0; - void processFrames() override; + DiscoveryParameters() {}; - void addSourceBuffers(OwnedArray& sourceBuffers) override {}; + DiscoveryParameters(double minVoltage_, double maxVoltage_, double voltageOffset_, double voltageIncrement_) + { + minVoltage = minVoltage_; + maxVoltage = maxVoltage_; + voltageOffset = voltageOffset_; + voltageIncrement = voltageIncrement_; + } - void updateDiscoveryParameters(DiscoveryParameters parameters); + bool operator==(const DiscoveryParameters& rhs) const + { + return rhs.minVoltage == minVoltage && rhs.maxVoltage == maxVoltage && rhs.voltageOffset == voltageOffset && rhs.voltageIncrement == voltageIncrement; + } + }; - bool configureVoltage(double voltage = defaultVoltage); + class PortController : public OnixDevice + { + public: + PortController(PortName port_, std::shared_ptr ctx_); - /** Sets the voltage to the given value, after setting the voltage to zero */ - void setVoltage(double voltage); + int configureDevice() override; - /** Overrides the voltage setting and directly sets it to the given voltage */ - void setVoltageOverride(double voltage, bool waitToSettle = true); + bool updateSettings() override { return true; } - bool checkLinkState() const; + void startAcquisition() override; - static DiscoveryParameters getHeadstageDiscoveryParameters(String headstage); + void stopAcquisition() override; - static int getPortOffset(PortName port) { return (uint32_t)port << 8; } + void addFrame(oni_frame_t*) override; - static String getPortName(int offset); + void processFrames() override; - static String getPortName(PortName port) { return port == PortName::PortA ? "Port A" : "Port B"; } + void addSourceBuffers(OwnedArray& sourceBuffers) override {}; - String getPortName() const { return getPortName(port); } + void updateDiscoveryParameters(DiscoveryParameters parameters); - static PortName getPortFromIndex(oni_dev_idx_t index); + bool configureVoltage(double voltage = defaultVoltage); - static int getOffsetFromIndex(oni_dev_idx_t index); + /** Sets the voltage to the given value, after setting the voltage to zero */ + void setVoltage(double voltage); - static Array getUniqueOffsetsFromIndices(std::vector indices); + /** Overrides the voltage setting and directly sets it to the given voltage */ + void setVoltageOverride(double voltage, bool waitToSettle = true); - static Array getUniquePortsFromIndices(std::vector); + bool checkLinkState() const; - /** Check if the port status changed and there is an error reported */ - bool getErrorFlag() { return errorFlag; } + static DiscoveryParameters getHeadstageDiscoveryParameters(String headstage); - double getLastVoltageSet() const { return lastVoltageSet; } + String getPortName() const { return OnixDevice::getPortName(port); } - static constexpr int HubAddressPortA = 256; - static constexpr int HubAddressPortB = 512; + /** Check if the port status changed and there is an error reported */ + bool getErrorFlag() { return errorFlag; } -private: - Array frameArray; + double getLastVoltageSet() const { return lastVoltageSet; } - const PortName port; + private: + Array frameArray; - static constexpr double defaultVoltage = -1.0; + const PortName port; - double lastVoltageSet = 0.0; + static constexpr double defaultVoltage = -1.0; - static constexpr uint32_t LINKSTATE_PP = 0x2; // parity check pass bit - static constexpr uint32_t LINKSTATE_SL = 0x1; // SERDES lock bit + double lastVoltageSet = 0.0; - DiscoveryParameters discoveryParameters; + static constexpr uint32_t LINKSTATE_PP = 0x2; // parity check pass bit + static constexpr uint32_t LINKSTATE_SL = 0x1; // SERDES lock bit - std::atomic errorFlag = false; + DiscoveryParameters discoveryParameters; - JUCE_LEAK_DETECTOR(PortController); -}; + std::atomic errorFlag = false; -class ConfigureVoltageWithProgressBar : public ThreadWithProgressWindow -{ -public: - ConfigureVoltageWithProgressBar(DiscoveryParameters params, PortController* port) - : ThreadWithProgressWindow("Configuring voltage on " + port->getPortName(), true, false) - { - m_params = params; - m_port = port; - } + JUCE_LEAK_DETECTOR(PortController); + }; - void run() override + class ConfigureVoltageWithProgressBar : public ThreadWithProgressWindow { - double voltage, progress = 0.0; - - double increment = m_params.voltageIncrement / (m_params.maxVoltage - m_params.minVoltage); + public: + ConfigureVoltageWithProgressBar(DiscoveryParameters params, PortController* port) + : ThreadWithProgressWindow("Configuring voltage on " + port->getPortName(), true, false) + { + m_params = params; + m_port = port; + } - for (voltage = m_params.minVoltage; voltage <= m_params.maxVoltage; voltage += m_params.voltageIncrement) + void run() override { - progress += increment; - setProgress(progress); + double voltage, progress = 0.0; - m_port->setVoltage(voltage); + double increment = m_params.voltageIncrement / (m_params.maxVoltage - m_params.minVoltage); - if (m_port->checkLinkState()) + for (voltage = m_params.minVoltage; voltage <= m_params.maxVoltage; voltage += m_params.voltageIncrement) { - setProgress(0.95); - m_port->setVoltage(voltage + m_params.voltageOffset); - result = m_port->checkLinkState();; - setProgress(1.0); - return; + progress += increment; + setProgress(progress); + + m_port->setVoltage(voltage); + + if (m_port->checkLinkState()) + { + setProgress(0.95); + m_port->setVoltage(voltage + m_params.voltageOffset); + result = m_port->checkLinkState();; + setProgress(1.0); + return; + } } - } - result = false; - return; - } + result = false; + return; + } - bool getResult() const { return result; } + bool getResult() const { return result; } -private: + private: - DiscoveryParameters m_params; + DiscoveryParameters m_params; - PortController* m_port; + PortController* m_port; - bool result = false; + bool result = false; - JUCE_LEAK_DETECTOR(ConfigureVoltageWithProgressBar); -}; + JUCE_LEAK_DETECTOR(ConfigureVoltageWithProgressBar); + }; +} diff --git a/Source/Formats/ProbeInterface.h b/Source/Formats/ProbeInterface.h index 635b34b..a22d4cb 100644 --- a/Source/Formats/ProbeInterface.h +++ b/Source/Formats/ProbeInterface.h @@ -24,149 +24,152 @@ #include "../NeuropixComponents.h" -class ProbeInterfaceJson +namespace OnixSourcePlugin { -public: - static bool writeProbeSettingsToJson(File& file, ProbeSettings<0, 0>* settings) + class ProbeInterfaceJson { - DynamicObject output; - - output.setProperty(Identifier("specification"), - var("probeinterface")); - output.setProperty(Identifier("version"), - var("0.2.23")); - - Array contact_positions; - Array shank_ids; - Array device_channel_indices; - Array contact_plane_axes; - Array contact_shapes; - Array contact_shape_params; - - Array ax1 = { 1.0f, 0.0f }; - Array ax2 = { 0.0f, 1.0f }; - Array contact_plane_axis = { ax1, ax2 }; - - for (int elec = 0; elec < settings->electrodeMetadata.size(); elec++) + public: + static bool writeProbeSettingsToJson(File& file, ProbeSettings<0, 0>* settings) { - ElectrodeMetadata& em = settings->electrodeMetadata[elec]; - int channelIndex = settings->selectedElectrode[elec]; - // TODO: Fix this section - //int channel = -1; - //if (channelIndex > -1) - // channel = settings->selectedChannel[channelIndex]; - - Array contact_position; - contact_position.add(em.xpos + 250 * em.shank); - contact_position.add(em.ypos); - - DynamicObject::Ptr contact_shape_param = new DynamicObject; - contact_shape_param->setProperty(Identifier("width"), settings->electrodeMetadata[elec].site_width); - - contact_positions.add(contact_position); - shank_ids.add(String(em.shank)); - device_channel_indices.add(0); - contact_plane_axes.add(contact_plane_axis); - contact_shapes.add("square"); - contact_shape_params.add(contact_shape_param.get()); - } - - DynamicObject::Ptr probe = new DynamicObject(); - DynamicObject::Ptr annotations = new DynamicObject(); - //annotations->setProperty(Identifier("name"), settings->probe->name); - annotations->setProperty(Identifier("manufacturer"), "imec"); + DynamicObject output; - probe->setProperty(Identifier("ndim"), 2); - probe->setProperty(Identifier("si_units"), "um"); - probe->setProperty(Identifier("annotations"), var(annotations)); - probe->setProperty(Identifier("contact_positions"), contact_positions); - probe->setProperty(Identifier("contact_plane_axes"), contact_plane_axes); - probe->setProperty(Identifier("contact_shapes"), contact_shapes); - probe->setProperty(Identifier("contact_shape_params"), contact_shape_params); - probe->setProperty(Identifier("device_channel_indices"), device_channel_indices); - probe->setProperty(Identifier("shank_ids"), shank_ids); + output.setProperty(Identifier("specification"), + var("probeinterface")); + output.setProperty(Identifier("version"), + var("0.2.23")); - Array probes; - probes.add(probe.get()); + Array contact_positions; + Array shank_ids; + Array device_channel_indices; + Array contact_plane_axes; + Array contact_shapes; + Array contact_shape_params; - output.setProperty(Identifier("probes"), probes); + Array ax1 = { 1.0f, 0.0f }; + Array ax2 = { 0.0f, 1.0f }; + Array contact_plane_axis = { ax1, ax2 }; - if (file.exists()) - file.deleteFile(); + for (int elec = 0; elec < settings->electrodeMetadata.size(); elec++) + { + ElectrodeMetadata& em = settings->electrodeMetadata[elec]; + int channelIndex = settings->selectedElectrode[elec]; + // TODO: Fix this section + //int channel = -1; + //if (channelIndex > -1) + // channel = settings->selectedChannel[channelIndex]; + + Array contact_position; + contact_position.add(em.xpos + 250 * em.shank); + contact_position.add(em.ypos); + + DynamicObject::Ptr contact_shape_param = new DynamicObject; + contact_shape_param->setProperty(Identifier("width"), settings->electrodeMetadata[elec].site_width); + + contact_positions.add(contact_position); + shank_ids.add(String(em.shank)); + device_channel_indices.add(0); + contact_plane_axes.add(contact_plane_axis); + contact_shapes.add("square"); + contact_shape_params.add(contact_shape_param.get()); + } - FileOutputStream f(file); + DynamicObject::Ptr probe = new DynamicObject(); + DynamicObject::Ptr annotations = new DynamicObject(); + //annotations->setProperty(Identifier("name"), settings->probe->name); + annotations->setProperty(Identifier("manufacturer"), "imec"); - JSON::FormatOptions options; + probe->setProperty(Identifier("ndim"), 2); + probe->setProperty(Identifier("si_units"), "um"); + probe->setProperty(Identifier("annotations"), var(annotations)); + probe->setProperty(Identifier("contact_positions"), contact_positions); + probe->setProperty(Identifier("contact_plane_axes"), contact_plane_axes); + probe->setProperty(Identifier("contact_shapes"), contact_shapes); + probe->setProperty(Identifier("contact_shape_params"), contact_shape_params); + probe->setProperty(Identifier("device_channel_indices"), device_channel_indices); + probe->setProperty(Identifier("shank_ids"), shank_ids); - options = options.withMaxDecimalPlaces(4); - options = options.withSpacing(JSON::Spacing::multiLine); + Array probes; + probes.add(probe.get()); - output.writeAsJSON(f, options); + output.setProperty(Identifier("probes"), probes); - return true; - } + if (file.exists()) + file.deleteFile(); - static bool readProbeSettingsFromJson(File& file, ProbeSettings<0,0>* settings) - { - var result; + FileOutputStream f(file); - static Result r = JSON::parse(file.loadFileAsString(), result); + JSON::FormatOptions options; - DynamicObject::Ptr obj = result.getDynamicObject(); + options = options.withMaxDecimalPlaces(4); + options = options.withSpacing(JSON::Spacing::multiLine); - // check that specification == 'probeinterface' - if (obj->hasProperty(Identifier("specification"))) - { - String specification = obj->getProperty(Identifier("specification")).toString(); + output.writeAsJSON(f, options); - if (specification.compare("probeinterface") != 0) - return false; + return true; } - if (obj->hasProperty(Identifier("probes"))) + static bool readProbeSettingsFromJson(File& file, ProbeSettings<0, 0>* settings) { - Array* probes = obj->getProperty(Identifier("probes")).getArray(); + var result; - // check that this file contains only one probe - if (probes->size() != 1) - return false; + static Result r = JSON::parse(file.loadFileAsString(), result); - DynamicObject::Ptr probe = probes->getReference(0).getDynamicObject(); + DynamicObject::Ptr obj = result.getDynamicObject(); - if (probe->hasProperty(Identifier("device_channel_indices"))) + // check that specification == 'probeinterface' + if (obj->hasProperty(Identifier("specification"))) { - Array* device_channel_indices = probe->getProperty(Identifier("device_channel_indices")).getArray(); + String specification = obj->getProperty(Identifier("specification")).toString(); - for (int ch = 0; ch < device_channel_indices->size(); ch++) - { - int index = int(device_channel_indices->getReference(ch)); - } + if (specification.compare("probeinterface") != 0) + return false; } - if (probe->hasProperty(Identifier("shank_ids"))) + if (obj->hasProperty(Identifier("probes"))) { - Array* shank_ids = probe->getProperty(Identifier("shank_ids")).getArray(); + Array* probes = obj->getProperty(Identifier("probes")).getArray(); - for (int ch = 0; ch < shank_ids->size(); ch++) + // check that this file contains only one probe + if (probes->size() != 1) + return false; + + DynamicObject::Ptr probe = probes->getReference(0).getDynamicObject(); + + if (probe->hasProperty(Identifier("device_channel_indices"))) { - int shank_id = int(shank_ids->getReference(ch)); + Array* device_channel_indices = probe->getProperty(Identifier("device_channel_indices")).getArray(); + + for (int ch = 0; ch < device_channel_indices->size(); ch++) + { + int index = int(device_channel_indices->getReference(ch)); + } } - } - if (probe->hasProperty(Identifier("contact_positions"))) - { - Array* contact_positions = probe->getProperty(Identifier("contact_positions")).getArray(); + if (probe->hasProperty(Identifier("shank_ids"))) + { + Array* shank_ids = probe->getProperty(Identifier("shank_ids")).getArray(); - for (int ch = 0; ch < contact_positions->size(); ch++) + for (int ch = 0; ch < shank_ids->size(); ch++) + { + int shank_id = int(shank_ids->getReference(ch)); + } + } + + if (probe->hasProperty(Identifier("contact_positions"))) { - Array* contact_position = contact_positions->getReference(ch).getArray(); + Array* contact_positions = probe->getProperty(Identifier("contact_positions")).getArray(); + + for (int ch = 0; ch < contact_positions->size(); ch++) + { + Array* contact_position = contact_positions->getReference(ch).getArray(); - int xpos = int(contact_position->getReference(0)); - int ypos = int(contact_position->getReference(1)); + int xpos = int(contact_position->getReference(0)); + int ypos = int(contact_position->getReference(1)); + } } } - } - return true; - } -}; + return true; + } + }; +} diff --git a/Source/FrameReader.cpp b/Source/FrameReader.cpp index 52d324f..16500fd 100644 --- a/Source/FrameReader.cpp +++ b/Source/FrameReader.cpp @@ -22,6 +22,8 @@ #include "FrameReader.h" +using namespace OnixSourcePlugin; + FrameReader::FrameReader(OnixDeviceVector sources_, std::shared_ptr ctx_) : Thread("FrameReader") { diff --git a/Source/FrameReader.h b/Source/FrameReader.h index 210786a..23aacfe 100644 --- a/Source/FrameReader.h +++ b/Source/FrameReader.h @@ -27,17 +27,20 @@ #include "OnixDevice.h" #include "oni.h" -class FrameReader : public Thread +namespace OnixSourcePlugin { -public: - FrameReader(OnixDeviceVector sources_, std::shared_ptr); + class FrameReader : public Thread + { + public: + FrameReader(OnixDeviceVector sources_, std::shared_ptr); - void run() override; + void run() override; -private: + private: - OnixDeviceVector sources; - std::shared_ptr context; + OnixDeviceVector sources; + std::shared_ptr context; - JUCE_LEAK_DETECTOR(FrameReader); -}; + JUCE_LEAK_DETECTOR(FrameReader); + }; +} diff --git a/Source/I2CRegisterContext.cpp b/Source/I2CRegisterContext.cpp index 3036d9e..eb4280c 100644 --- a/Source/I2CRegisterContext.cpp +++ b/Source/I2CRegisterContext.cpp @@ -22,6 +22,8 @@ #include "I2CRegisterContext.h" +using namespace OnixSourcePlugin; + I2CRegisterContext::I2CRegisterContext(uint32_t address_, const oni_dev_idx_t devIdx_, std::shared_ptr ctx_) : deviceIndex(devIdx_), i2cAddress(address_) { diff --git a/Source/I2CRegisterContext.h b/Source/I2CRegisterContext.h index ec4604b..d8b0508 100644 --- a/Source/I2CRegisterContext.h +++ b/Source/I2CRegisterContext.h @@ -29,26 +29,29 @@ #include -class I2CRegisterContext +namespace OnixSourcePlugin { -public: + class I2CRegisterContext + { + public: - I2CRegisterContext(uint32_t address, const oni_dev_idx_t, std::shared_ptr); + I2CRegisterContext(uint32_t address, const oni_dev_idx_t, std::shared_ptr); - int WriteByte(uint32_t address, uint32_t value, bool sixteenBitAddress = false); + int WriteByte(uint32_t address, uint32_t value, bool sixteenBitAddress = false); - int ReadByte(uint32_t address, oni_reg_val_t* value, bool sixteenBitAddress = false); + int ReadByte(uint32_t address, oni_reg_val_t* value, bool sixteenBitAddress = false); - int set933I2cRate(double); + int set933I2cRate(double); -protected: - std::shared_ptr i2cContext; + protected: + std::shared_ptr i2cContext; -private: + private: - const oni_dev_idx_t deviceIndex; + const oni_dev_idx_t deviceIndex; - const uint32_t i2cAddress; + const uint32_t i2cAddress; - JUCE_LEAK_DETECTOR(I2CRegisterContext); -}; + JUCE_LEAK_DETECTOR(I2CRegisterContext); + }; +} diff --git a/Source/NeuropixComponents.h b/Source/NeuropixComponents.h index 40cef71..989c947 100644 --- a/Source/NeuropixComponents.h +++ b/Source/NeuropixComponents.h @@ -29,239 +29,242 @@ #include "UI/ActivityView.h" -enum class VisualizationMode +namespace OnixSourcePlugin { - ENABLE_VIEW, - AP_GAIN_VIEW, - LFP_GAIN_VIEW, - REFERENCE_VIEW, - ACTIVITY_VIEW -}; - -enum class ProbeType -{ - NONE = 1, - NPX_V1E, - NPX_V2E, - NPX_V2E_BETA, -}; + enum class VisualizationMode + { + ENABLE_VIEW, + AP_GAIN_VIEW, + LFP_GAIN_VIEW, + REFERENCE_VIEW, + ACTIVITY_VIEW + }; -enum class Bank -{ - NONE = -1, - A = 0, - B = 1, - C = 2, - D = 3, - E = 4, - F = 5, - G = 6, - H = 7, - I = 8, - J = 9, - K = 10, - L = 11, - M = 12, -}; - -enum class ElectrodeStatus -{ - CONNECTED, - DISCONNECTED -}; + enum class ProbeType + { + NONE = 1, + NPX_V1E, + NPX_V2E, + NPX_V2E_BETA, + }; -enum class ElectrodeType -{ - ELECTRODE, - REFERENCE -}; + enum class Bank + { + NONE = -1, + A = 0, + B = 1, + C = 2, + D = 3, + E = 4, + F = 5, + G = 6, + H = 7, + I = 8, + J = 9, + K = 10, + L = 11, + M = 12, + }; -struct ElectrodeMetadata -{ - int global_index; - int shank_local_index; - int shank; - int column_index; - int channel; - int row_index; - float xpos; // position on shank, in microns - float ypos; // position on shank, in microns - float site_width; // in microns - Bank bank; - ElectrodeStatus status; - ElectrodeType type; - bool isSelected; - Colour colour; -}; - -struct ProbeMetadata -{ - int shank_count; - int electrodes_per_shank; - int num_adcs; - int adc_bits; - Path shankOutline; - int columns_per_shank; - int rows_per_shank; - String name; - bool switchable; -}; - -struct NeuropixelsV1fValues -{ - static const int numberOfChannels = 384; - static const int numberOfElectrodes = 960; - static const int numberOfShanks = 1; - static const int numberOfSettings = 1; -}; + enum class ElectrodeStatus + { + CONNECTED, + DISCONNECTED + }; -struct NeuropixelsV2eValues -{ - static const int numberOfChannels = 384; - static const int electrodesPerShank = 1280; - static const int numberOfShanks = 4; - static const int numberOfElectrodes = numberOfShanks * electrodesPerShank; - static const int numberOfSettings = 2; -}; - -template -struct ProbeSettings -{ - void updateProbeSettings(ProbeSettings* newSettings) + enum class ElectrodeType { - availableElectrodeConfigurations = newSettings->availableElectrodeConfigurations; - availableApGains = newSettings->availableApGains; - availableLfpGains = newSettings->availableLfpGains; - availableReferences = newSettings->availableReferences; - availableBanks = newSettings->availableBanks; - - electrodeConfigurationIndex = newSettings->electrodeConfigurationIndex; - apGainIndex = newSettings->apGainIndex; - lfpGainIndex = newSettings->lfpGainIndex; - referenceIndex = newSettings->referenceIndex; - apFilterState = newSettings->apFilterState; - - selectedBank = newSettings->selectedBank; - selectedShank = newSettings->selectedShank; - selectedElectrode = newSettings->selectedElectrode; - electrodeMetadata = newSettings->electrodeMetadata; - - probeType = newSettings->probeType; - - probeMetadata = newSettings->probeMetadata; + ELECTRODE, + REFERENCE }; - void clearElectrodeSelection() + struct ElectrodeMetadata { - selectedBank.clear(); - selectedShank.clear(); - selectedElectrode.clear(); - } + int global_index; + int shank_local_index; + int shank; + int column_index; + int channel; + int row_index; + float xpos; // position on shank, in microns + float ypos; // position on shank, in microns + float site_width; // in microns + Bank bank; + ElectrodeStatus status; + ElectrodeType type; + bool isSelected; + Colour colour; + }; - void selectElectrodes(std::vector electrodes) + struct ProbeMetadata { - for (int i = 0; i < electrodes.size(); i++) - { - selectElectrode(electrodes[i]); - } - } + int shank_count; + int electrodes_per_shank; + int num_adcs; + int adc_bits; + Path shankOutline; + int columns_per_shank; + int rows_per_shank; + String name; + bool switchable; + }; + + struct NeuropixelsV1fValues + { + static const int numberOfChannels = 384; + static const int numberOfElectrodes = 960; + static const int numberOfShanks = 1; + static const int numberOfSettings = 1; + }; + + struct NeuropixelsV2eValues + { + static const int numberOfChannels = 384; + static const int electrodesPerShank = 1280; + static const int numberOfShanks = 4; + static const int numberOfElectrodes = numberOfShanks * electrodesPerShank; + static const int numberOfSettings = 2; + }; - void selectElectrode(int electrode) + template + struct ProbeSettings { - Bank bank = electrodeMetadata[electrode].bank; - int channel = electrodeMetadata[electrode].channel; - int shank = electrodeMetadata[electrode].shank; - int global_index = electrodeMetadata[electrode].global_index; + void updateProbeSettings(ProbeSettings* newSettings) + { + availableElectrodeConfigurations = newSettings->availableElectrodeConfigurations; + availableApGains = newSettings->availableApGains; + availableLfpGains = newSettings->availableLfpGains; + availableReferences = newSettings->availableReferences; + availableBanks = newSettings->availableBanks; + + electrodeConfigurationIndex = newSettings->electrodeConfigurationIndex; + apGainIndex = newSettings->apGainIndex; + lfpGainIndex = newSettings->lfpGainIndex; + referenceIndex = newSettings->referenceIndex; + apFilterState = newSettings->apFilterState; + + selectedBank = newSettings->selectedBank; + selectedShank = newSettings->selectedShank; + selectedElectrode = newSettings->selectedElectrode; + electrodeMetadata = newSettings->electrodeMetadata; - for (int j = 0; j < electrodeMetadata.size(); j++) + probeType = newSettings->probeType; + + probeMetadata = newSettings->probeMetadata; + }; + + void clearElectrodeSelection() + { + selectedBank.clear(); + selectedShank.clear(); + selectedElectrode.clear(); + } + + void selectElectrodes(std::vector electrodes) { - if (electrodeMetadata[j].channel == channel) + for (int i = 0; i < electrodes.size(); i++) { - if (electrodeMetadata[j].bank == bank && electrodeMetadata[j].shank == shank) - { - electrodeMetadata[j].status = ElectrodeStatus::CONNECTED; - } + selectElectrode(electrodes[i]); + } + } + + void selectElectrode(int electrode) + { + Bank bank = electrodeMetadata[electrode].bank; + int channel = electrodeMetadata[electrode].channel; + int shank = electrodeMetadata[electrode].shank; + int global_index = electrodeMetadata[electrode].global_index; - else + for (int j = 0; j < electrodeMetadata.size(); j++) + { + if (electrodeMetadata[j].channel == channel) { - electrodeMetadata[j].status = ElectrodeStatus::DISCONNECTED; + if (electrodeMetadata[j].bank == bank && electrodeMetadata[j].shank == shank) + { + electrodeMetadata[j].status = ElectrodeStatus::CONNECTED; + } + + else + { + electrodeMetadata[j].status = ElectrodeStatus::DISCONNECTED; + } } } - } - - selectedBank[channel] = bank; - selectedShank[channel] = shank; - selectedElectrode[channel] = global_index; - } - Array availableElectrodeConfigurations; - Array availableApGains; // Available AP gain values for each channel (if any) - Array availableLfpGains; // Available LFP gain values for each channel (if any) - Array availableReferences; // reference types - Array availableBanks; // bank inds + selectedBank[channel] = bank; + selectedShank[channel] = shank; + selectedElectrode[channel] = global_index; + } - int electrodeConfigurationIndex; - int apGainIndex; - int lfpGainIndex; - int referenceIndex; - bool apFilterState; + Array availableElectrodeConfigurations; + Array availableApGains; // Available AP gain values for each channel (if any) + Array availableLfpGains; // Available LFP gain values for each channel (if any) + Array availableReferences; // reference types + Array availableBanks; // bank inds - std::array selectedBank; - std::array selectedShank; - std::array selectedElectrode; - std::array electrodeMetadata; + int electrodeConfigurationIndex; + int apGainIndex; + int lfpGainIndex; + int referenceIndex; + bool apFilterState; - ProbeType probeType; + std::array selectedBank; + std::array selectedShank; + std::array selectedElectrode; + std::array electrodeMetadata; - ProbeMetadata probeMetadata; + ProbeType probeType; - bool isValid = false; -}; + ProbeMetadata probeMetadata; -template -std::vector toBitReversedBytes(std::bitset bits) -{ - std::vector bytes((bits.size() - 1) / 8 + 1); + bool isValid = false; + }; - for (int i = 0; i < bytes.size(); i++) + template + std::vector toBitReversedBytes(std::bitset bits) { - for (int j = 0; j < 8; j++) + std::vector bytes((bits.size() - 1) / 8 + 1); + + for (int i = 0; i < bytes.size(); i++) { - bytes[i] |= bits[i * 8 + j] << (8 - j - 1); + for (int j = 0; j < 8; j++) + { + bytes[i] |= bits[i * 8 + j] << (8 - j - 1); + } + + // NB: Reverse bytes (http://graphics.stanford.edu/~seander/bithacks.html) + bytes[i] = (unsigned char)((bytes[i] * 0x0202020202ul & 0x010884422010ul) % 1023); } - // NB: Reverse bytes (http://graphics.stanford.edu/~seander/bithacks.html) - bytes[i] = (unsigned char)((bytes[i] * 0x0202020202ul & 0x010884422010ul) % 1023); + return bytes; } - return bytes; -} - -template -class INeuropixel -{ -public: - INeuropixel(int numSettings, int numShanks) : numberOfShanks(numShanks) + template + class INeuropixel { - if (numSettings > 2) return; - - for (int i = 0; i < numSettings; i++) + public: + INeuropixel(int numSettings, int numShanks) : numberOfShanks(numShanks) { - settings.emplace_back(std::make_unique>()); + if (numSettings > 2) return; + + for (int i = 0; i < numSettings; i++) + { + settings.emplace_back(std::make_unique>()); + } } - } - static const int numberOfChannels = ch; - static const int numberOfElectrodes = e; - const int numberOfShanks; + static const int numberOfChannels = ch; + static const int numberOfElectrodes = e; + const int numberOfShanks; - std::vector>> settings; + std::vector>> settings; - virtual void setSettings(ProbeSettings* settings_, int index) { return; } + virtual void setSettings(ProbeSettings* settings_, int index) { return; } - virtual void defineMetadata(ProbeSettings* settings) { return; } + virtual void defineMetadata(ProbeSettings* settings) { return; } - virtual uint64_t getProbeSerialNumber(int index) { return 0; } + virtual uint64_t getProbeSerialNumber(int index) { return 0; } - virtual std::vector selectElectrodeConfiguration(String config) { return {}; } -}; + virtual std::vector selectElectrodeConfiguration(String config) { return {}; } + }; +} diff --git a/Source/Onix1.cpp b/Source/Onix1.cpp index cdd99ac..273d4d8 100644 --- a/Source/Onix1.cpp +++ b/Source/Onix1.cpp @@ -22,6 +22,8 @@ #include "Onix1.h" +using namespace OnixSourcePlugin; + Onix1::Onix1(int hostIndex) { ctx_ = oni_create_ctx("riffa"); diff --git a/Source/Onix1.h b/Source/Onix1.h index 9a0ec8f..9137118 100644 --- a/Source/Onix1.h +++ b/Source/Onix1.h @@ -29,95 +29,98 @@ #include "../../plugin-GUI/Source/Utils/Utils.h" -constexpr char* NEUROPIXELSV1F_HEADSTAGE_NAME = "Neuropixels 1.0 Headstage"; -constexpr char* NEUROPIXELSV2E_HEADSTAGE_NAME = "Neuropixels 2.0 Headstage"; -constexpr char* BREAKOUT_BOARD_NAME = "Breakout Board"; - -class error_t : public std::exception +namespace OnixSourcePlugin { -public: - explicit error_t(int errorNum) : errorNum_(errorNum) {} + constexpr char* NEUROPIXELSV1F_HEADSTAGE_NAME = "Neuropixels 1.0 Headstage"; + constexpr char* NEUROPIXELSV2E_HEADSTAGE_NAME = "Neuropixels 2.0 Headstage"; + constexpr char* BREAKOUT_BOARD_NAME = "Breakout Board"; - const char* what() const noexcept override + class error_t : public std::exception { - return oni_error_str(errorNum_); - } + public: + explicit error_t(int errorNum) : errorNum_(errorNum) {} - int num() const { return errorNum_; } + const char* what() const noexcept override + { + return oni_error_str(errorNum_); + } -private: - int errorNum_; -}; + int num() const { return errorNum_; } -using device_map_t = std::unordered_map; + private: + int errorNum_; + }; -class Onix1 -{ -public: - Onix1(int hostIndex = 0); + using device_map_t = std::unordered_map; - ~Onix1(); + class Onix1 + { + public: + Onix1(int hostIndex = 0); - inline bool isInitialized() const { return ctx_ != nullptr; } + ~Onix1(); - template - int getOption(int option, opt_t* value) - { - size_t len = sizeof(opt_t); - int rc = get_opt_(option, value, &len); - return rc; - } + inline bool isInitialized() const { return ctx_ != nullptr; } - template - int setOption(int option, const opt_t value) - { - int rc = oni_set_opt(ctx_, option, &value, opt_size_(value)); - if (rc != ONI_ESUCCESS) LOGE(oni_error_str(rc)); - return rc; - } - - int readRegister(oni_dev_idx_t devIndex, oni_reg_addr_t registerAddress, oni_reg_val_t* value) const; + template + int getOption(int option, opt_t* value) + { + size_t len = sizeof(opt_t); + int rc = get_opt_(option, value, &len); + return rc; + } - int writeRegister(oni_dev_idx_t, oni_reg_addr_t, oni_reg_val_t) const; + template + int setOption(int option, const opt_t value) + { + int rc = oni_set_opt(ctx_, option, &value, opt_size_(value)); + if (rc != ONI_ESUCCESS) LOGE(oni_error_str(rc)); + return rc; + } - device_map_t getDeviceTable() const noexcept { return deviceTable; } + int readRegister(oni_dev_idx_t devIndex, oni_reg_addr_t registerAddress, oni_reg_val_t* value) const; - int updateDeviceTable(); + int writeRegister(oni_dev_idx_t, oni_reg_addr_t, oni_reg_val_t) const; - oni_frame_t* readFrame() const; + device_map_t getDeviceTable() const noexcept { return deviceTable; } - int issueReset() { int val = 1; int rc = setOption(ONI_OPT_RESET, val); return rc; } + int updateDeviceTable(); + + oni_frame_t* readFrame() const; + + int issueReset() { int val = 1; int rc = setOption(ONI_OPT_RESET, val); return rc; } std::string getVersion() const { return std::to_string(major) + "." + std::to_string(minor) + "." + std::to_string(patch); } - double convertTimestampToSeconds(uint32_t timestamp) const { return static_cast(timestamp) / ACQ_CLK_HZ; } + double convertTimestampToSeconds(uint32_t timestamp) const { return static_cast(timestamp) / ACQ_CLK_HZ; } -private: + private: - /** The ONI ctx object */ - oni_ctx ctx_; + /** The ONI ctx object */ + oni_ctx ctx_; - int major; - int minor; - int patch; + int major; + int minor; + int patch; - uint32_t ACQ_CLK_HZ; + uint32_t ACQ_CLK_HZ; - device_map_t deviceTable; + device_map_t deviceTable; - template - size_t opt_size_(opt_t opt) - { - size_t len = 0; - if constexpr (std::is_same::value) - len = strlen(len) + 1; - else if constexpr (std::is_same::value) - len = strlen(len) + 1; - else - len = sizeof(opt); - - return len; - } - - int get_opt_(int option, void* value, size_t* size) const; -}; + template + size_t opt_size_(opt_t opt) + { + size_t len = 0; + if constexpr (std::is_same::value) + len = strlen(len) + 1; + else if constexpr (std::is_same::value) + len = strlen(len) + 1; + else + len = sizeof(opt); + + return len; + } + + int get_opt_(int option, void* value, size_t* size) const; + }; +} diff --git a/Source/OnixDevice.cpp b/Source/OnixDevice.cpp index 8761ac3..525d3ea 100644 --- a/Source/OnixDevice.cpp +++ b/Source/OnixDevice.cpp @@ -22,6 +22,8 @@ #include "OnixDevice.h" +using namespace OnixSourcePlugin; + OnixDevice::OnixDevice(String name_, String headstageName, OnixDeviceType type_, const oni_dev_idx_t deviceIdx_, std::shared_ptr ctx) : type(type_), deviceIdx(deviceIdx_) { @@ -106,3 +108,67 @@ String OnixDevice::getStreamIdentifier() return streamIdentifier; } + +int OnixDevice::getPortOffset(PortName port) +{ + return (uint32_t)port << 8; +} + +String OnixDevice::getPortName(int offset) +{ + switch (offset) + { + case 0: + return ""; + case HubAddressPortA: + return "Port A"; + case HubAddressPortB: + return "Port B"; + default: + return ""; + } +} + +String OnixDevice::getPortName(PortName port) +{ + return getPortName(getPortOffset(port)); +} + +String OnixDevice::getPortNameFromIndex(oni_dev_idx_t index) +{ + return getPortName(getOffsetFromIndex(index)); +} + +PortName OnixDevice::getPortFromIndex(oni_dev_idx_t index) +{ + return index & (1 << 8) ? PortName::PortA : PortName::PortB; +} + +int OnixDevice::getOffsetFromIndex(oni_dev_idx_t index) +{ + return index & 0b1100000000; +} + +Array OnixDevice::getUniqueOffsetsFromIndices(std::vector indices) +{ + Array offsets; + + for (auto index : indices) + { + offsets.addIfNotAlreadyThere(getOffsetFromIndex(index)); + } + + return offsets; +} + +Array OnixDevice::getUniquePortsFromIndices(std::vector indices) +{ + Array ports; + + for (auto index : indices) + { + ports.addIfNotAlreadyThere(getPortFromIndex(index)); + } + + return ports; +} diff --git a/Source/OnixDevice.h b/Source/OnixDevice.h index 2d45a3e..83a835e 100644 --- a/Source/OnixDevice.h +++ b/Source/OnixDevice.h @@ -35,196 +35,211 @@ using namespace std::chrono; -enum class PortName +namespace OnixSourcePlugin { - PortA = 1, - PortB = 2 -}; - -enum class OnixDeviceType { - BNO, - POLLEDBNO, - NEUROPIXELS_1, - NEUROPIXELSV2E, - PORT_CONTROL, - MEMORYMONITOR, - OUTPUTCLOCK, - HEARTBEAT, - HARPSYNCINPUT, - ANALOGIO, - DIGITALIO, -}; - -struct StreamInfo { -public: - StreamInfo() {} - - StreamInfo(String name, String description, String streamIdentifier, int numChannels, float sampleRate, String channelPrefix, ContinuousChannel::Type channelType, - float bitVolts, String units, StringArray channelNameSuffixes, String channelIdentifierDataType, StringArray channelIdentifierSubTypes = {}) + enum class PortName { - m_name = name; - m_description = description; - m_streamIdentifier = streamIdentifier; - m_numChannels = numChannels; - m_sampleRate = sampleRate; - m_channelPrefix = channelPrefix; - m_channelType = channelType; - m_bitVolts = bitVolts; - m_units = units; - m_channelNameSuffixes = channelNameSuffixes; - m_channelIdentifierDataType = channelIdentifierDataType; - m_channelIdentifierSubTypes = channelIdentifierSubTypes; - - if (m_numChannels != m_channelNameSuffixes.size()) - { - if (m_channelNameSuffixes.size() != 0) - LOGE("Difference between number of channels and channel name suffixes. Generating default suffixes instead."); + PortA = 1, + PortB = 2 + }; - m_channelNameSuffixes.clear(); - m_channelNameSuffixes.ensureStorageAllocated(numChannels); + enum class OnixDeviceType { + BNO, + POLLEDBNO, + NEUROPIXELS_1, + NEUROPIXELSV2E, + PORT_CONTROL, + MEMORYMONITOR, + OUTPUTCLOCK, + HEARTBEAT, + HARPSYNCINPUT, + ANALOGIO, + DIGITALIO, + }; - for (int i = 0; i < m_numChannels; i++) - { - m_channelNameSuffixes.add(String(i + 1)); - } - } + struct StreamInfo { + public: + StreamInfo() {} - if (m_channelIdentifierSubTypes.size() > 0 && m_numChannels != m_channelIdentifierSubTypes.size()) + StreamInfo(String name, String description, String streamIdentifier, int numChannels, float sampleRate, String channelPrefix, ContinuousChannel::Type channelType, + float bitVolts, String units, StringArray channelNameSuffixes, String channelIdentifierDataType, StringArray channelIdentifierSubTypes = {}) { - if (m_channelIdentifierSubTypes.size() == 1) + m_name = name; + m_description = description; + m_streamIdentifier = streamIdentifier; + m_numChannels = numChannels; + m_sampleRate = sampleRate; + m_channelPrefix = channelPrefix; + m_channelType = channelType; + m_bitVolts = bitVolts; + m_units = units; + m_channelNameSuffixes = channelNameSuffixes; + m_channelIdentifierDataType = channelIdentifierDataType; + m_channelIdentifierSubTypes = channelIdentifierSubTypes; + + if (m_numChannels != m_channelNameSuffixes.size()) { - for (int i = 1; i < m_numChannels; i++) + if (m_channelNameSuffixes.size() != 0) + LOGE("Difference between number of channels and channel name suffixes. Generating default suffixes instead."); + + m_channelNameSuffixes.clear(); + m_channelNameSuffixes.ensureStorageAllocated(numChannels); + + for (int i = 0; i < m_numChannels; i++) { - m_channelIdentifierSubTypes.add(m_channelIdentifierSubTypes[0]); + m_channelNameSuffixes.add(String(i + 1)); } } - else + + if (m_channelIdentifierSubTypes.size() > 0 && m_numChannels != m_channelIdentifierSubTypes.size()) { - LOGE("Difference between number of channels and channel identifier subtypes. Generating default subtypes instead."); + if (m_channelIdentifierSubTypes.size() == 1) + { + for (int i = 1; i < m_numChannels; i++) + { + m_channelIdentifierSubTypes.add(m_channelIdentifierSubTypes[0]); + } + } + else + { + LOGE("Difference between number of channels and channel identifier subtypes. Generating default subtypes instead."); - m_channelIdentifierSubTypes.clear(); - m_channelIdentifierSubTypes.ensureStorageAllocated(numChannels); + m_channelIdentifierSubTypes.clear(); + m_channelIdentifierSubTypes.ensureStorageAllocated(numChannels); - for (int i = 0; i < m_numChannels; i++) - { - m_channelIdentifierSubTypes.add(String(i + 1)); + for (int i = 0; i < m_numChannels; i++) + { + m_channelIdentifierSubTypes.add(String(i + 1)); + } } } - } + }; + + String getName() const { return m_name; } + String getDescription() const { return m_description; } + String getStreamIdentifier() const { return m_streamIdentifier; } + int getNumChannels() const { return m_numChannels; } + float getSampleRate() const { return m_sampleRate; } + String getChannelPrefix() const { return m_channelPrefix; } + ContinuousChannel::Type getChannelType() const { return m_channelType; } + float getBitVolts() const { return m_bitVolts; } + String getUnits() const { return m_units; } + StringArray getChannelNameSuffixes() const { return m_channelNameSuffixes; } + String getChannelIdentifierDataType() const { return m_channelIdentifierDataType; } + StringArray getChannelIdentifierSubTypes() const { return m_channelIdentifierSubTypes; } + + private: + String m_name = "name"; + String m_description = "description"; + String m_streamIdentifier = "identifier"; + int m_numChannels = 0; + float m_sampleRate = 0; + String m_channelPrefix = "channelPrefix"; + ContinuousChannel::Type m_channelType = ContinuousChannel::Type::INVALID; + float m_bitVolts = 1.0f; + String m_units = "units"; + StringArray m_channelNameSuffixes = { "suffixes" }; + String m_channelIdentifierDataType = "datatype"; + StringArray m_channelIdentifierSubTypes = { "subtypes" }; }; - String getName() const { return m_name; } - String getDescription() const { return m_description; } - String getStreamIdentifier() const { return m_streamIdentifier; } - int getNumChannels() const { return m_numChannels; } - float getSampleRate() const { return m_sampleRate; } - String getChannelPrefix() const { return m_channelPrefix; } - ContinuousChannel::Type getChannelType() const { return m_channelType; } - float getBitVolts() const { return m_bitVolts; } - String getUnits() const { return m_units; } - StringArray getChannelNameSuffixes() const { return m_channelNameSuffixes; } - String getChannelIdentifierDataType() const { return m_channelIdentifierDataType; } - StringArray getChannelIdentifierSubTypes() const { return m_channelIdentifierSubTypes; } - -private: - String m_name = "name"; - String m_description = "description"; - String m_streamIdentifier = "identifier"; - int m_numChannels = 0; - float m_sampleRate = 0; - String m_channelPrefix = "channelPrefix"; - ContinuousChannel::Type m_channelType = ContinuousChannel::Type::INVALID; - float m_bitVolts = 1.0f; - String m_units = "units"; - StringArray m_channelNameSuffixes = { "suffixes" }; - String m_channelIdentifierDataType = "datatype"; - StringArray m_channelIdentifierSubTypes = { "subtypes" }; -}; - -/** - - Streams data from an ONIX device + /** -*/ -class OnixDevice -{ -public: + Streams data from an ONIX device - /** Constructor */ - OnixDevice(String name_, String headstageName, OnixDeviceType type_, const oni_dev_idx_t, std::shared_ptr oni_ctx); + */ + class OnixDevice + { + public: - /** Destructor */ - ~OnixDevice() { } + /** Constructor */ + OnixDevice(String name_, String headstageName, OnixDeviceType type_, const oni_dev_idx_t, std::shared_ptr oni_ctx); - virtual void addFrame(oni_frame_t*) {}; + /** Destructor */ + ~OnixDevice() { } - virtual void processFrames() {}; + virtual void addFrame(oni_frame_t*) {}; - const String getName() { return name; } + virtual void processFrames() {}; - bool isEnabled() const { return enabled; } + const String getName() { return name; } - void setEnabled(bool newState) { enabled = newState; } + bool isEnabled() const { return enabled; } - virtual int configureDevice() { return -1; }; + void setEnabled(bool newState) { enabled = newState; } - virtual bool updateSettings() { return false; }; + virtual int configureDevice() { return -1; }; - virtual void startAcquisition() {}; + virtual bool updateSettings() { return false; }; - virtual void stopAcquisition() {}; + virtual void startAcquisition() {}; - /** Given the sourceBuffers from OnixSource, add all streams for the current device to the array */ - virtual void addSourceBuffers(OwnedArray& sourceBuffers) {}; + virtual void stopAcquisition() {}; - oni_dev_idx_t getDeviceIdx(bool getPassthroughIndex = false); + /** Given the sourceBuffers from OnixSource, add all streams for the current device to the array */ + virtual void addSourceBuffers(OwnedArray& sourceBuffers) {}; - /** Creates a stream name using the provided inputs, returning a String following the pattern: name[0]-name[1]-name[2]-etc., with all spaces removed */ - static String createStreamName(std::vector names) - { - String streamName; + oni_dev_idx_t getDeviceIdx(bool getPassthroughIndex = false); - for (int i = 0; i < names.size(); i++) + /** Creates a stream name using the provided inputs, returning a String following the pattern: name[0]-name[1]-name[2]-etc., with all spaces removed */ + static String createStreamName(std::vector names) { - streamName += names[i].removeCharacters(" "); + String streamName; - if (i != names.size() - 1) streamName += "-"; + for (int i = 0; i < names.size(); i++) + { + streamName += names[i].removeCharacters(" "); + + if (i != names.size() - 1) streamName += "-"; + } + + return streamName; } - return streamName; - } + Array streamInfos; + + const int bufferSizeInSeconds = 10; - Array streamInfos; + static constexpr int HubAddressPortA = 256; + static constexpr int HubAddressPortB = 512; - const int bufferSizeInSeconds = 10; + String getHeadstageName() { return m_headstageName; } + void setHeadstageName(String headstage) { m_headstageName = headstage; } - String getHeadstageName() { return m_headstageName; } - void setHeadstageName(String headstage) { m_headstageName = headstage; } + static int getPortOffset(PortName port); + static String getPortName(int offset); + static String getPortName(PortName port); + static String getPortNameFromIndex(oni_dev_idx_t index); + static PortName getPortFromIndex(oni_dev_idx_t index); + static int getOffsetFromIndex(oni_dev_idx_t index); + static Array getUniqueOffsetsFromIndices(std::vector indices); + static Array getUniquePortsFromIndices(std::vector indices); - OnixDeviceType getDeviceType() const; + OnixDeviceType getDeviceType() const; - /** Returns a string for this device that follows the pattern: onix.[headstage|breakout].[device] */ - String getStreamIdentifier(); + /** Returns a string for this device that follows the pattern: onix.[headstage|breakout].[device] */ + String getStreamIdentifier(); -protected: + protected: - oni_dev_idx_t getDeviceIndexFromPassthroughIndex(oni_dev_idx_t hubIndex); + oni_dev_idx_t getDeviceIndexFromPassthroughIndex(oni_dev_idx_t hubIndex); - const oni_dev_idx_t deviceIdx; - std::shared_ptr deviceContext; + const oni_dev_idx_t deviceIdx; + std::shared_ptr deviceContext; -private: + private: - String name; + String name; - bool enabled = true; - bool isPassthrough = false; + bool enabled = true; + bool isPassthrough = false; - String m_headstageName; + String m_headstageName; - const OnixDeviceType type; + const OnixDeviceType type; - JUCE_LEAK_DETECTOR(OnixDevice); -}; + JUCE_LEAK_DETECTOR(OnixDevice); + }; -using OnixDeviceVector = std::vector>; + using OnixDeviceVector = std::vector>; +} diff --git a/Source/OnixSource.cpp b/Source/OnixSource.cpp index 7edcdaa..9c1f627 100644 --- a/Source/OnixSource.cpp +++ b/Source/OnixSource.cpp @@ -23,6 +23,8 @@ #include "OnixSource.h" #include "Devices/DeviceList.h" +using namespace OnixSourcePlugin; + OnixSource::OnixSource(SourceNode* sn) : DataThread(sn), devicesFound(false), @@ -573,7 +575,7 @@ void OnixSource::updateSettings(OwnedArray* continuousChannel deviceInfos->add(new DeviceInfo(deviceSettings)); DataStream::Settings dataStreamSettings{ - OnixDevice::createStreamName({PortController::getPortName(PortController::getPortFromIndex(source->getDeviceIdx())), source->getHeadstageName(), source->getName()}), + OnixDevice::createStreamName({OnixDevice::getPortNameFromIndex(source->getDeviceIdx()), source->getHeadstageName(), source->getName()}), "Continuous data from a Bno055 9-axis IMU", source->getStreamIdentifier(), source->streamInfos[0].getSampleRate() diff --git a/Source/OnixSource.h b/Source/OnixSource.h index df72b1f..8878b00 100644 --- a/Source/OnixSource.h +++ b/Source/OnixSource.h @@ -30,127 +30,130 @@ #include "FrameReader.h" #include "Devices/PortController.h" -/** - - @see DataThread, SourceNode - -*/ -class OnixSource : public DataThread +namespace OnixSourcePlugin { -public: + /** - /** Constructor */ - OnixSource(SourceNode* sn); + @see DataThread, SourceNode - /** Destructor */ - ~OnixSource() + */ + class OnixSource : public DataThread { - if (context != nullptr && context->isInitialized()) + public: + + /** Constructor */ + OnixSource(SourceNode* sn); + + /** Destructor */ + ~OnixSource() { - portA->setVoltageOverride(0.0f, false); - portB->setVoltageOverride(0.0f, false); + if (context != nullptr && context->isInitialized()) + { + portA->setVoltageOverride(0.0f, false); + portB->setVoltageOverride(0.0f, false); + } } - } - /** Static method to create DataThread */ - static DataThread* createDataThread(SourceNode* sn); + /** Static method to create DataThread */ + static DataThread* createDataThread(SourceNode* sn); - /** Creates the custom editor */ - std::unique_ptr createEditor(SourceNode* sn) override; + /** Creates the custom editor */ + std::unique_ptr createEditor(SourceNode* sn) override; - /** Reads frames and adds them to the appropriate device */ - bool updateBuffer() override; + /** Reads frames and adds them to the appropriate device */ + bool updateBuffer() override; - /** Returns true if the processor is ready to stream data, including all hardware initialization. Returns false if not ready. */ - bool isReady() override; + /** Returns true if the processor is ready to stream data, including all hardware initialization. Returns false if not ready. */ + bool isReady() override; - /** Returns true if the hardware is connected, false otherwise.*/ - bool foundInputSource() override; + /** Returns true if the hardware is connected, false otherwise.*/ + bool foundInputSource() override; - /** Returns true if the deviceMap matches the settings tabs that are open */ - bool isDevicesReady(); + /** Returns true if the deviceMap matches the settings tabs that are open */ + bool isDevicesReady(); - /** Initializes data transfer.*/ - bool startAcquisition() override; + /** Initializes data transfer.*/ + bool startAcquisition() override; - /** Stops data transfer.*/ - bool stopAcquisition() override; + /** Stops data transfer.*/ + bool stopAcquisition() override; - void updateDiscoveryParameters(PortName port, DiscoveryParameters parameters); + void updateDiscoveryParameters(PortName port, DiscoveryParameters parameters); - /** Takes a string from the editor. Can be an empty string to allow for automated discovery */ - bool configurePortVoltage(PortName port, String voltage) const; + /** Takes a string from the editor. Can be an empty string to allow for automated discovery */ + bool configurePortVoltage(PortName port, String voltage) const; - /** Sets the port voltage */ - void setPortVoltage(PortName port, double voltage) const; + /** Sets the port voltage */ + void setPortVoltage(PortName port, double voltage) const; - double getLastVoltageSet(PortName port); + double getLastVoltageSet(PortName port); - void resetContext() { if (context != nullptr && context->isInitialized()) context->issueReset(); } + void resetContext() { if (context != nullptr && context->isInitialized()) context->issueReset(); } - bool isContextInitialized() { return context != nullptr && context->isInitialized(); } + bool isContextInitialized() { return context != nullptr && context->isInitialized(); } - void initializeDevices(bool updateStreamInfo = false); + void initializeDevices(bool updateStreamInfo = false); - void disconnectDevices(bool updateStreamInfo = false); + void disconnectDevices(bool updateStreamInfo = false); - OnixDeviceVector getDataSources(); + OnixDeviceVector getDataSources(); - OnixDeviceVector getEnabledDataSources(); + OnixDeviceVector getEnabledDataSources(); - OnixDeviceVector getDataSourcesFromPort(PortName port); + OnixDeviceVector getDataSourcesFromPort(PortName port); - OnixDeviceVector getDataSourcesFromOffset(int offset); + OnixDeviceVector getDataSourcesFromOffset(int offset); - std::shared_ptr getDevice(OnixDeviceType type); + std::shared_ptr getDevice(OnixDeviceType type); - static std::map createDeviceMap(OnixDeviceVector, bool filterDevices = false); + static std::map createDeviceMap(OnixDeviceVector, bool filterDevices = false); - std::map createDeviceMap(bool filterDevices = false); + std::map createDeviceMap(bool filterDevices = false); - std::map getHeadstageMap(); + std::map getHeadstageMap(); - String getLiboniVersion() { if (context != nullptr && context->isInitialized()) return context->getVersion(); else return ""; } + String getLiboniVersion() { if (context != nullptr && context->isInitialized()) return context->getVersion(); else return ""; } - void updateSourceBuffers(); + void updateSourceBuffers(); - // DataThread Methods - void updateSettings(OwnedArray* continuousChannels, - OwnedArray* eventChannels, - OwnedArray* spikeChannels, - OwnedArray* sourceStreams, - OwnedArray* devices, - OwnedArray* configurationObjects); + // DataThread Methods + void updateSettings(OwnedArray* continuousChannels, + OwnedArray* eventChannels, + OwnedArray* spikeChannels, + OwnedArray* sourceStreams, + OwnedArray* devices, + OwnedArray* configurationObjects); -private: + private: - /** Available data sources */ - OnixDeviceVector sources; - OnixDeviceVector enabledSources; + /** Available data sources */ + OnixDeviceVector sources; + OnixDeviceVector enabledSources; - /** Available headstages, indexed by their offset value */ - std::map headstages; + /** Available headstages, indexed by their offset value */ + std::map headstages; - /** Pointer to the editor */ - OnixSourceEditor* editor; + /** Pointer to the editor */ + OnixSourceEditor* editor; - /** Thread that reads frames */ - std::unique_ptr frameReader; + /** Thread that reads frames */ + std::unique_ptr frameReader; - std::shared_ptr context = nullptr; + std::shared_ptr context = nullptr; - std::shared_ptr portA; - std::shared_ptr portB; + std::shared_ptr portA; + std::shared_ptr portB; - const oni_size_t block_read_size = 2048; + const oni_size_t block_read_size = 2048; - bool devicesFound = false; + bool devicesFound = false; - void addIndividualStreams(Array, OwnedArray*, OwnedArray*, OwnedArray*); + void addIndividualStreams(Array, OwnedArray*, OwnedArray*, OwnedArray*); - void addCombinedStreams(DataStream::Settings, Array, OwnedArray*, OwnedArray*, OwnedArray*); + void addCombinedStreams(DataStream::Settings, Array, OwnedArray*, OwnedArray*, OwnedArray*); String createContinuousChannelIdentifier(StreamInfo streamInfo, int channelNumber); - JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(OnixSource); -}; + JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(OnixSource); + }; +} diff --git a/Source/OnixSourceCanvas.cpp b/Source/OnixSourceCanvas.cpp index f845bae..bb3ea53 100644 --- a/Source/OnixSourceCanvas.cpp +++ b/Source/OnixSourceCanvas.cpp @@ -22,6 +22,9 @@ #include "OnixSourceCanvas.h" #include "OnixSource.h" +#include "OnixSourceEditor.h" + +using namespace OnixSourcePlugin; OnixSourceCanvas::OnixSourceCanvas(GenericProcessor* processor_, OnixSourceEditor* editor_, OnixSource* onixSource_) : Visualizer(processor_), @@ -223,7 +226,7 @@ void OnixSourceCanvas::updateSettingsInterfaceDataSource(std::shared_ptr OnixSourceCanvas::getHeadstageTabs() @@ -254,7 +257,7 @@ void OnixSourceCanvas::removeTabs(PortName port) for (int i = headstageTabs.size() - 1; i >= 0; i -= 1) { - if (headstageTabs[i]->getName().contains(PortController::getPortName(port))) + if (headstageTabs[i]->getName().contains(OnixDevice::getPortName(port))) { headstageTabs.remove(i, true); tabExists = true; @@ -310,7 +313,7 @@ void OnixSourceCanvas::askKeepRemove(int offset) { String selectedHeadstage = editor->getHeadstageSelected(offset); - String msg = "Headstage " + selectedHeadstage + " is selected on " + PortController::getPortName(offset) + ", but was not discovered there.\n\n"; + String msg = "Headstage " + selectedHeadstage + " is selected on " + OnixDevice::getPortName(offset) + ", but was not discovered there.\n\n"; msg += "Select one of the options below to continue:\n"; msg += " [Keep Current] to keep " + selectedHeadstage + " selected.\n"; msg += " [Remove] to remove " + selectedHeadstage + ".\n - Note: this will delete any settings that were modified."; @@ -342,8 +345,8 @@ void OnixSourceCanvas::askKeepUpdate(int offset, String foundHeadstage, OnixDevi if (selectedHeadstage == foundHeadstage) return; - String msg = "Headstage " + selectedHeadstage + " is selected on " + PortController::getPortName(offset) + ". "; - msg += "However, headstage " + foundHeadstage + " was found on " + PortController::getPortName(offset) + ". \n\n"; + String msg = "Headstage " + selectedHeadstage + " is selected on " + OnixDevice::getPortName(offset) + ". "; + msg += "However, headstage " + foundHeadstage + " was found on " + OnixDevice::getPortName(offset) + ". \n\n"; msg += "Select one of the options below to continue:\n"; msg += " [Keep Current] to keep " + selectedHeadstage + " selected.\n"; msg += " [Update] to change the selected headstage to " + foundHeadstage + ".\n - Note: this will delete any settings that were modified."; diff --git a/Source/OnixSourceCanvas.h b/Source/OnixSourceCanvas.h index 54b22db..1539f39 100644 --- a/Source/OnixSourceCanvas.h +++ b/Source/OnixSourceCanvas.h @@ -27,106 +27,108 @@ #include "UI/InterfaceList.h" #include "UI/CustomTabComponent.h" -#include "OnixSourceEditor.h" - -class OnixSource; - -/** - Holds the visualizer for additional probe settings -*/ -class OnixSourceCanvas : public Visualizer +namespace OnixSourcePlugin { -public: - /** Constructor */ - OnixSourceCanvas(GenericProcessor*, OnixSourceEditor*, OnixSource*); + class OnixSource; + class OnixSourceEditor; + + /** + Holds the visualizer for additional probe settings + */ + class OnixSourceCanvas : public Visualizer + { + public: + /** Constructor */ + OnixSourceCanvas(GenericProcessor*, OnixSourceEditor*, OnixSource*); - /** Renders the Visualizer on each animation callback cycle */ - void refresh() override; + /** Renders the Visualizer on each animation callback cycle */ + void refresh() override; - /** Starts animation (not needed for this component) */ - void beginAnimation() override {} + /** Starts animation (not needed for this component) */ + void beginAnimation() override {} - /** Stops animation (not needed for this component) */ - void endAnimation() override {} + /** Stops animation (not needed for this component) */ + void endAnimation() override {} - /** Called when the Visualizer's tab becomes visible after being hidden */ - void refreshState() override; + /** Called when the Visualizer's tab becomes visible after being hidden */ + void refreshState() override; - /** Removes tabs from the canvas at the specified port */ - void removeTabs(PortName port); + /** Removes tabs from the canvas at the specified port */ + void removeTabs(PortName port); - /** Removes all tabs from the canvas */ - void removeAllTabs(); + /** Removes all tabs from the canvas */ + void removeAllTabs(); - /** Called when the hardware is connected, to ensure the right tabs are present */ - void refreshTabs(); + /** Called when the hardware is connected, to ensure the right tabs are present */ + void refreshTabs(); - /** Called when the Visualizer is first created, and optionally when - the parameters of the underlying processor are changed */ - void update() const; + /** Called when the Visualizer is first created, and optionally when + the parameters of the underlying processor are changed */ + void update() const; - /** Starts animation of sub-interfaces */ - void startAcquisition(); + /** Starts animation of sub-interfaces */ + void startAcquisition(); - /** Stops animation of sub-interfaces */ - void stopAcquisition(); + /** Stops animation of sub-interfaces */ + void stopAcquisition(); - /** Add the hub and all of its devices to the canvas */ - void addHub(String, int); + /** Add the hub and all of its devices to the canvas */ + void addHub(String, int); - /** Called when the basestation is created or refreshed */ - void populateSourceTabs(CustomTabComponent*, OnixDeviceVector); + /** Called when the basestation is created or refreshed */ + void populateSourceTabs(CustomTabComponent*, OnixDeviceVector); - /** Saves custom UI settings */ - void saveCustomParametersToXml(XmlElement* xml) override; + /** Saves custom UI settings */ + void saveCustomParametersToXml(XmlElement* xml) override; - /** Loads custom UI settings*/ - void loadCustomParametersFromXml(XmlElement* xml) override; + /** Loads custom UI settings*/ + void loadCustomParametersFromXml(XmlElement* xml) override; - /** Sets bounds of sub-components*/ - void resized(); + /** Sets bounds of sub-components*/ + void resized(); - Array getHeadstageTabs(); + Array getHeadstageTabs(); - std::map createSelectedMap(std::vector>); + std::map createSelectedMap(std::vector>); - std::vector> settingsInterfaces; + std::vector> settingsInterfaces; - void resetContext(); + void resetContext(); - bool foundInputSource(); + bool foundInputSource(); -private: + private: - OnixSourceEditor* editor; + OnixSourceEditor* editor; - OnixSource* source; + OnixSource* source; - std::unique_ptr topLevelTabComponent; - OwnedArray headstageTabs; + std::unique_ptr topLevelTabComponent; + OwnedArray headstageTabs; - CustomTabComponent* addTopLevelTab(String tabName, int index = -1); + CustomTabComponent* addTopLevelTab(String tabName, int index = -1); - void addInterfaceToTab(String tabName, CustomTabComponent* tab, std::shared_ptr interface_); + void addInterfaceToTab(String tabName, CustomTabComponent* tab, std::shared_ptr interface_); - void updateSettingsInterfaceDataSource(std::shared_ptr); + void updateSettingsInterfaceDataSource(std::shared_ptr); - // Compare two device names, ignoring the "-X" if it exists - bool compareDeviceNames(String dev1, String dev2); + // Compare two device names, ignoring the "-X" if it exists + bool compareDeviceNames(String dev1, String dev2); - String getTopLevelTabName(PortName port, String headstage); + String getTopLevelTabName(PortName port, String headstage); - /** - Create an alert window that asks whether to keep the selected headstage on the given port, - or to remove it since the hardware was not found - */ - void askKeepRemove(int offset); + /** + Create an alert window that asks whether to keep the selected headstage on the given port, + or to remove it since the hardware was not found + */ + void askKeepRemove(int offset); - /** - Create an alert window that asks whether to keep the selected headstage on the given port, - or to update to the headstage that was found - */ - void askKeepUpdate(int offset, String foundHeadstage, OnixDeviceVector devices); + /** + Create an alert window that asks whether to keep the selected headstage on the given port, + or to update to the headstage that was found + */ + void askKeepUpdate(int offset, String foundHeadstage, OnixDeviceVector devices); - JUCE_LEAK_DETECTOR(OnixSourceCanvas); -}; + JUCE_LEAK_DETECTOR(OnixSourceCanvas); + }; +} diff --git a/Source/OnixSourceEditor.cpp b/Source/OnixSourceEditor.cpp index a67d5a7..cf17173 100644 --- a/Source/OnixSourceEditor.cpp +++ b/Source/OnixSourceEditor.cpp @@ -22,6 +22,9 @@ #include "OnixSourceEditor.h" #include "OnixSource.h" +#include "OnixSourceCanvas.h" + +using namespace OnixSourcePlugin; OnixSourceEditor::OnixSourceEditor(GenericProcessor* parentNode, OnixSource* source_) : VisualizerEditor(parentNode, "Onix Source", 250), source(source_) @@ -311,7 +314,7 @@ void OnixSourceEditor::updateComboBox(ComboBox* cb) for (auto& [key, _] : deviceMap) { deviceIndices.emplace_back(key); } for (auto& [key, _] : tabMap) { tabIndices.emplace_back(key); } - auto devicePorts = PortController::getUniquePortsFromIndices(deviceIndices); + auto devicePorts = OnixDevice::getUniquePortsFromIndices(deviceIndices); auto tabPorts = PortController::getUniquePortsFromIndices(tabIndices); bool isPortA = cb == headstageComboBoxA.get(); @@ -323,7 +326,7 @@ void OnixSourceEditor::updateComboBox(ComboBox* cb) AlertWindow::showMessageBox( MessageBoxIconType::WarningIcon, "Devices Connected", - "Cannot select a different headstage on " + PortController::getPortName(currentPort) + " when connected. \n\nPress disconnect before changing the selected headstage."); + "Cannot select a different headstage on " + OnixDevice::getPortName(currentPort) + " when connected. \n\nPress disconnect before changing the selected headstage."); refreshComboBoxSelection(); return; @@ -492,9 +495,9 @@ String OnixSourceEditor::getHeadstageSelected(int offset) { case 0: return "Breakout Board"; - case PortController::HubAddressPortA: + case OnixDevice::HubAddressPortA: return headstageComboBoxA->getText(); - case PortController::HubAddressPortB: + case OnixDevice::HubAddressPortB: return headstageComboBoxB->getText(); default: return ""; @@ -536,13 +539,13 @@ void OnixSourceEditor::refreshComboBoxSelection() for (const auto tab : headstageTabs) { - if (tab->getName().contains(PortController::getPortName(PortName::PortA))) + if (tab->getName().contains(OnixDevice::getPortName(PortName::PortA))) { setComboBoxSelection(headstageComboBoxA.get(), tab->getName()); source->updateDiscoveryParameters(PortName::PortA, PortController::getHeadstageDiscoveryParameters(headstageComboBoxA->getText())); resetPortA = false; } - else if (tab->getName().contains(PortController::getPortName(PortName::PortB))) + else if (tab->getName().contains(OnixDevice::getPortName(PortName::PortB))) { setComboBoxSelection(headstageComboBoxB.get(), tab->getName()); source->updateDiscoveryParameters(PortName::PortB, PortController::getHeadstageDiscoveryParameters(headstageComboBoxB->getText())); diff --git a/Source/OnixSourceEditor.h b/Source/OnixSourceEditor.h index 13e5fda..cf777a2 100644 --- a/Source/OnixSourceEditor.h +++ b/Source/OnixSourceEditor.h @@ -1,22 +1,22 @@ /* - ------------------------------------------------------------------ + ------------------------------------------------------------------ - Copyright (C) Open Ephys + Copyright (C) Open Ephys - ------------------------------------------------------------------ + ------------------------------------------------------------------ - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. - You should have received a copy of the GNU General Public License - along with this program. If not, see . + You should have received a copy of the GNU General Public License + along with this program. If not, see . */ @@ -24,105 +24,108 @@ #include -#include "OnixSourceCanvas.h" #include "NeuropixComponents.h" #include "Devices/MemoryMonitor.h" -class OnixSource; +namespace OnixSourcePlugin +{ + class OnixSource; + class OnixSourceCanvas; -/** + /** - Used to change the number of data streams, and the - number of channels per stream. + Used to change the number of data streams, and the + number of channels per stream. -*/ -class OnixSourceEditor : public VisualizerEditor, - public Label::Listener, - public Button::Listener, - public TextEditor::Listener, - public ComboBox::Listener -{ -public: + */ + class OnixSourceEditor : public VisualizerEditor, + public Label::Listener, + public Button::Listener, + public TextEditor::Listener, + public ComboBox::Listener + { + public: - OnixSourceEditor(GenericProcessor* parentNode, OnixSource* source_); + OnixSourceEditor(GenericProcessor* parentNode, OnixSource* source_); - void labelTextChanged(Label* l) override; + void labelTextChanged(Label* l) override; - void buttonClicked(Button* b) override; + void buttonClicked(Button* b) override; - void comboBoxChanged(ComboBox* cb) override; + void comboBoxChanged(ComboBox* cb) override; - void updateComboBox(ComboBox* cb); + void updateComboBox(ComboBox* cb); - void updateSettings() override; + void updateSettings() override; - void setInterfaceEnabledState(bool newState); + void setInterfaceEnabledState(bool newState); - void startAcquisition() override; + void startAcquisition() override; - void stopAcquisition() override; + void stopAcquisition() override; - Visualizer* createNewCanvas(void) override; + Visualizer* createNewCanvas(void) override; - void saveVisualizerEditorParameters(XmlElement* xml) override; + void saveVisualizerEditorParameters(XmlElement* xml) override; - void loadVisualizerEditorParameters(XmlElement* xml) override; + void loadVisualizerEditorParameters(XmlElement* xml) override; - void checkCanvas() { checkForCanvas(); }; + void checkCanvas() { checkForCanvas(); }; - void resetCanvas(); + void resetCanvas(); - bool isHeadstageSelected(PortName port); + bool isHeadstageSelected(PortName port); - String getHeadstageSelected(int offset); + String getHeadstageSelected(int offset); - String getHeadstageSelected(PortName port); + String getHeadstageSelected(PortName port); - void refreshComboBoxSelection(); + void refreshComboBoxSelection(); - std::map createTabMapFromCanvas(); + std::map createTabMapFromCanvas(); - void setConnectedStatus(bool); + void setConnectedStatus(bool); -private: + private: - OnixSourceCanvas* canvas; - OnixSource* source; + OnixSourceCanvas* canvas; + OnixSource* source; const FillType fillDisconnected = FillType(Colours::transparentBlack); const FillType fillSearching = FillType(Colour::fromFloatRGBA(0.0f, 1.0f, 87.0f / 255, 1.0f)); const FillType fillConnected = FillType(Colour::fromFloatRGBA(184.0f / 255, 0.0f, 252.0f / 255, 1.0f)); - const Colour statusIndicatorStrokeColor = Colours::black; + const Colour statusIndicatorStrokeColor = Colours::black; - const float statusIndicatorStrokeThickness = 1.0f; + const float statusIndicatorStrokeThickness = 1.0f; - std::unique_ptr portStatusA; - std::unique_ptr portStatusB; + std::unique_ptr portStatusA; + std::unique_ptr portStatusB; - std::unique_ptr