Implement FlexRay transmit, configuration, and cold start

This commit is contained in:
Paul Hollinsky
2019-11-12 20:38:47 -05:00
parent 3396f5dcce
commit 37778d7891
20 changed files with 1042 additions and 77 deletions
@@ -0,0 +1,110 @@
#ifndef __FLEXRAYCLUSTER_H_
#define __FLEXRAYCLUSTER_H_
#ifdef __cplusplus
#include <cstdint>
#include "icsneo/communication/message/flexray/control/flexraycontrolmessage.h"
#include "icsneo/device/extensions/flexray/erayregister.h"
#include "icsneo/device/extensions/flexray/poccommand.h"
namespace icsneo {
namespace FlexRay {
namespace Cluster {
#endif // __cplusplus
typedef enum {
FLEXRAY_BAUDRATE_10M = 0,
FLEXRAY_BAUDRATE_5M = 1, // 5Mbit currently not supported in the monitor
FLEXRAY_BAUDRATE_2M5 = 2, // 2.5Mbit currently not supported in the monitor
FLEXRAY_BAUDRATE_2M5_ALT = 3 // Per the ERAY spec, 0b11 also means 2.5MBits
} neoflexray_speed_t;
typedef enum {
FLEXRAY_SPP_5 = 0, // FlexRay 2.1 requires this value to be 0
FLEXRAY_SPP_4 = 1,
FLEXRAY_SPP_6 = 2,
FLEXRAY_SPP_5_ALT = 3 // Per the ERAY spec, 0b11 also means sample point 5
} neoflexray_spp_t;
#ifdef __cplusplus
#define INIT(x) = x
#define neoflexray_cluster_config_t icsneo::FlexRay::Cluster::Configuration
struct Configuration {
#else // __cplusplus
#include <stdbool.h>
#include <stdint.h>
#define INIT(x)
typedef struct {
#endif // __cplusplus
neoflexray_speed_t Speed INIT(FLEXRAY_BAUDRATE_10M /* = 0 */); // gdSampleClockPeriod, pSamplesPerMicrotick, Baud Rate Prescaler
neoflexray_spp_t StrobePointPosition INIT(FLEXRAY_SPP_5 /* = 0 */);
uint8_t ActionPointOffset INIT(0);
uint32_t BitTimeNS INIT(0);
uint8_t CASRxLowMax INIT(0);
uint8_t ColdStartAttempts INIT(0);
uint32_t CycleCountMax INIT(0);
double CycleDurationSec INIT(0);
bool DetectNITError INIT(false);
uint8_t DynamicSlotIdlePhaseMinislots INIT(0); // In Minislot increments [0..2]
uint32_t IgnoreAfterTx INIT(0);
uint8_t ListenNoiseMacroticks INIT(0);
uint16_t MacroticksPerCycle INIT(0);
double MacrotickDurationSec INIT(0);
uint8_t MaxWithoutClockCorrectionFatal INIT(0);
uint8_t MaxWithoutClockCorrectionPassive INIT(0);
uint8_t MinislotActionPointOffsetMacroticks INIT(0);
uint32_t MinislotDurationMacroticks INIT(0); // gdMinislot
uint32_t NetworkIdleTimeMacroticks INIT(0);
uint8_t NetworkManagementVectorLengthBytes INIT(0);
uint32_t NumberOfMinislots INIT(0);
uint16_t NumberOfStaticSlots INIT(0);
uint32_t OffsetCorrectionStartMacroticks INIT(0);
uint8_t PayloadLengthOfStaticSlotInWords INIT(0);
uint32_t SafetyMarginMacroticks INIT(0);
double SampleClockPeriodSec INIT(0);
bool UseSampleClockPeriodSec INIT(false);
uint16_t StaticSlotMacroticks INIT(0); // gdStaticSlot
uint32_t SymbolWindowMacroticks INIT(0);
uint32_t SymbolWindowActionPointOffsetMacroticks INIT(0);
uint16_t SyncFrameIDCountMax INIT(0); // gSyncNodeMax
double TransceiverStandbyDelaySec INIT(false);
bool UseTransceiverStandbyDelaySec INIT(0);
uint8_t TransmissionStartSequenceDurationBits INIT(0); // gdTSSTransmitter
uint8_t WakeupRxIdleBits INIT(0);
uint8_t WakeupRxLowBits INIT(0);
uint16_t WakeupRxWindowBits INIT(0); // gdWakeupSymbolRxWindow
uint8_t WakeupTxActiveBits INIT(0); // gdWakeupSymbolTxLow (active = low here)
uint8_t WakeupTxIdleBits INIT(0);
#ifdef __cplusplus
};
#else
} neoflexray_cluster_config_t;
#endif
#ifdef __cplusplus
} // namespace Cluster
} // namespace FlexRay
} // namespace icsneo
#endif // __cplusplus
#endif // __FLEXRAYCLUSTER_H_
@@ -1,13 +1,21 @@
#ifndef __FLEXRAYCONTROLLER_H_
#define __FLEXRAYCONTROLLER_H_
#ifdef __cplusplus
#include <cstdint>
#include <memory>
#include <chrono>
#include <mutex>
#include "icsneo/communication/message/flexray/control/flexraycontrolmessage.h"
#include "icsneo/communication/message/flexray/flexraymessage.h"
#include "icsneo/device/extensions/flexray/messagebuffer.h"
#include "icsneo/device/extensions/flexray/erayregister.h"
#include "icsneo/device/extensions/flexray/poccommand.h"
#include "icsneo/device/extensions/flexray/pocstatus.h"
#include "icsneo/device/extensions/flexray/cluster.h"
#define INIT(x) = x
namespace icsneo {
@@ -17,21 +25,46 @@ namespace FlexRay {
class Controller {
public:
Controller(Device& device, uint8_t index) : device(device), index(index) {}
std::shared_ptr<FlexRayControlMessage> getStatus() const;
Controller(Device& device, uint8_t index, Network net) : device(device), index(index), network(net) {}
void _setStatus(std::shared_ptr<FlexRayControlMessage> msg);
// Begin Public Interface
std::shared_ptr<FlexRayControlMessage> getStatus() const;
const Network& getNetwork() const { return network; }
struct Configuration; // Forward declaration
std::pair<const Cluster::Configuration&, const Controller::Configuration&> getConfiguration() const;
void setConfiguration(Cluster::Configuration clConfig, Controller::Configuration coConfig);
bool getStartWhenGoingOnline() const { return startWhenGoingOnline; }
void setStartWhenGoingOnline(bool enable) { startWhenGoingOnline = enable; }
bool getAllowColdstart() const { return allowColdstart; }
void setAllowColdstart(bool enable) { allowColdstart = enable; }
bool getWakeupBeforeStart() const { return wakeupBeforeStart; }
void setWakeupBeforeStart(bool enable) { wakeupBeforeStart = enable; }
void getReady();
void start();
void addMessageBuffer(MessageBuffer buffer);
void clearMessageBuffers();
bool wakeup(std::chrono::milliseconds timeout = std::chrono::milliseconds(50));
bool configure(std::chrono::milliseconds timeout = std::chrono::milliseconds(2000));
bool getReady(std::chrono::milliseconds timeout = std::chrono::milliseconds(2000));
bool start(std::chrono::milliseconds timeout = std::chrono::milliseconds(2000));
bool transmit(const std::shared_ptr<FlexRayMessage>& frmsg);
bool halt(std::chrono::milliseconds timeout = std::chrono::milliseconds(50));
bool freeze(std::chrono::milliseconds timeout = std::chrono::milliseconds(50));
bool triggerMTS(std::chrono::milliseconds timeout = std::chrono::milliseconds(200));
// End Public Interface
private:
bool isPOCBusy() const { return readRegisterOr(ERAYRegister::SUCC1, 0x00000080) & 0x00000080; }
bool isClearAllRAMBusy() const { return readRegisterOr(ERAYRegister::MHDS, 0x00000080) & 0x00000080; }
bool isInputBufferHostBusy() const { return readRegisterOr(ERAYRegister::IBCR, 0x00008000) & 0x00008000; }
std::pair<bool, FlexRay::POCCommand> getCurrentPOCCommand(std::chrono::milliseconds timeout = std::chrono::milliseconds(50)) const;
bool setCurrentPOCCommand(
FlexRay::POCCommand cmd,
@@ -39,6 +72,14 @@ private:
std::chrono::milliseconds timeout = std::chrono::milliseconds(50));
bool wasCommandSuccessful(std::chrono::milliseconds timeout = std::chrono::milliseconds(50)) const;
std::pair<bool, FlexRay::POCStatus> getCurrentPOCStatus(std::chrono::milliseconds timeout = std::chrono::milliseconds(50)) const;
bool lockConfiguration(std::chrono::milliseconds timeout = std::chrono::milliseconds(150));
bool enterConfig(std::chrono::milliseconds timeout = std::chrono::milliseconds(50));
static uint16_t CalculateHCRC(const MessageBuffer& buf);
static uint16_t CalculateCycleFilter(uint8_t baseCycle, uint8_t cycleRepetition);
std::pair<bool, uint32_t> readRegister(
ERAYRegister reg,
std::chrono::milliseconds timeout = std::chrono::milliseconds(50)) const;
@@ -60,15 +101,107 @@ private:
Device& device;
uint8_t index;
Network network;
mutable std::mutex statusLock;
mutable std::mutex readRegisterLock;
std::shared_ptr<FlexRayControlMessage> status;
bool startWhenGoingOnline = false;
bool allowColdstart = false;
bool wakeupBeforeStart = false;
public:
#define neoflexray_controller_config_t icsneo::FlexRay::Controller::Configuration
struct Configuration {
#else // __cplusplus
#include <stdbool.h>
#include <stdint.h>
#define INIT(x)
typedef struct {
#endif // __cplusplus
uint16_t AcceptStartupRangeMicroticks INIT(0);
bool AllowHaltDueToClock INIT(false);
uint8_t AllowPassiveToActiveCyclePairs INIT(0);
uint8_t ClusterDriftDamping INIT(0);
bool ChannelA INIT(false);
bool ChannelB INIT(false);
uint8_t DecodingCorrectionMicroticks INIT(0);
uint8_t DelayCompensationAMicroticks INIT(0);
uint8_t DelayCompensationBMicroticks INIT(0);
uint8_t ExternOffsetCorrectionControl INIT(0);
uint8_t ExternRateCorrectionControl INIT(0);
uint8_t ExternOffsetCorrectionMicroticks INIT(0);
uint8_t ExternRateCorrectionMicroticks INIT(0);
bool ExternalSync INIT(false);
bool UseExternalSync INIT(false);
bool FallBackInternal INIT(false);
bool UseFallBackInternal INIT(false);
uint16_t KeySlotID INIT(0);
bool KeySlotOnlyEnabled INIT(false); // pSingleSlotEnabled (TSM)
bool KeySlotUsedForStartup INIT(false); // pKeySlotUsedForStartup (TXST)
bool KeySlotUsedForSync INIT(false); // pKeySlotUsedForSync (TXSY)
uint16_t LatestTxMinislot INIT(0);
uint32_t ListenTimeout INIT(0);
uint8_t MacroInitialOffsetA INIT(0); // Valid 2..72
uint8_t MacroInitialOffsetB INIT(0); // Valid 2..72
uint32_t MaximumDynamicPayloadLengthWords INIT(0);
uint8_t MicroInitialOffsetA INIT(0); // Valid 0..240
uint8_t MicroInitialOffsetB INIT(0); // Valid 0..240
uint32_t MicroPerCycle INIT(0);
double MicrotickDurationSec INIT(0);
bool UseMicrotickDurationSec INIT(false);
bool MTSOnA INIT(false);
bool MTSOnB INIT(false);
bool NMVectorEarlyUpdate INIT(false);
bool UseNMVectorEarlyUpdate INIT(false);
uint16_t OffsetCorrectionOutMicroticks INIT(0);
uint16_t RateCorrectionOutMicroticks INIT(0); // pdMaxDrift and pRateCorrectionOut
uint32_t SamplesPerMicrotick INIT(0);
bool UseSamplesPerMicrotick INIT(false);
uint16_t SecondKeySlotID INIT(0);
bool TwoKeySlotMode INIT(false);
uint8_t WakeupPattern INIT(0);
bool WakeupOnChannelB INIT(false);
#ifndef __cplusplus
} neoflexray_controller_config_t;
#else
};
private:
bool configDirty = false;
Cluster::Configuration clusterConfig;
Controller::Configuration controllerConfig;
std::vector<MessageBuffer> messageBuffers;
};
} // namespace FlexRay
} // namespace icsneo
#endif // __cplusplus
#endif // __FLEXRAYCONTROLLER_H_
@@ -5,6 +5,8 @@
namespace icsneo {
namespace FlexRay {
enum class ERAYRegister : uint32_t {
// Customer Registers : Not Part of ERAY, part of FUJITSU FlexRay ASSP MB88121C
VER = 0x0000,// Version Information Register reset = 0440_79FF Access = r
@@ -100,6 +102,8 @@ enum class ERAYRegister : uint32_t {
NDAT1 = 0x0330,// New Data Register 1 0000_0000 r
NDAT2 = 0x0334,// New Data Register 2 0000_0000 r
ENDN = 0x03F4,// Endian check, 8765_4321 r
WRHS1 = 0x0500,// Write Header Section Register 1
WRHS2 = 0x0504,// Write Header Section Register 2
WRHS3 = 0x0508,// Write Header Section Register 3
@@ -111,6 +115,8 @@ enum class ERAYRegister : uint32_t {
OBCR = 0x714,
};
} // namespace FlexRay
} // namespace icsneo
#endif // __ERAYREGISTER_H_
@@ -16,9 +16,14 @@ class Controller;
class Extension : public DeviceExtension {
public:
Extension(Device& device, uint8_t controllerCount);
Extension(Device& device, const std::vector<Network>& controllerNetworks);
const char* getName() const override { return "FlexRay"; }
void onGoOnline() override;
void onGoOffline() override;
void handleMessage(const std::shared_ptr<Message>& message) override;
bool transmitHook(const std::shared_ptr<Message>& message, bool& success) override;
std::shared_ptr<Controller> getController(uint8_t index) const {
if(index >= controllers.size())
@@ -0,0 +1,52 @@
#ifndef __FLEXRAYMESSAGEBUFFER_H_
#define __FLEXRAYMESSAGEBUFFER_H_
#ifdef __cplusplus
#include <cstdint>
namespace icsneo {
namespace FlexRay {
#define INIT(x) = x
#define neoflexray_message_buffer_t icsneo::FlexRay::MessageBuffer
struct MessageBuffer {
#else // __cplusplus
#include <stdbool.h>
#include <stdint.h>
#define INIT(x)
typedef struct {
#endif // __cplusplus
bool isDynamic INIT(false);
bool isSync INIT(false); // Must be set if isStartup is set!
bool isStartup INIT(false);
bool isNMFrame INIT(false);
bool isTransmit INIT(false);
uint16_t frameID INIT(0);
bool channelA INIT(false);
bool channelB INIT(false);
uint8_t frameLengthBytes INIT(0);
uint8_t baseCycle INIT(0);
uint8_t cycleRepetition INIT(0);
bool continuousMode INIT(false);
uint16_t _dataPointer INIT(0); // For internal use
uint16_t _id INIT(0); // For internal use
#ifndef __cplusplus
} neoflexray_message_buffer_t;
#else
};
} // namespace FlexRay
} // namespace icsneo
#endif // __cplusplus
#endif // __FLEXRAYMESSAGEBUFFER_H_
@@ -14,6 +14,7 @@ enum class POCStatus : uint8_t {
NormalPassive = 0x03,
Halt = 0x04,
MonitorMode = 0x05,
Config = 0x0f,
WakeupStandby = 0x10,
WakeupListen = 0x11,
WakeupSend = 0x12,