Properly decode incoming FlexRayPackets

pull/25/head
Paul Hollinsky 2019-11-18 06:09:25 +01:00
parent 31062dd928
commit 4821a957dd
4 changed files with 74 additions and 62 deletions

View File

@ -16,13 +16,20 @@ std::shared_ptr<FlexRayMessage> HardwareFlexRayPacket::DecodeToMessage(const std
// Always get the frame length, even for a symbol // Always get the frame length, even for a symbol
msg->framelen = data->frame_length_12_5ns * 12.5e-9; msg->framelen = data->frame_length_12_5ns * 12.5e-9;
msg->channel = data->statusBits.bits.chb ? icsneo::FlexRay::Channel::B : icsneo::FlexRay::Channel::A;
if(data->tss_length_12_5ns == 0xffff) {// Flag value meaning this is a symbol if(data->tss_length_12_5ns == 0xffff) {// Flag value meaning this is a symbol
msg->symbol = FlexRay::Symbol::Unknown; // We can't know the symbol yet because this will depend on the baudrate // These values are only for 10Mbit
// Eventually we'll have to get this from the framelen // That's the only baudrate supported for now
if (data->frame_length_12_5ns > 480)
msg->symbol = FlexRay::Symbol::Wakeup;
else if (data->frame_length_12_5ns > 264)
msg->symbol = FlexRay::Symbol::CAS;
else
msg->symbol = FlexRay::Symbol::Unknown;
} else { } else {
msg->tsslen = data->tss_length_12_5ns * 12.5e-9; msg->tsslen = data->tss_length_12_5ns * 12.5e-9;
msg->channel = data->statusBits.bits.chb ? icsneo::FlexRay::Channel::B : icsneo::FlexRay::Channel::A;
if(data->statusBits.bits.bytesRxed >= 5) { if(data->statusBits.bits.bytesRxed >= 5) {
if(data->statusBits.bits.hcrc_error) if(data->statusBits.bits.hcrc_error)
msg->headerCRCStatus = FlexRay::CRCStatus::Error; msg->headerCRCStatus = FlexRay::CRCStatus::Error;
@ -43,14 +50,16 @@ std::shared_ptr<FlexRayMessage> HardwareFlexRayPacket::DecodeToMessage(const std
if(msg->headerCRCStatus != FlexRay::CRCStatus::Error) { if(msg->headerCRCStatus != FlexRay::CRCStatus::Error) {
msg->reserved0was1 = data->reserved_0; msg->reserved0was1 = data->reserved_0;
msg->payloadPreamble = data->payload_preamble; msg->payloadPreamble = data->payload_preamble;
msg->nullFrame = data->null_frame; msg->nullFrame = !data->null_frame;
msg->sync = data->sync; msg->sync = data->sync;
msg->startup = data->startup; msg->startup = data->startup;
msg->slotid = data->slotid; msg->slotid = data->slotid;
msg->cycle = data->cycle;
msg->dynamic = data->statusBits.bits.dynamic;
if(int64_t(numBytes) != int64_t(data->Length) - 4) { if(int64_t(numBytes) != int64_t(data->Length) - 4) {
} else {
// This is an error, probably need to flag it // This is an error, probably need to flag it
} else {
msg->data = std::vector<uint8_t>((const uint8_t*)(data + 1), (const uint8_t*)(data + 1) + numBytes);
} }
} }
} }

View File

@ -25,7 +25,7 @@ void FlexRay::Controller::setConfiguration(Cluster::Configuration clConfig, Cont
void FlexRay::Controller::addMessageBuffer(MessageBuffer buffer) { void FlexRay::Controller::addMessageBuffer(MessageBuffer buffer) {
configDirty = true; configDirty = true;
messageBuffers.emplace_back(std::move(buffer)); messageBuffers.emplace_back(std::make_shared<MessageBuffer>(buffer));
} }
void FlexRay::Controller::clearMessageBuffers() { void FlexRay::Controller::clearMessageBuffers() {
@ -180,71 +180,72 @@ bool FlexRay::Controller::configure(std::chrono::milliseconds timeout) {
(controllerConfig.ExternRateCorrectionMicroticks << 24) (controllerConfig.ExternRateCorrectionMicroticks << 24)
}); });
std::vector<MessageBuffer> staticTx, dynamicTx; std::vector<std::shared_ptr<MessageBuffer>> staticTx;
std::vector<std::shared_ptr<MessageBuffer>> dynamicTx;
// Add key slot messages // Add key slot messages
MessageBuffer first; std::shared_ptr<MessageBuffer> first = std::make_shared<MessageBuffer>();
bool firstIsInMessageBuffers = false; bool firstIsInMessageBuffers = false;
bool firstUsed = false; bool firstUsed = false;
MessageBuffer second; std::shared_ptr<MessageBuffer> second = std::make_shared<MessageBuffer>();
bool secondIsInMessageBuffers = false; bool secondIsInMessageBuffers = false;
bool secondUsed = false; bool secondUsed = false;
if(controllerConfig.KeySlotUsedForSync || controllerConfig.KeySlotOnlyEnabled) { if(controllerConfig.KeySlotUsedForSync || controllerConfig.KeySlotOnlyEnabled) {
first.isStartup = controllerConfig.KeySlotUsedForStartup; first->isStartup = controllerConfig.KeySlotUsedForStartup;
first.isSync = controllerConfig.KeySlotUsedForSync; first->isSync = controllerConfig.KeySlotUsedForSync;
first.isTransmit = true; first->isTransmit = true;
first.channelA = true; first->channelA = true;
first.channelB = !controllerConfig.TwoKeySlotMode && controllerConfig.ChannelB; first->channelB = !controllerConfig.TwoKeySlotMode && controllerConfig.ChannelB;
first.frameID = controllerConfig.KeySlotID; first->frameID = controllerConfig.KeySlotID;
first.frameLengthBytes = clusterConfig.PayloadLengthOfStaticSlotInWords * 2; first->frameLengthBytes = clusterConfig.PayloadLengthOfStaticSlotInWords * 2;
first.baseCycle = 0; first->baseCycle = 0;
first.cycleRepetition = 1; first->cycleRepetition = 1;
first.continuousMode = 1; first->continuousMode = 0;
staticTx.emplace_back(first); staticTx.push_back(first);
firstUsed = true; firstUsed = true;
if(controllerConfig.TwoKeySlotMode) { if(controllerConfig.TwoKeySlotMode) {
second.isStartup = controllerConfig.KeySlotUsedForStartup; second->isStartup = controllerConfig.KeySlotUsedForStartup;
second.isSync = controllerConfig.KeySlotUsedForSync; second->isSync = controllerConfig.KeySlotUsedForSync;
second.isTransmit = true; second->isTransmit = true;
second.channelB =true; second->channelB =true;
second.frameID = controllerConfig.SecondKeySlotID; second->frameID = controllerConfig.SecondKeySlotID;
second.frameLengthBytes = clusterConfig.PayloadLengthOfStaticSlotInWords * 2; second->frameLengthBytes = clusterConfig.PayloadLengthOfStaticSlotInWords * 2;
second.baseCycle = 0; second->baseCycle = 0;
second.cycleRepetition = 1; second->cycleRepetition = 1;
second.continuousMode = 0; second->continuousMode = 0;
staticTx.emplace_back(second); staticTx.push_back(second);
secondUsed = true; secondUsed = true;
} }
} }
for(const auto& buf : messageBuffers) { for(auto& buf : messageBuffers) {
if(!buf.isTransmit) if(!buf->isTransmit)
continue; // Only transmit frames need to be written to the controller continue; // Only transmit frames need to be written to the controller
if(!buf.isDynamic && ((controllerConfig.KeySlotUsedForSync && buf.isSync) || (controllerConfig.KeySlotUsedForStartup && buf.isStartup))) { if(!buf->isDynamic && ((controllerConfig.KeySlotUsedForSync && buf->isSync) || (controllerConfig.KeySlotUsedForStartup && buf->isStartup))) {
if(staticTx[0].frameID == buf.frameID) { if(staticTx[0]->frameID == buf->frameID) {
staticTx[0].frameLengthBytes = buf.frameLengthBytes; staticTx[0]->frameLengthBytes = buf->frameLengthBytes;
staticTx[0].baseCycle = buf.baseCycle; staticTx[0]->baseCycle = buf->baseCycle;
staticTx[0].cycleRepetition = buf.cycleRepetition; staticTx[0]->cycleRepetition = buf->cycleRepetition;
staticTx[0].continuousMode = buf.continuousMode; staticTx[0]->continuousMode = buf->continuousMode;
firstIsInMessageBuffers = true; firstIsInMessageBuffers = true;
continue; continue;
} }
if(controllerConfig.TwoKeySlotMode && staticTx[1].frameID == buf.frameID) { if(controllerConfig.TwoKeySlotMode && staticTx[1]->frameID == buf->frameID) {
staticTx[1].frameLengthBytes = buf.frameLengthBytes; staticTx[1]->frameLengthBytes = buf->frameLengthBytes;
staticTx[1].baseCycle = buf.baseCycle; staticTx[1]->baseCycle = buf->baseCycle;
staticTx[1].cycleRepetition = buf.cycleRepetition; staticTx[1]->cycleRepetition = buf->cycleRepetition;
staticTx[1].continuousMode = buf.continuousMode; staticTx[1]->continuousMode = buf->continuousMode;
secondIsInMessageBuffers = true; secondIsInMessageBuffers = true;
continue; continue;
} }
} }
if(buf.isDynamic) if(buf->isDynamic)
dynamicTx.push_back(buf); dynamicTx.push_back(buf);
else else
staticTx.push_back(buf); staticTx.push_back(buf);
@ -259,13 +260,12 @@ bool FlexRay::Controller::configure(std::chrono::milliseconds timeout) {
int64_t totalBuffers = staticTx.size() + dynamicTx.size(); int64_t totalBuffers = staticTx.size() + dynamicTx.size();
if(totalBuffers > 128) // TODO warn if(totalBuffers > 128) // TODO warn
totalBuffers = 128; totalBuffers = 128;
totalBuffers -= 1;
registerWrites.push_back({ ERAYRegister::MRC, registerWrites.push_back({ ERAYRegister::MRC,
// FDB[7:0] set to 0, No group of message buffers exclusively for the static segment configured // FDB[7:0] set to 0, No group of message buffers exclusively for the static segment configured
// FFB[7:0] set to 0x80, No message buffer assigned to the FIFO // FFB[7:0] set to 0x80, No message buffer assigned to the FIFO
(0x80 << 8) | (0x80 << 8) |
(uint8_t(totalBuffers) << 16) | (uint8_t(totalBuffers - 1) << 16) |
(controllerConfig.TwoKeySlotMode << 2) (controllerConfig.TwoKeySlotMode << 2)
}); });
@ -276,8 +276,8 @@ bool FlexRay::Controller::configure(std::chrono::milliseconds timeout) {
} }
uint16_t dataPointer = (totalBuffers + 1) * 4; uint16_t dataPointer = (totalBuffers + 1) * 4;
for(auto i = 0; i <= totalBuffers; i++) { for(auto i = 0; i < totalBuffers; i++) {
auto& buf = (i < staticTx.size() ? staticTx[i] : dynamicTx[i - staticTx.size()]); MessageBuffer& buf = *(i < staticTx.size() ? staticTx[i] : dynamicTx[i - staticTx.size()]);
if(buf.frameID == 0) if(buf.frameID == 0)
buf.frameID = i | (1 << 10); buf.frameID = i | (1 << 10);
@ -355,8 +355,12 @@ bool FlexRay::Controller::getReady(std::chrono::milliseconds timeout) {
return false; return false;
updateTimeout(); updateTimeout();
if(status == POCStatus::Ready && !configDirty) if(status == POCStatus::Ready && !configDirty) {
return true; // Already in the desired state // Already in the desired state
if(allowColdstart && !setCurrentPOCCommand(FlexRay::POCCommand::AllowColdstart, true, timeout))
return false;
return true;
}
if(status != POCStatus::Config) { if(status != POCStatus::Config) {
// Must enter config before continuing // Must enter config before continuing
@ -408,28 +412,28 @@ bool FlexRay::Controller::transmit(const std::shared_ptr<FlexRayMessage>& frmsg)
bool success = false; bool success = false;
for(const auto& buf : messageBuffers) { for(const auto& buf : messageBuffers) {
if(!buf.isTransmit) if(!buf->isTransmit)
continue; continue;
if(frmsg->slotid != buf.frameID) if(frmsg->slotid != buf->frameID)
continue; continue;
if(CalculateCycleFilter(frmsg->cycle, frmsg->cycleRepetition) != CalculateCycleFilter(buf.baseCycle, buf.cycleRepetition)) if(CalculateCycleFilter(frmsg->cycle, frmsg->cycleRepetition) != CalculateCycleFilter(buf->baseCycle, buf->cycleRepetition))
continue; continue;
FlexRay::Channel bufChannel = FlexRay::Channel::None; FlexRay::Channel bufChannel = FlexRay::Channel::None;
if(buf.channelA && buf.channelB) if(buf->channelA && buf->channelB)
bufChannel = FlexRay::Channel::AB; bufChannel = FlexRay::Channel::AB;
else if(buf.channelA) else if(buf->channelA)
bufChannel = FlexRay::Channel::A; bufChannel = FlexRay::Channel::A;
else if(buf.channelB) else if(buf->channelB)
bufChannel = FlexRay::Channel::B; bufChannel = FlexRay::Channel::B;
if(frmsg->channel != bufChannel) if(frmsg->channel != bufChannel)
continue; continue;
// This is a message buffer we want to fill // This is a message buffer we want to fill
if(!device.com->sendCommand(Command::FlexRayControl, FlexRayControlMessage::BuildWriteMessageBufferArgs(index, buf._id, frmsg->data, buf.frameLengthBytes))) if(!device.com->sendCommand(Command::FlexRayControl, FlexRayControlMessage::BuildWriteMessageBufferArgs(index, buf->_id, frmsg->data, buf->frameLengthBytes)))
continue; continue;
success = true; success = true;

View File

@ -196,7 +196,7 @@ private:
bool configDirty = false; bool configDirty = false;
Cluster::Configuration clusterConfig; Cluster::Configuration clusterConfig;
Controller::Configuration controllerConfig; Controller::Configuration controllerConfig;
std::vector<MessageBuffer> messageBuffers; std::vector<std::shared_ptr<MessageBuffer>> messageBuffers;
}; };
} // namespace FlexRay } // namespace FlexRay

View File

@ -51,8 +51,7 @@ protected:
Network::NetID::LIN3, Network::NetID::LIN3,
Network::NetID::LIN4, Network::NetID::LIN4,
Network::NetID::FlexRay, Network::NetID::FlexRay
Network::NetID::FlexRay2
}; };
return supportedNetworks; return supportedNetworks;
} }