Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 13 additions & 5 deletions Source/Devices/AnalogIO.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -22,11 +22,13 @@

#include "AnalogIO.h"

AnalogIO::AnalogIO(String name, const oni_dev_idx_t deviceIdx_, std::shared_ptr<Onix1> oni_ctx)
: OnixDevice(name, BREAKOUT_BOARD_NAME, OnixDeviceType::ANALOGIO, deviceIdx_, oni_ctx)
using namespace OnixSourcePlugin;

AnalogIO::AnalogIO(std::string name, std::string hubName, const oni_dev_idx_t deviceIdx_, std::shared_ptr<Onix1> oni_ctx)
: OnixDevice(name, hubName, AnalogIO::getDeviceType(), deviceIdx_, oni_ctx)
{
StreamInfo analogInputStream = StreamInfo(
OnixDevice::createStreamName({ getHeadstageName(), name, "AnalogInput" }),
OnixDevice::createStreamName({ getHubName(), name, "AnalogInput" }),
"Analog Input data",
getStreamIdentifier(),
getNumChannels(),
Expand All @@ -51,10 +53,16 @@ AnalogIO::AnalogIO(String name, const oni_dev_idx_t deviceIdx_, std::shared_ptr<
dataType = AnalogIODataType::Volts;
}

int AnalogIO::configureDevice()
OnixDeviceType AnalogIO::getDeviceType()
{
if (deviceContext == nullptr || !deviceContext->isInitialized()) return -1;
return OnixDeviceType::ANALOGIO;
}

int AnalogIO::configureDevice()
{
if (deviceContext == nullptr || !deviceContext->isInitialized())
throw error_str("Device context is not initialized properly for " + getName());

return deviceContext->writeRegister(deviceIdx, (uint32_t)AnalogIORegisters::ENABLE, (oni_reg_val_t)(isEnabled() ? 1 : 0));
}

Expand Down
249 changes: 127 additions & 122 deletions Source/Devices/AnalogIO.h
Original file line number Diff line number Diff line change
Expand Up @@ -24,168 +24,173 @@

#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<Onix1> 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(std::string name, std::string hubName, const oni_dev_idx_t, std::shared_ptr<Onix1> 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<DataBuffer>& sourceBuffers) override;
/** Given the sourceBuffers from OnixSource, add all streams for the current device to the array */
void addSourceBuffers(OwnedArray<DataBuffer>& 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];
}
void setChannelVoltageRange(int channelNumber, AnalogIOVoltageRange direction)
{
if (channelNumber > numChannels || channelNumber < 0)
{
LOGE("Channel number must be between 0 and " + String(channelNumber));
return;
}

AnalogIODataType getDataType() const { return dataType; }
channelVoltageRange[channelNumber] = direction;
}

int getNumChannels() { return numChannels; }
AnalogIODataType getDataType() const { return dataType; }

private:
void setDataType(AnalogIODataType type) { dataType = type; }

DataBuffer* analogInputBuffer = nullptr;
int getNumChannels() { return numChannels; }

static const int AnalogIOFrequencyHz = 100000;
static OnixDeviceType getDeviceType();

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<AnalogIODirection, numChannels> channelDirection;
std::array<AnalogIOVoltageRange, numChannels> 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<oni_frame_t*, CriticalSection, numFrames> 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<AnalogIODirection, numChannels> channelDirection;
std::array<AnalogIOVoltageRange, numChannels> channelVoltageRange;

bool shouldAddToBuffer = false;
AnalogIODataType dataType = AnalogIODataType::Volts;

std::array<float, numFrames* numChannels> analogInputSamples;
Array<oni_frame_t*, CriticalSection, numFrames> frameArray;

double timestamps[numFrames];
int64 sampleNumbers[numFrames];
uint64 eventCodes[numFrames];
unsigned short currentFrame = 0;
unsigned short currentAverageFrame = 0;
int sampleNumber = 0;

std::array<float, numChannels> voltsPerDivision;
bool shouldAddToBuffer = false;

static float getVoltsPerDivision(AnalogIOVoltageRange voltageRange);
std::array<float, numFrames* numChannels> 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<float, numChannels> voltsPerDivision;

void setDataType(AnalogIODataType type) { dataType = type; }
static float getVoltsPerDivision(AnalogIOVoltageRange voltageRange);

JUCE_LEAK_DETECTOR(AnalogIO);
};
JUCE_LEAK_DETECTOR(AnalogIO);
};
}
Loading