I2C: Network support
parent
13ec2bca98
commit
9817887523
|
|
@ -8,4 +8,5 @@ CMakeSettings.json
|
||||||
third-party/concurrentqueue/benchmarks
|
third-party/concurrentqueue/benchmarks
|
||||||
third-party/concurrentqueue/tests
|
third-party/concurrentqueue/tests
|
||||||
*.bak
|
*.bak
|
||||||
.vs
|
.vs
|
||||||
|
.cache
|
||||||
|
|
|
||||||
|
|
@ -182,6 +182,7 @@ set(SRC_FILES
|
||||||
communication/packet/ethphyregpacket.cpp
|
communication/packet/ethphyregpacket.cpp
|
||||||
communication/packet/logicaldiskinfopacket.cpp
|
communication/packet/logicaldiskinfopacket.cpp
|
||||||
communication/packet/wivicommandpacket.cpp
|
communication/packet/wivicommandpacket.cpp
|
||||||
|
communication/packet/i2cpacket.cpp
|
||||||
communication/packet/scriptstatuspacket.cpp
|
communication/packet/scriptstatuspacket.cpp
|
||||||
communication/decoder.cpp
|
communication/decoder.cpp
|
||||||
communication/encoder.cpp
|
communication/encoder.cpp
|
||||||
|
|
@ -389,6 +390,7 @@ if(LIBICSNEO_BUILD_TESTS)
|
||||||
test/diskdriverwritetest.cpp
|
test/diskdriverwritetest.cpp
|
||||||
test/eventmanagertest.cpp
|
test/eventmanagertest.cpp
|
||||||
test/ethernetpacketizertest.cpp
|
test/ethernetpacketizertest.cpp
|
||||||
|
test/i2cencoderdecodertest.cpp
|
||||||
)
|
)
|
||||||
|
|
||||||
target_link_libraries(libicsneo-tests gtest gtest_main)
|
target_link_libraries(libicsneo-tests gtest gtest_main)
|
||||||
|
|
|
||||||
|
|
@ -10,6 +10,7 @@
|
||||||
#include "icsneo/communication/message/scriptstatusmessage.h"
|
#include "icsneo/communication/message/scriptstatusmessage.h"
|
||||||
#include "icsneo/communication/message/a2bmessage.h"
|
#include "icsneo/communication/message/a2bmessage.h"
|
||||||
#include "icsneo/communication/message/flexray/control/flexraycontrolmessage.h"
|
#include "icsneo/communication/message/flexray/control/flexraycontrolmessage.h"
|
||||||
|
#include "icsneo/communication/message/i2cmessage.h"
|
||||||
#include "icsneo/communication/command.h"
|
#include "icsneo/communication/command.h"
|
||||||
#include "icsneo/device/device.h"
|
#include "icsneo/device/device.h"
|
||||||
#include "icsneo/communication/packet/canpacket.h"
|
#include "icsneo/communication/packet/canpacket.h"
|
||||||
|
|
@ -21,6 +22,7 @@
|
||||||
#include "icsneo/communication/packet/ethphyregpacket.h"
|
#include "icsneo/communication/packet/ethphyregpacket.h"
|
||||||
#include "icsneo/communication/packet/logicaldiskinfopacket.h"
|
#include "icsneo/communication/packet/logicaldiskinfopacket.h"
|
||||||
#include "icsneo/communication/packet/wivicommandpacket.h"
|
#include "icsneo/communication/packet/wivicommandpacket.h"
|
||||||
|
#include "icsneo/communication/packet/i2cpacket.h"
|
||||||
#include "icsneo/communication/packet/scriptstatuspacket.h"
|
#include "icsneo/communication/packet/scriptstatuspacket.h"
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
|
||||||
|
|
@ -122,6 +124,20 @@ bool Decoder::decode(std::shared_ptr<Message>& result, const std::shared_ptr<Pac
|
||||||
iso.network = packet->network;
|
iso.network = packet->network;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
case Network::Type::I2C: {
|
||||||
|
if(packet->data.size() < sizeof(HardwareI2CPacket)) {
|
||||||
|
report(APIEvent::Type::PacketDecodingError, APIEvent::Severity::Error);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
result = HardwareI2CPacket::DecodeToMessage(packet->data);
|
||||||
|
if(!result) {
|
||||||
|
report(APIEvent::Type::PacketDecodingError, APIEvent::Severity::Error);
|
||||||
|
return false; //malformed packet indicated by a nullptr return
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
case Network::Type::Internal: {
|
case Network::Type::Internal: {
|
||||||
switch(packet->network.getNetID()) {
|
switch(packet->network.getNetID()) {
|
||||||
case Network::NetID::Reset_Status: {
|
case Network::NetID::Reset_Status: {
|
||||||
|
|
|
||||||
|
|
@ -6,6 +6,8 @@
|
||||||
#include "icsneo/communication/packet/canpacket.h"
|
#include "icsneo/communication/packet/canpacket.h"
|
||||||
#include "icsneo/communication/packet/ethphyregpacket.h"
|
#include "icsneo/communication/packet/ethphyregpacket.h"
|
||||||
#include "icsneo/communication/message/ethphymessage.h"
|
#include "icsneo/communication/message/ethphymessage.h"
|
||||||
|
#include "icsneo/communication/packet/i2cpacket.h"
|
||||||
|
#include "icsneo/communication/message/i2cmessage.h"
|
||||||
|
|
||||||
using namespace icsneo;
|
using namespace icsneo;
|
||||||
|
|
||||||
|
|
@ -68,6 +70,18 @@ bool Encoder::encode(const Packetizer& packetizer, std::vector<uint8_t>& result,
|
||||||
// packets to the device. This function just encodes them back to back into `result`
|
// packets to the device. This function just encodes them back to back into `result`
|
||||||
return HardwareISO9141Packet::EncodeFromMessage(*isomsg, result, report, packetizer);
|
return HardwareISO9141Packet::EncodeFromMessage(*isomsg, result, report, packetizer);
|
||||||
} // End of Network::Type::ISO9141
|
} // End of Network::Type::ISO9141
|
||||||
|
case Network::Type::I2C: {
|
||||||
|
auto i2cmsg = std::dynamic_pointer_cast<I2CMessage>(message);
|
||||||
|
if(!i2cmsg) {
|
||||||
|
report(APIEvent::Type::MessageFormattingError, APIEvent::Severity::Error);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
buffer = &result;
|
||||||
|
if(!HardwareI2CPacket::EncodeFromMessage(*i2cmsg, result, report)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
default:
|
default:
|
||||||
report(APIEvent::Type::UnexpectedNetworkType, APIEvent::Severity::Error);
|
report(APIEvent::Type::UnexpectedNetworkType, APIEvent::Severity::Error);
|
||||||
return false;
|
return false;
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,83 @@
|
||||||
|
#include "icsneo/communication/packet/i2cpacket.h"
|
||||||
|
|
||||||
|
namespace icsneo
|
||||||
|
{
|
||||||
|
std::shared_ptr<Message> HardwareI2CPacket::DecodeToMessage(const std::vector<uint8_t>& bytestream)
|
||||||
|
{
|
||||||
|
auto msg = std::make_shared<I2CMessage>();
|
||||||
|
const I2CHeader* packet = reinterpret_cast<const I2CHeader*>(bytestream.data());
|
||||||
|
const size_t numPayloadBytes = packet->length;
|
||||||
|
const size_t numControlBytes = packet->CoreMiniBitsI2C.CBLen;
|
||||||
|
const size_t numDataBytes = numPayloadBytes - numControlBytes;
|
||||||
|
if( (numPayloadBytes == 0) || (numDataBytes > I2CMaxLength) ||
|
||||||
|
(sizeof(I2CHeader) != (bytestream.size() - numPayloadBytes)) )
|
||||||
|
{ return nullptr; }
|
||||||
|
|
||||||
|
msg->network = Network::GetNetIDFromCoreMiniNetwork(static_cast<Network::CoreMini>(packet->networkID));
|
||||||
|
msg->address = (packet->CoreMiniBitsI2C.ID & 0x3FFu);
|
||||||
|
msg->deviceMode = static_cast<I2CMessage::DeviceMode>(packet->CoreMiniBitsI2C.CT);
|
||||||
|
msg->direction = static_cast<I2CMessage::Direction>(packet->CoreMiniBitsI2C.DIR);
|
||||||
|
|
||||||
|
msg->isExtendedID = static_cast<bool>(packet->CoreMiniBitsI2C.EID & 0x01u);
|
||||||
|
msg->isTXMsg = static_cast<bool>(packet->CoreMiniBitsI2C.TXMsg & 0x01u);
|
||||||
|
msg->txTimeout = static_cast<bool>(packet->CoreMiniBitsI2C.TXTimeout & 0x01u);
|
||||||
|
msg->txNack = static_cast<bool>(packet->CoreMiniBitsI2C.TXNack & 0x01u);
|
||||||
|
msg->txAborted = static_cast<bool>(packet->CoreMiniBitsI2C.TXAborted & 0x01u);
|
||||||
|
msg->txLostArb = static_cast<bool>(packet->CoreMiniBitsI2C.TXLostArb & 0x01u);
|
||||||
|
msg->txError = static_cast<bool>(packet->CoreMiniBitsI2C.TXError & 0x01u);
|
||||||
|
//We don't care about 0xTRB0Dx in this case...
|
||||||
|
//copy 0xTRB0STAT even though we likely won't use it either
|
||||||
|
msg->stats = packet->stats;
|
||||||
|
msg->timestamp = (packet->timestamp & (0x7FFFFFFFFFFFFFFFull));
|
||||||
|
|
||||||
|
//The device will combine the 'control' bytes and data bytes into one payload
|
||||||
|
//The control bytes will always come before the data
|
||||||
|
auto cbStart = bytestream.begin() + sizeof(I2CHeader);
|
||||||
|
auto dataStart = cbStart + numControlBytes;
|
||||||
|
std::copy(cbStart, dataStart, std::back_inserter(msg->controlBytes));
|
||||||
|
std::copy(dataStart, bytestream.end(), std::back_inserter(msg->dataBytes));
|
||||||
|
|
||||||
|
return msg;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool HardwareI2CPacket::EncodeFromMessage(const I2CMessage& message, std::vector<uint8_t>& bytestream, const device_eventhandler_t& report)
|
||||||
|
{
|
||||||
|
const size_t numControlBytes = message.controlBytes.size();
|
||||||
|
const size_t numDataBytes = message.dataBytes.size();
|
||||||
|
if(I2CMaxLength < numDataBytes)
|
||||||
|
{
|
||||||
|
report(APIEvent::Type::I2CMessageExceedsMaxLength, APIEvent::Severity::Error);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if(message.controlBytes.empty() || message.dataBytes.empty())
|
||||||
|
{
|
||||||
|
//You'll need to provide a target R/W register in controlBytes
|
||||||
|
//alternatively, you're expecting to read without providing a dataBytes payload
|
||||||
|
report(APIEvent::Type::RequiredParameterNull, APIEvent::Severity::Error);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bytestream.push_back(static_cast<uint8_t>(numControlBytes & 0xFFu));
|
||||||
|
bytestream.push_back(static_cast<uint8_t>((numControlBytes) >> 8) & 0xFFu);
|
||||||
|
bytestream.push_back(static_cast<uint8_t>(numDataBytes & 0xFFu));
|
||||||
|
bytestream.push_back(static_cast<uint8_t>((numDataBytes) >> 8) & 0xFFu);
|
||||||
|
bytestream.push_back(static_cast<uint8_t>((message.stats) >> 8) & 0xFFu);
|
||||||
|
bytestream.push_back(static_cast<uint8_t>(message.stats & 0xFFu));
|
||||||
|
|
||||||
|
if(message.isExtendedID)
|
||||||
|
{
|
||||||
|
bytestream.push_back(static_cast<uint8_t>(message.address & 0xFFu));
|
||||||
|
bytestream.push_back(static_cast<uint8_t>(((message.address) >> 8) & 0x03u) | 0x04u);
|
||||||
|
} else {
|
||||||
|
bytestream.push_back(static_cast<uint8_t>(message.address & 0xFFu));
|
||||||
|
bytestream.push_back(static_cast<uint8_t>(0x00u));
|
||||||
|
}
|
||||||
|
|
||||||
|
if(I2CMessage::Direction::Read == message.direction)
|
||||||
|
{ bytestream.back() |= static_cast<uint8_t>(0x10u); }
|
||||||
|
|
||||||
|
std::copy(message.controlBytes.begin(), message.controlBytes.end(), std::back_inserter(bytestream));
|
||||||
|
std::copy(message.dataBytes.begin(), message.dataBytes.end(), std::back_inserter(bytestream));
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -89,6 +89,7 @@ public:
|
||||||
AtomicOperationCompletedNonatomically = 0x2035,
|
AtomicOperationCompletedNonatomically = 0x2035,
|
||||||
WiVIStackRefreshFailed = 0x2036,
|
WiVIStackRefreshFailed = 0x2036,
|
||||||
WiVIUploadStackOverflow = 0x2037,
|
WiVIUploadStackOverflow = 0x2037,
|
||||||
|
I2CMessageExceedsMaxLength = 0x2038,
|
||||||
|
|
||||||
// Transport Events
|
// Transport Events
|
||||||
FailedToRead = 0x3000,
|
FailedToRead = 0x3000,
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,48 @@
|
||||||
|
#ifndef __I2CMESSAGE_H_
|
||||||
|
#define __I2CMESSAGE_H_
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
|
||||||
|
#include "icsneo/communication/message/message.h"
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
namespace icsneo {
|
||||||
|
|
||||||
|
class I2CMessage : public Frame {
|
||||||
|
public:
|
||||||
|
enum class DeviceMode : uint8_t {
|
||||||
|
Target = 0,
|
||||||
|
Controller = 1
|
||||||
|
};
|
||||||
|
|
||||||
|
enum class Direction : uint8_t {
|
||||||
|
Write = 0,
|
||||||
|
Read = 1
|
||||||
|
};
|
||||||
|
|
||||||
|
bool isExtendedID = false;
|
||||||
|
bool isTXMsg = false;
|
||||||
|
bool txError = false;
|
||||||
|
bool txLostArb = false;
|
||||||
|
bool txAborted = false;
|
||||||
|
bool txNack = false;
|
||||||
|
bool txTimeout = false;
|
||||||
|
uint16_t stats = static_cast<uint16_t>(0x0000u);
|
||||||
|
uint16_t address;
|
||||||
|
Direction direction;
|
||||||
|
DeviceMode deviceMode;
|
||||||
|
|
||||||
|
//Must contain the target register address to read or write
|
||||||
|
std::vector<uint8_t> controlBytes;
|
||||||
|
|
||||||
|
//The device expects a dataBytes payload even if you're reading
|
||||||
|
//In the case of a read these bytes aren't interesting, but they have to be there
|
||||||
|
//Add bytes to write, or the same number of junk bytes you expect the device send back
|
||||||
|
std::vector<uint8_t> dataBytes;
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif // __cplusplus
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
@ -0,0 +1,61 @@
|
||||||
|
#ifndef __I2CPACKET_H__
|
||||||
|
#define __I2CPACKET_H__
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
|
||||||
|
#include "icsneo/communication/message/i2cmessage.h"
|
||||||
|
#include "icsneo/api/eventmanager.h"
|
||||||
|
#include "icsneo/communication/packetizer.h"
|
||||||
|
#include "icsneo/communication/network.h"
|
||||||
|
#include <cstdint>
|
||||||
|
#include <memory>
|
||||||
|
|
||||||
|
namespace icsneo {
|
||||||
|
|
||||||
|
static constexpr size_t I2CMaxLength = 1024u;
|
||||||
|
|
||||||
|
#pragma pack(push, 2)
|
||||||
|
|
||||||
|
struct I2CHeader {
|
||||||
|
struct {
|
||||||
|
// C1xI2C
|
||||||
|
uint16_t ID : 10;// i2c address, 7-bit or 10-bit
|
||||||
|
uint16_t EID : 1;// using extended addressing, i.e. 10-bit
|
||||||
|
uint16_t CT : 1;// Controller/Target
|
||||||
|
uint16_t DIR : 1;// read/write
|
||||||
|
uint16_t RESERVED_0 : 3;
|
||||||
|
|
||||||
|
// C2xI2C
|
||||||
|
uint16_t TXMsg: 1;
|
||||||
|
uint16_t CBLen: 11;
|
||||||
|
uint16_t RESERVED_1: 4;
|
||||||
|
|
||||||
|
// C3xI2C
|
||||||
|
uint16_t TXTimeout : 1;
|
||||||
|
uint16_t TXNack : 1;
|
||||||
|
uint16_t TXAborted : 1;
|
||||||
|
uint16_t TXLostArb : 1;
|
||||||
|
uint16_t TXError : 1;
|
||||||
|
uint16_t RESERVED_2: 11;
|
||||||
|
} CoreMiniBitsI2C;
|
||||||
|
|
||||||
|
uint8_t coreMiniMessageData[8];
|
||||||
|
uint16_t stats;
|
||||||
|
|
||||||
|
uint64_t timestamp;
|
||||||
|
|
||||||
|
uint16_t networkID;
|
||||||
|
uint16_t length;
|
||||||
|
};
|
||||||
|
|
||||||
|
#pragma pack(pop)
|
||||||
|
|
||||||
|
struct HardwareI2CPacket {
|
||||||
|
static std::shared_ptr<Message> DecodeToMessage(const std::vector<uint8_t>& bytestream);
|
||||||
|
static bool EncodeFromMessage(const I2CMessage& message, std::vector<uint8_t>& bytestream, const device_eventhandler_t& report);
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif //_cplusplus
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
@ -28,7 +28,10 @@ public:
|
||||||
Network::NetID::LIN,
|
Network::NetID::LIN,
|
||||||
|
|
||||||
Network::NetID::A2B1,
|
Network::NetID::A2B1,
|
||||||
Network::NetID::A2B2
|
Network::NetID::A2B2,
|
||||||
|
|
||||||
|
Network::NetID::I2C,
|
||||||
|
Network::NetID::I2C2
|
||||||
};
|
};
|
||||||
return supportedNetworks;
|
return supportedNetworks;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -59,7 +59,12 @@ protected:
|
||||||
|
|
||||||
Network::NetID::LIN,
|
Network::NetID::LIN,
|
||||||
|
|
||||||
Network::NetID::FlexRay
|
Network::NetID::FlexRay,
|
||||||
|
|
||||||
|
Network::NetID::I2C,
|
||||||
|
Network::NetID::I2C2,
|
||||||
|
Network::NetID::I2C3,
|
||||||
|
Network::NetID::I2C4,
|
||||||
};
|
};
|
||||||
rxNetworks.insert(rxNetworks.end(), supportedRxNetworks.begin(), supportedRxNetworks.end());
|
rxNetworks.insert(rxNetworks.end(), supportedRxNetworks.begin(), supportedRxNetworks.end());
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -16,6 +16,7 @@
|
||||||
#include "icsneo/communication/message/iso9141message.h"
|
#include "icsneo/communication/message/iso9141message.h"
|
||||||
#include "icsneo/communication/message/canerrorcountmessage.h"
|
#include "icsneo/communication/message/canerrorcountmessage.h"
|
||||||
#include "icsneo/communication/message/ethphymessage.h"
|
#include "icsneo/communication/message/ethphymessage.h"
|
||||||
|
#include "icsneo/communication/message/i2cmessage.h"
|
||||||
#include "icsneo/communication/message/a2bmessage.h"
|
#include "icsneo/communication/message/a2bmessage.h"
|
||||||
|
|
||||||
namespace icsneo {
|
namespace icsneo {
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,90 @@
|
||||||
|
#include "icsneo/icsneocpp.h"
|
||||||
|
#include "icsneo/communication/encoder.h"
|
||||||
|
#include "icsneo/communication/packet/i2cpacket.h"
|
||||||
|
#include "icsneo/communication/message/i2cmessage.h"
|
||||||
|
#include "icsneo/communication/packetizer.h"
|
||||||
|
#include "icsneo/api/eventmanager.h"
|
||||||
|
#include "gtest/gtest.h"
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
using namespace icsneo;
|
||||||
|
|
||||||
|
class I2CEncoderDecoderTest : public ::testing::Test {
|
||||||
|
protected:
|
||||||
|
void SetUp() override {
|
||||||
|
report = [](APIEvent::Type, APIEvent::Severity) {
|
||||||
|
// Unless caught by the test, the packetizer should not throw errors
|
||||||
|
EXPECT_TRUE(false);
|
||||||
|
};
|
||||||
|
packetizer.emplace([this](APIEvent::Type t, APIEvent::Severity s) {
|
||||||
|
report(t, s);
|
||||||
|
});
|
||||||
|
packetEncoder.emplace([this](APIEvent::Type t, APIEvent::Severity s) {
|
||||||
|
report(t, s);
|
||||||
|
});
|
||||||
|
packetDecoder.emplace([this](APIEvent::Type t, APIEvent::Severity s) {
|
||||||
|
report(t, s);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
device_eventhandler_t report;
|
||||||
|
std::optional<Encoder> packetEncoder;
|
||||||
|
std::optional<Packetizer> packetizer;
|
||||||
|
std::optional<Decoder> packetDecoder;
|
||||||
|
//Read request to the device
|
||||||
|
//Control length 1, control bytes 0x12 (I2C register to read from)
|
||||||
|
//data length 1: blank bytes padded in that the device will fill in the reply
|
||||||
|
std::vector<uint8_t> testBytes =
|
||||||
|
{0xaa, 0x0c, 0x11, 0x00, 0x58, 0x00, 0x01, 0x00,
|
||||||
|
0x01, 0x00, 0x00, 0x01, 0x68, 0x10, 0x12, 0x00};
|
||||||
|
|
||||||
|
std::vector<uint8_t> recvBytes =
|
||||||
|
{0xaa, 0x0c, 0x24,0x00, 0x58, 0x00, 0x68, 0x18,
|
||||||
|
0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x97, 0x29,
|
||||||
|
0xe6, 0xfb, 0xc1, 0xfc, 0xb0, 0x80, 0x35, 0x00,
|
||||||
|
0x02, 0x00, 0x12, 0x80};
|
||||||
|
};
|
||||||
|
|
||||||
|
TEST_F(I2CEncoderDecoderTest, PacketEncoderTest) {
|
||||||
|
std::vector<uint8_t> bytestream;
|
||||||
|
auto message = std::make_shared<icsneo::I2CMessage>();
|
||||||
|
message->network = icsneo::Network::NetID::I2C;
|
||||||
|
message->controlBytes.push_back(static_cast<uint8_t>(0x12u)); //Product ID register address
|
||||||
|
message->dataBytes.push_back(static_cast<uint8_t>(0x00u));
|
||||||
|
message->address = 0x68u; //7 bit addressing, BASE_ADDR
|
||||||
|
message->stats = static_cast<uint16_t>(0x0001u);
|
||||||
|
message->direction = I2CMessage::Direction::Read;
|
||||||
|
message->isTXMsg = true;
|
||||||
|
packetEncoder->encode(*packetizer, bytestream, message);
|
||||||
|
EXPECT_EQ(bytestream, testBytes);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(I2CEncoderDecoderTest, PacketDecoderTest) {
|
||||||
|
std::shared_ptr<icsneo::Message> decodeMsg;
|
||||||
|
std::shared_ptr<icsneo::I2CMessage> message = std::make_shared<icsneo::I2CMessage>();
|
||||||
|
|
||||||
|
message->network = icsneo::Network::NetID::I2C;
|
||||||
|
message->controlBytes.push_back(static_cast<uint8_t>(0x12u)); //Product ID register address
|
||||||
|
message->dataBytes.push_back(static_cast<uint8_t>(0x80u));
|
||||||
|
message->address = 0x68u; //7 bit addressing, BASE_ADDR
|
||||||
|
message->stats = static_cast<uint16_t>(0x0002u);
|
||||||
|
message->direction = I2CMessage::Direction::Read;
|
||||||
|
message->deviceMode = I2CMessage::DeviceMode::Controller;
|
||||||
|
message->isTXMsg = true;
|
||||||
|
message->timestamp = static_cast<uint64_t>(0xB0FCC1FBE62997);
|
||||||
|
|
||||||
|
EXPECT_TRUE(packetizer->input(recvBytes));
|
||||||
|
auto packets = packetizer->output();
|
||||||
|
if(packets.empty()) { EXPECT_TRUE(false); }
|
||||||
|
EXPECT_TRUE(packetDecoder->decode(decodeMsg, packets.back()));
|
||||||
|
auto testMessage = std::dynamic_pointer_cast<icsneo::I2CMessage>(decodeMsg);
|
||||||
|
EXPECT_EQ(message->network, testMessage->network);
|
||||||
|
EXPECT_EQ(message->controlBytes, testMessage->controlBytes);
|
||||||
|
EXPECT_EQ(message->dataBytes, testMessage->dataBytes);
|
||||||
|
EXPECT_EQ(message->address, testMessage->address);
|
||||||
|
EXPECT_EQ(message->stats, testMessage->stats);
|
||||||
|
EXPECT_EQ(message->direction, testMessage->direction);
|
||||||
|
EXPECT_EQ(message->deviceMode, testMessage->deviceMode);
|
||||||
|
EXPECT_EQ(message->isTXMsg, testMessage->isTXMsg);
|
||||||
|
EXPECT_EQ(message->timestamp, testMessage->timestamp);
|
||||||
|
}
|
||||||
Loading…
Reference in New Issue