Properly decode incoming FlexRayPackets
parent
31062dd928
commit
4821a957dd
|
|
@ -16,13 +16,20 @@ std::shared_ptr<FlexRayMessage> HardwareFlexRayPacket::DecodeToMessage(const std
|
|||
// Always get the frame length, even for a symbol
|
||||
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
|
||||
msg->symbol = FlexRay::Symbol::Unknown; // We can't know the symbol yet because this will depend on the baudrate
|
||||
// Eventually we'll have to get this from the framelen
|
||||
// These values are only for 10Mbit
|
||||
// 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 {
|
||||
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.hcrc_error)
|
||||
msg->headerCRCStatus = FlexRay::CRCStatus::Error;
|
||||
|
|
@ -43,14 +50,16 @@ std::shared_ptr<FlexRayMessage> HardwareFlexRayPacket::DecodeToMessage(const std
|
|||
if(msg->headerCRCStatus != FlexRay::CRCStatus::Error) {
|
||||
msg->reserved0was1 = data->reserved_0;
|
||||
msg->payloadPreamble = data->payload_preamble;
|
||||
msg->nullFrame = data->null_frame;
|
||||
msg->nullFrame = !data->null_frame;
|
||||
msg->sync = data->sync;
|
||||
msg->startup = data->startup;
|
||||
msg->slotid = data->slotid;
|
||||
msg->cycle = data->cycle;
|
||||
msg->dynamic = data->statusBits.bits.dynamic;
|
||||
if(int64_t(numBytes) != int64_t(data->Length) - 4) {
|
||||
|
||||
} else {
|
||||
// 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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -25,7 +25,7 @@ void FlexRay::Controller::setConfiguration(Cluster::Configuration clConfig, Cont
|
|||
|
||||
void FlexRay::Controller::addMessageBuffer(MessageBuffer buffer) {
|
||||
configDirty = true;
|
||||
messageBuffers.emplace_back(std::move(buffer));
|
||||
messageBuffers.emplace_back(std::make_shared<MessageBuffer>(buffer));
|
||||
}
|
||||
|
||||
void FlexRay::Controller::clearMessageBuffers() {
|
||||
|
|
@ -180,71 +180,72 @@ bool FlexRay::Controller::configure(std::chrono::milliseconds timeout) {
|
|||
(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
|
||||
MessageBuffer first;
|
||||
std::shared_ptr<MessageBuffer> first = std::make_shared<MessageBuffer>();
|
||||
bool firstIsInMessageBuffers = false;
|
||||
bool firstUsed = false;
|
||||
|
||||
MessageBuffer second;
|
||||
std::shared_ptr<MessageBuffer> second = std::make_shared<MessageBuffer>();
|
||||
bool secondIsInMessageBuffers = false;
|
||||
bool secondUsed = false;
|
||||
|
||||
if(controllerConfig.KeySlotUsedForSync || controllerConfig.KeySlotOnlyEnabled) {
|
||||
first.isStartup = controllerConfig.KeySlotUsedForStartup;
|
||||
first.isSync = controllerConfig.KeySlotUsedForSync;
|
||||
first.isTransmit = true;
|
||||
first.channelA = true;
|
||||
first.channelB = !controllerConfig.TwoKeySlotMode && controllerConfig.ChannelB;
|
||||
first.frameID = controllerConfig.KeySlotID;
|
||||
first.frameLengthBytes = clusterConfig.PayloadLengthOfStaticSlotInWords * 2;
|
||||
first.baseCycle = 0;
|
||||
first.cycleRepetition = 1;
|
||||
first.continuousMode = 1;
|
||||
staticTx.emplace_back(first);
|
||||
first->isStartup = controllerConfig.KeySlotUsedForStartup;
|
||||
first->isSync = controllerConfig.KeySlotUsedForSync;
|
||||
first->isTransmit = true;
|
||||
first->channelA = true;
|
||||
first->channelB = !controllerConfig.TwoKeySlotMode && controllerConfig.ChannelB;
|
||||
first->frameID = controllerConfig.KeySlotID;
|
||||
first->frameLengthBytes = clusterConfig.PayloadLengthOfStaticSlotInWords * 2;
|
||||
first->baseCycle = 0;
|
||||
first->cycleRepetition = 1;
|
||||
first->continuousMode = 0;
|
||||
staticTx.push_back(first);
|
||||
firstUsed = true;
|
||||
|
||||
if(controllerConfig.TwoKeySlotMode) {
|
||||
second.isStartup = controllerConfig.KeySlotUsedForStartup;
|
||||
second.isSync = controllerConfig.KeySlotUsedForSync;
|
||||
second.isTransmit = true;
|
||||
second.channelB =true;
|
||||
second.frameID = controllerConfig.SecondKeySlotID;
|
||||
second.frameLengthBytes = clusterConfig.PayloadLengthOfStaticSlotInWords * 2;
|
||||
second.baseCycle = 0;
|
||||
second.cycleRepetition = 1;
|
||||
second.continuousMode = 0;
|
||||
staticTx.emplace_back(second);
|
||||
second->isStartup = controllerConfig.KeySlotUsedForStartup;
|
||||
second->isSync = controllerConfig.KeySlotUsedForSync;
|
||||
second->isTransmit = true;
|
||||
second->channelB =true;
|
||||
second->frameID = controllerConfig.SecondKeySlotID;
|
||||
second->frameLengthBytes = clusterConfig.PayloadLengthOfStaticSlotInWords * 2;
|
||||
second->baseCycle = 0;
|
||||
second->cycleRepetition = 1;
|
||||
second->continuousMode = 0;
|
||||
staticTx.push_back(second);
|
||||
secondUsed = true;
|
||||
}
|
||||
}
|
||||
|
||||
for(const auto& buf : messageBuffers) {
|
||||
if(!buf.isTransmit)
|
||||
for(auto& buf : messageBuffers) {
|
||||
if(!buf->isTransmit)
|
||||
continue; // Only transmit frames need to be written to the controller
|
||||
|
||||
if(!buf.isDynamic && ((controllerConfig.KeySlotUsedForSync && buf.isSync) || (controllerConfig.KeySlotUsedForStartup && buf.isStartup))) {
|
||||
if(staticTx[0].frameID == buf.frameID) {
|
||||
staticTx[0].frameLengthBytes = buf.frameLengthBytes;
|
||||
staticTx[0].baseCycle = buf.baseCycle;
|
||||
staticTx[0].cycleRepetition = buf.cycleRepetition;
|
||||
staticTx[0].continuousMode = buf.continuousMode;
|
||||
if(!buf->isDynamic && ((controllerConfig.KeySlotUsedForSync && buf->isSync) || (controllerConfig.KeySlotUsedForStartup && buf->isStartup))) {
|
||||
if(staticTx[0]->frameID == buf->frameID) {
|
||||
staticTx[0]->frameLengthBytes = buf->frameLengthBytes;
|
||||
staticTx[0]->baseCycle = buf->baseCycle;
|
||||
staticTx[0]->cycleRepetition = buf->cycleRepetition;
|
||||
staticTx[0]->continuousMode = buf->continuousMode;
|
||||
firstIsInMessageBuffers = true;
|
||||
continue;
|
||||
}
|
||||
|
||||
if(controllerConfig.TwoKeySlotMode && staticTx[1].frameID == buf.frameID) {
|
||||
staticTx[1].frameLengthBytes = buf.frameLengthBytes;
|
||||
staticTx[1].baseCycle = buf.baseCycle;
|
||||
staticTx[1].cycleRepetition = buf.cycleRepetition;
|
||||
staticTx[1].continuousMode = buf.continuousMode;
|
||||
if(controllerConfig.TwoKeySlotMode && staticTx[1]->frameID == buf->frameID) {
|
||||
staticTx[1]->frameLengthBytes = buf->frameLengthBytes;
|
||||
staticTx[1]->baseCycle = buf->baseCycle;
|
||||
staticTx[1]->cycleRepetition = buf->cycleRepetition;
|
||||
staticTx[1]->continuousMode = buf->continuousMode;
|
||||
secondIsInMessageBuffers = true;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
if(buf.isDynamic)
|
||||
if(buf->isDynamic)
|
||||
dynamicTx.push_back(buf);
|
||||
else
|
||||
staticTx.push_back(buf);
|
||||
|
|
@ -259,13 +260,12 @@ bool FlexRay::Controller::configure(std::chrono::milliseconds timeout) {
|
|||
int64_t totalBuffers = staticTx.size() + dynamicTx.size();
|
||||
if(totalBuffers > 128) // TODO warn
|
||||
totalBuffers = 128;
|
||||
totalBuffers -= 1;
|
||||
|
||||
registerWrites.push_back({ ERAYRegister::MRC,
|
||||
// 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
|
||||
(0x80 << 8) |
|
||||
(uint8_t(totalBuffers) << 16) |
|
||||
(uint8_t(totalBuffers - 1) << 16) |
|
||||
(controllerConfig.TwoKeySlotMode << 2)
|
||||
});
|
||||
|
||||
|
|
@ -276,8 +276,8 @@ bool FlexRay::Controller::configure(std::chrono::milliseconds timeout) {
|
|||
}
|
||||
|
||||
uint16_t dataPointer = (totalBuffers + 1) * 4;
|
||||
for(auto i = 0; i <= totalBuffers; i++) {
|
||||
auto& buf = (i < staticTx.size() ? staticTx[i] : dynamicTx[i - staticTx.size()]);
|
||||
for(auto i = 0; i < totalBuffers; i++) {
|
||||
MessageBuffer& buf = *(i < staticTx.size() ? staticTx[i] : dynamicTx[i - staticTx.size()]);
|
||||
|
||||
if(buf.frameID == 0)
|
||||
buf.frameID = i | (1 << 10);
|
||||
|
|
@ -355,8 +355,12 @@ bool FlexRay::Controller::getReady(std::chrono::milliseconds timeout) {
|
|||
return false;
|
||||
updateTimeout();
|
||||
|
||||
if(status == POCStatus::Ready && !configDirty)
|
||||
return true; // Already in the desired state
|
||||
if(status == POCStatus::Ready && !configDirty) {
|
||||
// Already in the desired state
|
||||
if(allowColdstart && !setCurrentPOCCommand(FlexRay::POCCommand::AllowColdstart, true, timeout))
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
if(status != POCStatus::Config) {
|
||||
// Must enter config before continuing
|
||||
|
|
@ -408,28 +412,28 @@ bool FlexRay::Controller::transmit(const std::shared_ptr<FlexRayMessage>& frmsg)
|
|||
bool success = false;
|
||||
|
||||
for(const auto& buf : messageBuffers) {
|
||||
if(!buf.isTransmit)
|
||||
if(!buf->isTransmit)
|
||||
continue;
|
||||
|
||||
if(frmsg->slotid != buf.frameID)
|
||||
if(frmsg->slotid != buf->frameID)
|
||||
continue;
|
||||
|
||||
if(CalculateCycleFilter(frmsg->cycle, frmsg->cycleRepetition) != CalculateCycleFilter(buf.baseCycle, buf.cycleRepetition))
|
||||
if(CalculateCycleFilter(frmsg->cycle, frmsg->cycleRepetition) != CalculateCycleFilter(buf->baseCycle, buf->cycleRepetition))
|
||||
continue;
|
||||
|
||||
FlexRay::Channel bufChannel = FlexRay::Channel::None;
|
||||
if(buf.channelA && buf.channelB)
|
||||
if(buf->channelA && buf->channelB)
|
||||
bufChannel = FlexRay::Channel::AB;
|
||||
else if(buf.channelA)
|
||||
else if(buf->channelA)
|
||||
bufChannel = FlexRay::Channel::A;
|
||||
else if(buf.channelB)
|
||||
else if(buf->channelB)
|
||||
bufChannel = FlexRay::Channel::B;
|
||||
|
||||
if(frmsg->channel != bufChannel)
|
||||
continue;
|
||||
|
||||
// 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;
|
||||
|
||||
success = true;
|
||||
|
|
|
|||
|
|
@ -196,7 +196,7 @@ private:
|
|||
bool configDirty = false;
|
||||
Cluster::Configuration clusterConfig;
|
||||
Controller::Configuration controllerConfig;
|
||||
std::vector<MessageBuffer> messageBuffers;
|
||||
std::vector<std::shared_ptr<MessageBuffer>> messageBuffers;
|
||||
};
|
||||
|
||||
} // namespace FlexRay
|
||||
|
|
|
|||
|
|
@ -51,8 +51,7 @@ protected:
|
|||
Network::NetID::LIN3,
|
||||
Network::NetID::LIN4,
|
||||
|
||||
Network::NetID::FlexRay,
|
||||
Network::NetID::FlexRay2
|
||||
Network::NetID::FlexRay
|
||||
};
|
||||
return supportedNetworks;
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue