neoVI FIRE 2: MiscIO and EMiscIO Support
parent
92589c2ce7
commit
bb322ad190
|
|
@ -118,6 +118,26 @@ bool Decoder::decode(std::shared_ptr<Message>& result, const std::shared_ptr<Pac
|
|||
result = msg;
|
||||
return true;
|
||||
}
|
||||
case Network::NetID::Device: {
|
||||
// These are neoVI network messages
|
||||
// They come in as CAN but we will handle them in the device rather than
|
||||
// passing them onto the user.
|
||||
if(packet->data.size() < 24) {
|
||||
report(APIEvent::Type::PacketDecodingError, APIEvent::Severity::Error);
|
||||
return false;
|
||||
}
|
||||
|
||||
result = HardwareCANPacket::DecodeToMessage(packet->data);
|
||||
if(!result) {
|
||||
report(APIEvent::Type::PacketDecodingError, APIEvent::Severity::Error);
|
||||
return false; // A nullptr was returned, the packet was malformed
|
||||
}
|
||||
// Timestamps are in (resolution) ns increments since 1/1/2007 GMT 00:00:00.0000
|
||||
// The resolution depends on the device
|
||||
result->timestamp *= timestampResolution;
|
||||
result->network = packet->network;
|
||||
return true;
|
||||
}
|
||||
case Network::NetID::DeviceStatus: {
|
||||
result = std::make_shared<Message>();
|
||||
result->network = packet->network;
|
||||
|
|
|
|||
|
|
@ -470,6 +470,46 @@ optional<bool> Device::getDigitalIO(IO type, size_t number /* = 1 */) {
|
|||
report(APIEvent::Type::ValueNotYetPresent, APIEvent::Severity::Error);
|
||||
|
||||
return backupPowerGood;
|
||||
case IO::Misc: {
|
||||
bool found = false;
|
||||
for(const auto& misc : getMiscIO()) {
|
||||
if(misc.number == number) {
|
||||
found = misc.supportsDigitalIn;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if(!found)
|
||||
break; // ParameterOutOfRange
|
||||
|
||||
if(number > miscDigital.size())
|
||||
break; // ParameterOutOfRange
|
||||
|
||||
if(!miscDigital[number - 1].has_value())
|
||||
report(APIEvent::Type::ValueNotYetPresent, APIEvent::Severity::Error);
|
||||
|
||||
return miscDigital[number - 1];
|
||||
}
|
||||
case IO::EMisc: {
|
||||
bool found = false;
|
||||
for(const auto& misc : getEMiscIO()) {
|
||||
if(misc.number == number) {
|
||||
found = misc.supportsDigitalIn;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if(!found)
|
||||
break; // ParameterOutOfRange
|
||||
|
||||
if(number > miscDigital.size())
|
||||
break; // ParameterOutOfRange
|
||||
|
||||
// If there is ever a device with overlapping misc IOs and emisc IOs,
|
||||
// you will need to make a new member variable for the emisc IOs.
|
||||
if(!miscDigital[number - 1].has_value())
|
||||
report(APIEvent::Type::ValueNotYetPresent, APIEvent::Severity::Error);
|
||||
|
||||
return miscDigital[number - 1];
|
||||
}
|
||||
};
|
||||
|
||||
report(APIEvent::Type::ParameterOutOfRange, APIEvent::Severity::Error);
|
||||
|
|
@ -522,12 +562,74 @@ bool Device::setDigitalIO(IO type, size_t number, bool value) {
|
|||
});
|
||||
case IO::BackupPowerGood:
|
||||
break; // Read-only, return ParameterOutOfRange
|
||||
case IO::Misc:
|
||||
case IO::EMisc:
|
||||
break; // Read-only for the moment, return ParameterOutOfRange
|
||||
};
|
||||
|
||||
report(APIEvent::Type::ParameterOutOfRange, APIEvent::Severity::Error);
|
||||
return false;
|
||||
}
|
||||
|
||||
optional<double> Device::getAnalogIO(IO type, size_t number /* = 1 */) {
|
||||
if(number == 0) { // Start counting from 1
|
||||
report(APIEvent::Type::ParameterOutOfRange, APIEvent::Severity::Error);
|
||||
return false;
|
||||
}
|
||||
|
||||
std::lock_guard<std::mutex> lk(ioMutex);
|
||||
switch(type) {
|
||||
case IO::EthernetActivation:
|
||||
case IO::USBHostPower:
|
||||
case IO::BackupPowerEnabled:
|
||||
case IO::BackupPowerGood:
|
||||
break;
|
||||
case IO::Misc: {
|
||||
bool found = false;
|
||||
for(const auto& misc : getMiscIO()) {
|
||||
if(misc.number == number) {
|
||||
found = misc.supportsAnalogIn;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if(!found)
|
||||
break; // ParameterOutOfRange
|
||||
|
||||
if(number > miscAnalog.size())
|
||||
break; // ParameterOutOfRange
|
||||
|
||||
if(!miscAnalog[number - 1].has_value())
|
||||
report(APIEvent::Type::ValueNotYetPresent, APIEvent::Severity::Error);
|
||||
|
||||
return miscAnalog[number - 1];
|
||||
}
|
||||
case IO::EMisc: {
|
||||
bool found = false;
|
||||
for(const auto& misc : getEMiscIO()) {
|
||||
if(misc.number == number) {
|
||||
found = misc.supportsAnalogIn;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if(!found)
|
||||
break; // ParameterOutOfRange
|
||||
|
||||
if(number > miscAnalog.size())
|
||||
break; // ParameterOutOfRange
|
||||
|
||||
// If there is ever a device with overlapping misc IOs and emisc IOs,
|
||||
// you will need to make a new member variable for the emisc IOs.
|
||||
if(!miscAnalog[number - 1].has_value())
|
||||
report(APIEvent::Type::ValueNotYetPresent, APIEvent::Severity::Error);
|
||||
|
||||
return miscAnalog[number - 1];
|
||||
}
|
||||
};
|
||||
|
||||
report(APIEvent::Type::ParameterOutOfRange, APIEvent::Severity::Error);
|
||||
return nullopt;
|
||||
}
|
||||
|
||||
void Device::addExtension(std::shared_ptr<DeviceExtension>&& extension) {
|
||||
std::lock_guard<std::mutex> lk(extensionsLock);
|
||||
extensions.push_back(extension);
|
||||
|
|
@ -552,6 +654,12 @@ void Device::handleInternalMessage(std::shared_ptr<Message> message) {
|
|||
case Network::NetID::Reset_Status:
|
||||
latestResetStatus = std::dynamic_pointer_cast<ResetStatusMessage>(message);
|
||||
break;
|
||||
case Network::NetID::Device: {
|
||||
auto canmsg = std::dynamic_pointer_cast<CANMessage>(message);
|
||||
if(canmsg)
|
||||
handleNeoVIMessage(std::move(canmsg));
|
||||
break;
|
||||
}
|
||||
case Network::NetID::DeviceStatus:
|
||||
// Device Status format is unique per device, so the devices need to decode it themselves
|
||||
handleDeviceStatus(message);
|
||||
|
|
@ -565,6 +673,27 @@ void Device::handleInternalMessage(std::shared_ptr<Message> message) {
|
|||
});
|
||||
}
|
||||
|
||||
void Device::handleNeoVIMessage(std::shared_ptr<CANMessage> message) {
|
||||
switch(message->arbid) {
|
||||
case 0x103: { // Report Message (neoVI FIRE 2)
|
||||
if(message->data.size() < 34) {
|
||||
report(APIEvent::Type::PacketDecodingError, APIEvent::Severity::EventWarning);
|
||||
return;
|
||||
}
|
||||
|
||||
uint16_t emisc[2];
|
||||
memcpy(emisc, message->data.data() + 24, sizeof(emisc));
|
||||
std::lock_guard<std::mutex> lk(ioMutex);
|
||||
miscAnalog[0] = (message->data[24] | (uint16_t(message->data[25]) << 8)) * 0.01015511; // In volts now
|
||||
miscAnalog[1] = (message->data[26] | (uint16_t(message->data[27]) << 8)) * 0.01015511;
|
||||
miscDigital[0] = message->data[28] & 0x01;
|
||||
miscDigital[1] = message->data[29] & 0x01;
|
||||
miscDigital[4] = message->data[30] & 0x01;
|
||||
miscDigital[5] = message->data[31] & 0x01;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Device::updateLEDState() {
|
||||
std::vector<uint8_t> args {(uint8_t) ledState};
|
||||
com->sendCommand(Command::UpdateLEDState, args);
|
||||
|
|
|
|||
|
|
@ -249,6 +249,19 @@ int main() {
|
|||
ret = device->transmit(ethTxMessage); // This will return false if the device does not support OP (BR) Ethernet 2
|
||||
std::cout << (ret ? "OK" : "FAIL") << std::endl;
|
||||
|
||||
std::vector<icsneo::MiscIO> emisc = device->getEMiscIO();
|
||||
if(!emisc.empty()) {
|
||||
std::cout << "\tReading EMisc values..." << std::endl;
|
||||
for(const auto& io : emisc) {
|
||||
icsneo::optional<double> val = device->getAnalogIO(icsneo::IO::EMisc, io.number);
|
||||
std::cout << "\t\tEMISC" << io.number;
|
||||
if(val.has_value())
|
||||
std::cout << " - OK (" << val.value() << "V)" << std::endl;
|
||||
else
|
||||
std::cout << " - FAIL, it may need to be enabled in neoVI Explorer (" << icsneo::GetLastError() << ")" << std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(50));
|
||||
|
||||
// Go offline, stop sending and receiving traffic
|
||||
|
|
|
|||
|
|
@ -1,15 +1,30 @@
|
|||
#ifndef __ICSNEO_IO_H_
|
||||
#define __ICSNEO_IO_H_
|
||||
|
||||
typedef struct _neomiscio_t {
|
||||
size_t number;
|
||||
bool supportsDigitalIn;
|
||||
bool supportsDigitalOut;
|
||||
bool supportsAnalogIn;
|
||||
#ifdef __cplusplus
|
||||
_neomiscio_t(size_t n, bool dIn = false, bool dOut = false, bool aIn = false)
|
||||
: number(n), supportsDigitalIn(dIn), supportsDigitalOut(dOut), supportsAnalogIn(aIn) {}
|
||||
#endif
|
||||
} neomiscio_t;
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
||||
namespace icsneo {
|
||||
|
||||
using MiscIO = neomiscio_t;
|
||||
|
||||
enum class IO {
|
||||
EthernetActivation = 0, // The DoIP activation line, 0 is HiZ and 1 is pulled up to VBAT
|
||||
USBHostPower = 1,
|
||||
BackupPowerEnabled = 2, // The FIRE 2's backup super capacitor
|
||||
BackupPowerGood = 3, // Whether or not the FIRE 2's backup super capacitor is charged (read only)
|
||||
Misc = 4, // General purpose IO on the device
|
||||
EMisc = 5, // Extended general purpose IO on the device
|
||||
};
|
||||
|
||||
// Note that the C API does a static cast between this and neoio_t so keep them in sync!
|
||||
|
|
@ -24,6 +39,8 @@ typedef enum _neoio_t {
|
|||
ICSNEO_IO_USB_HOST_POWER = (1),
|
||||
ICSNEO_IO_BACKUP_POWER_EN = (2),
|
||||
ICSNEO_IO_BACKUP_POWER_GOOD = (3),
|
||||
ICSNEO_IO_MISC = (4),
|
||||
ICSNEO_IO_EMISC = (5),
|
||||
} neoio_t;
|
||||
#endif
|
||||
|
||||
|
|
|
|||
|
|
@ -263,6 +263,7 @@ public:
|
|||
case NetID::MOST150:
|
||||
return Type::MOST;
|
||||
case NetID::RED:
|
||||
case NetID::Device:
|
||||
case NetID::Reset_Status:
|
||||
case NetID::DeviceStatus:
|
||||
case NetID::FlexRayControl:
|
||||
|
|
@ -309,7 +310,7 @@ public:
|
|||
static const char* GetNetIDString(NetID netid) {
|
||||
switch(netid) {
|
||||
case NetID::Device:
|
||||
return "Device";
|
||||
return "neoVI";
|
||||
case NetID::HSCAN:
|
||||
return "HSCAN";
|
||||
case NetID::MSCAN:
|
||||
|
|
|
|||
|
|
@ -107,6 +107,18 @@ public:
|
|||
*/
|
||||
virtual bool getBackupPowerSupported() const { return false; }
|
||||
|
||||
/**
|
||||
* Retrieve the information about the misc IOs present on this
|
||||
* device.
|
||||
*/
|
||||
virtual std::vector<MiscIO> getMiscIO() const { return {}; }
|
||||
|
||||
/**
|
||||
* Retrieve the information about the emisc IOs present on this
|
||||
* device.
|
||||
*/
|
||||
virtual std::vector<MiscIO> getEMiscIO() const { return {}; }
|
||||
|
||||
/**
|
||||
* Get the value of a digital IO, returning an empty optional if the
|
||||
* value is not present, the specified IO is not valid for this device,
|
||||
|
|
@ -131,6 +143,16 @@ public:
|
|||
*/
|
||||
bool setDigitalIO(IO type, bool value) { return setDigitalIO(type, 1, value); }
|
||||
|
||||
/**
|
||||
* Get the value of an analog IO, returning an empty optional if the
|
||||
* value is not present, the specified IO is not valid for this device,
|
||||
* or if an error occurs.
|
||||
*
|
||||
* The index number starts counting at 1 to keep the numbers in sync
|
||||
* with the numbering on the device, and is set to 1 by default.
|
||||
*/
|
||||
optional<double> getAnalogIO(IO type, size_t number = 1);
|
||||
|
||||
virtual std::vector<std::shared_ptr<FlexRay::Controller>> getFlexRayControllers() const { return {}; }
|
||||
|
||||
const device_eventhandler_t& getEventHandler() const { return report; }
|
||||
|
|
@ -150,6 +172,8 @@ protected:
|
|||
optional<bool> usbHostPowerStatus;
|
||||
optional<bool> backupPowerEnabled;
|
||||
optional<bool> backupPowerGood;
|
||||
std::array<optional<bool>, 6> miscDigital;
|
||||
std::array<optional<double>, 2> miscAnalog;
|
||||
|
||||
// START Initialization Functions
|
||||
Device(neodevice_t neodevice = { 0 }) {
|
||||
|
|
@ -251,6 +275,8 @@ private:
|
|||
std::vector<Network> supportedTXNetworks;
|
||||
std::vector<Network> supportedRXNetworks;
|
||||
|
||||
void handleNeoVIMessage(std::shared_ptr<CANMessage> message);
|
||||
|
||||
enum class LEDState : uint8_t {
|
||||
Offline = 0x04,
|
||||
CoreMiniRunning = 0x08, // This should override "offline" if the CoreMini is running
|
||||
|
|
|
|||
|
|
@ -73,6 +73,18 @@ public:
|
|||
size_t getEthernetActivationLineCount() const override { return 1; }
|
||||
size_t getUSBHostPowerCount() const override { return 1; }
|
||||
bool getBackupPowerSupported() const override { return true; }
|
||||
std::vector<MiscIO> getMiscIO() const override {
|
||||
return {
|
||||
{5, true, true, false},
|
||||
{6, true, true, false}
|
||||
};
|
||||
}
|
||||
std::vector<MiscIO> getEMiscIO() const override {
|
||||
return {
|
||||
{1, true, true, true},
|
||||
{2, true, true, true}
|
||||
};
|
||||
}
|
||||
|
||||
protected:
|
||||
NeoVIFIRE2(neodevice_t neodevice) : Device(neodevice) {
|
||||
|
|
|
|||
Loading…
Reference in New Issue