.. _program_listing_file_lib_dio_dio.cpp: Program Listing for File dio.cpp ================================ |exhale_lsh| :ref:`Return to documentation for file ` (``lib/dio/dio.cpp``) .. |exhale_lsh| unicode:: U+021B0 .. UPWARDS ARROW WITH TIP LEFTWARDS .. code-block:: 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 . // --------------------------------------------------------------------- #include "dio.hpp" #include "utilities/time.hpp" uint32_t DigitalState::nchannels() const { return state_.size(); } std::vector &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::reference DigitalState::operator[](uint32_t channel) { return state_[channel]; } std::vector DigitalState::state(std::vector channels) const { std::vector 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 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 values) { if (values.size() != nchannels()) { throw DigitalStateError("Incorrect size of vector."); } state_ = values; } void DigitalState::set_state(std::vector channels, std::vector 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 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 channels, DigitalOutputMode mode) { for (const uint32_t &c : channels) { if (c <= nchannels_) { mode_[c] = mode; } } } std::vector DigitalOutputProtocol::find_channels(DigitalOutputMode mode) { std::vector 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 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); } }