Program Listing for File dio.cpp¶
↰ Return to documentation for file (lib/dio/dio.cpp
)
// ---------------------------------------------------------------------
// This file is part of falcon-core.
//
// Copyright (C) 2015, 2016, 2017 Neuro-Electronics Research Flanders
//
// Falcon-server 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.
//
// Falcon-server 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 falcon-core. If not, see <http://www.gnu.org/licenses/>.
// ---------------------------------------------------------------------
#include "dio.hpp"
#include "utilities/time.hpp"
uint32_t DigitalState::nchannels() const { return state_.size(); }
std::vector<bool> &DigitalState::state() { return state_; }
bool DigitalState::state(uint32_t channel) const {
if (channel >= nchannels()) {
throw DigitalStateError("Invalid channel number.");
}
return state_[channel];
}
typename std::vector<bool>::reference
DigitalState::operator[](uint32_t channel) {
return state_[channel];
}
std::vector<bool> DigitalState::state(std::vector<uint32_t> channels) const {
std::vector<bool> ret;
for (auto &it : channels) {
if (it >= nchannels()) {
throw DigitalStateError("Invalid channel number");
}
ret.push_back(state_[it]);
}
return ret;
}
void DigitalState::set_state(uint32_t channel, bool value) {
if (channel >= nchannels()) {
throw DigitalStateError("Invalid channel number.");
}
state_[channel] = value;
}
void DigitalState::set_state(std::vector<uint32_t> channels, bool value) {
for (auto &it : channels) {
if (it >= nchannels()) {
continue;
} // fail silently
state_[it] = value;
}
}
void DigitalState::set_state(bool value) { state_.assign(nchannels(), value); }
void DigitalState::set_state(std::vector<bool> values) {
if (values.size() != nchannels()) {
throw DigitalStateError("Incorrect size of vector.");
}
state_ = values;
}
void DigitalState::set_state(std::vector<uint32_t> channels,
std::vector<bool> values) {
if (channels.size() != values.size()) {
throw DigitalStateError("Incompatible size of vectors.");
}
for (unsigned int k = 0; k < channels.size(); ++k) {
if (channels[k] >= nchannels()) {
continue;
} // fail silently
state_[channels[k]] = values[k];
}
}
void DigitalState::toggle_state(uint32_t channel) {
set_state(channel, !state(channel));
}
void DigitalState::toggle_state(std::vector<uint32_t> channels) {
for (auto &it : channels) {
if (it >= nchannels()) {
continue;
} // fail silently
state_[it] = !state_[it];
}
}
std::string DigitalState::to_string(std::string high, std::string low,
std::string spacer) const {
std::string s = "";
for (uint32_t k = 0; k < nchannels(); ++k) {
if (k > 0) {
s += spacer;
}
s += state_[k] ? high : low;
}
return s;
}
std::string DigitalDevice::type() const { return type_; }
std::string DigitalDevice::description() const {
return type() + " (" + std::to_string(nchannels()) + " channels)";
}
DigitalOutputProtocol::DigitalOutputProtocol(uint32_t nchannels,
unsigned int pulse_width,
DigitalOutputMode default_mode)
: nchannels_(nchannels), pulse_width_(pulse_width) {
mode_.assign(nchannels_, default_mode);
}
void DigitalOutputProtocol::set_mode(uint32_t channel, DigitalOutputMode mode) {
if (channel <= nchannels_) { // fail silently
mode_[channel] = mode;
}
}
unsigned int DigitalOutputProtocol::pulse_width() const { return pulse_width_; }
void DigitalOutputProtocol::set_pulse_width(unsigned int value) {
pulse_width_ = value;
}
void DigitalOutputProtocol::set_mode(std::vector<uint32_t> channels,
DigitalOutputMode mode) {
for (const uint32_t &c : channels) {
if (c <= nchannels_) {
mode_[c] = mode;
}
}
}
std::vector<uint32_t>
DigitalOutputProtocol::find_channels(DigitalOutputMode mode) {
std::vector<uint32_t> channels;
for (uint32_t k = 0; k < mode_.size(); ++k) {
if (mode_[k] == mode) {
channels.push_back(k);
}
}
return channels;
}
void DigitalOutputProtocol::execute(DigitalDevice &device) {
DigitalState state(nchannels_);
std::vector<uint32_t> channels;
state = device.read_state();
channels = find_channels(DigitalOutputMode::HIGH);
state.set_state(channels, true);
channels = find_channels(DigitalOutputMode::LOW);
state.set_state(channels, false);
channels = find_channels(DigitalOutputMode::TOGGLE);
state.toggle_state(channels);
channels = find_channels(DigitalOutputMode::PULSE);
state.set_state(channels, true);
device.write_state(state);
if (channels.size() > 0) { // some channels are pulsed
custom_sleep_for(pulse_width_);
state.set_state(channels, false);
device.write_state(state);
}
}