1 // 2 // Copyright (c) 2010-2023 Antmicro 3 // 4 // This file is licensed under the MIT License. 5 // Full license text is available in 'licenses/MIT.txt'. 6 // 7 using System; 8 using System.Linq; 9 using System.Collections.Generic; 10 using Antmicro.Renode.Core; 11 using Antmicro.Renode.Core.CAN; 12 using Antmicro.Renode.Core.Structure.Registers; 13 using Antmicro.Renode.Logging; 14 using Antmicro.Renode.Utilities; 15 using Antmicro.Renode.Peripherals.Bus; 16 using Antmicro.Renode.Peripherals.Memory; 17 using Antmicro.Renode.Hooks; 18 using Antmicro.Renode.Utilities.Packets; 19 using Antmicro.Renode.Time; 20 21 namespace Antmicro.Renode.Peripherals.CAN 22 { 23 public partial class MCAN 24 { BuildStructuredViews()25 private void BuildStructuredViews() 26 { 27 rxFIFO0 = new RxFIFOView 28 { 29 StartAddress = rv.RxFIFO0Configuration.RxFIFO0StartAddress, 30 Size = rv.RxFIFO0Configuration.RxFIFO0Size, 31 Watermark = rv.RxFIFO0Configuration.RxFIFO0Watermark, 32 OperationMode = rv.RxFIFO0Configuration.FIFO0OperationMode, 33 GetIndexRaw = rv.RxFIFO0Status.RxFIFO0GetIndex, 34 PutIndexRaw = rv.RxFIFO0Status.RxFIFO0PutIndex, 35 Full = rv.RxFIFO0Status.RxFIFO0Full, 36 MessageLost = rv.RxFIFO0Status.RxFIFO0MessageLost, 37 AcknowledgeIndex = rv.RxFIFO0Acknowledge.RxFIFO0AcknowledgeIndex, 38 DataFieldSize = rv.RxBufferFIFOElementSizeConfiguration.RxFIFO0DataFieldSize, 39 InterruptMessageLost = rv.InterruptRegister.InterruptFlags[(int)Interrupt.RxFIFO0MessageLost], 40 InterruptWatermarkReached = rv.InterruptRegister.InterruptFlags[(int)Interrupt.RxFIFO0WatermarkReached], 41 InterruptFull = rv.InterruptRegister.InterruptFlags[(int)Interrupt.RxFIFO0Full], 42 InterruptNewMessage = rv.InterruptRegister.InterruptFlags[(int)Interrupt.RxFIFO0NewMessage] 43 }; 44 45 rxFIFO1 = new RxFIFOView 46 { 47 StartAddress = rv.RxFIFO1Configuration.RxFIFO1StartAddress, 48 Size = rv.RxFIFO1Configuration.RxFIFO1Size, 49 Watermark = rv.RxFIFO1Configuration.RxFIFO1Watermark, 50 OperationMode = rv.RxFIFO1Configuration.FIFO1OperationMode, 51 GetIndexRaw = rv.RxFIFO1Status.RxFIFO1GetIndex, 52 PutIndexRaw = rv.RxFIFO1Status.RxFIFO1PutIndex, 53 Full = rv.RxFIFO1Status.RxFIFO1Full, 54 MessageLost = rv.RxFIFO1Status.RxFIFO1MessageLost, 55 AcknowledgeIndex = rv.RxFIFO1Acknowledge.RxFIFO1AcknowledgeIndex, 56 DataFieldSize = rv.RxBufferFIFOElementSizeConfiguration.RxFIFO1DataFieldSize, 57 InterruptMessageLost = rv.InterruptRegister.InterruptFlags[(int)Interrupt.RxFIFO1MessageLost], 58 InterruptWatermarkReached = rv.InterruptRegister.InterruptFlags[(int)Interrupt.RxFIFO1WatermarkReached], 59 InterruptFull = rv.InterruptRegister.InterruptFlags[(int)Interrupt.RxFIFO1Full], 60 InterruptNewMessage = rv.InterruptRegister.InterruptFlags[(int)Interrupt.RxFIFO1NewMessage] 61 }; 62 63 filterConfigurationStandard = new FilterConfigurationView 64 { 65 RejectRemoteFrames = rv.GlobalFilterConfiguration.RejectRemoteFramesStandard, 66 AcceptNonMatchingFrames = rv.GlobalFilterConfiguration.AcceptNonMatchingFramesStandard, 67 FilterListStartAddress = rv.StandardIDFilterConfiguration.FilterListStandardStartAddress, 68 ListSize = rv.StandardIDFilterConfiguration.ListSizeStandard 69 }; 70 71 filterConfigurationExtended = new FilterConfigurationView 72 { 73 RejectRemoteFrames = rv.GlobalFilterConfiguration.RejectRemoteFramesExtended, 74 AcceptNonMatchingFrames = rv.GlobalFilterConfiguration.AcceptNonMatchingFramesExtended, 75 FilterListStartAddress = rv.ExtendedIDFilterConfiguration.FilterListExtendedStartAddress, 76 ListSize = rv.ExtendedIDFilterConfiguration.ListSizeExtended 77 }; 78 79 rxBuffer = new RxBufferView 80 { 81 StartAddress = rv.RxBufferConfiguration.RxBufferStartAddress, 82 DataFieldSize = rv.RxBufferFIFOElementSizeConfiguration.RxBufferDataFieldSize 83 }; 84 85 txBuffers = new TxBufferView 86 { 87 StartAddress = rv.TxBufferConfiguration.TxBuffersStartAddress, 88 NumberOfDedicatedTxBuffers = rv.TxBufferConfiguration.NumberOfDedicatedTxBuffers, 89 TxFIFOQueueSize = rv.TxBufferConfiguration.TxFIFOQueueSize, 90 TxFIFOQueueMode = rv.TxBufferConfiguration.TxFIFOQueueMode, 91 DataFieldSize = rv.TxBufferElementSizeConfiguration.TxBufferDataFieldSize 92 }; 93 94 txFIFOQueue = new TxFIFOQueueView 95 { 96 Offset = rv.TxBufferConfiguration.NumberOfDedicatedTxBuffers, 97 Size = rv.TxBufferConfiguration.TxFIFOQueueSize, 98 QueueMode = rv.TxBufferConfiguration.TxFIFOQueueMode, 99 GetIndexRaw = rv.TxFIFOQueueStatus.TxFIFOGetIndex, 100 PutIndexRaw = rv.TxFIFOQueueStatus.TxFIFOQueuePutIndex, 101 FullRaw = rv.TxFIFOQueueStatus.TxFIFOQueueFull, 102 TransmissionRequestPendingFlags = rv.TxBufferRequestPending.TransmissionRequestPendingFlags 103 }; 104 105 txEventFIFO = new TxEventFIFOView 106 { 107 StartAddress = rv.TxEventFIFOConfiguration.EventFIFOStartAddress, 108 Size = rv.TxEventFIFOConfiguration.EventFIFOSize, 109 Watermark = rv.TxEventFIFOConfiguration.EventFIFOWatermark, 110 GetIndexRaw = rv.TxEventFIFOStatus.EventFIFOGetIndex, 111 PutIndexRaw = rv.TxEventFIFOStatus.EventFIFOPutIndex, 112 Full = rv.TxEventFIFOStatus.EventFIFOFull, 113 ElementLost = rv.TxEventFIFOStatus.TxEventFIFOElementLost, 114 AcknowledgeIndex = rv.TxEventFIFOAcknowledge.EventFIFOAcknowledgeIndex, 115 InterruptNewEntry = rv.InterruptRegister.InterruptFlags[(int)Interrupt.TxEventFIFONewEntry], 116 InterruptWatermarkReached = rv.InterruptRegister.InterruptFlags[(int)Interrupt.TxEventFIFOWatermarkReached], 117 InterruptFull = rv.InterruptRegister.InterruptFlags[(int)Interrupt.TxEventFIFOFull], 118 InterruptElementLost = rv.InterruptRegister.InterruptFlags[(int)Interrupt.TxEventFIFOElementLost], 119 }; 120 } 121 BuildRegisterMapView()122 private void BuildRegisterMapView() 123 { 124 rv = new RegisterMapView 125 { 126 TestRegister = new TestRegister(), 127 CCControlRegister = new CCControlRegister(), 128 ProtocolStatusRegister = new ProtocolStatusRegister(), 129 InterruptRegister = new InterruptRegister(), 130 InterruptEnable = new InterruptEnable(), 131 InterruptLineSelect = new InterruptLineSelect(), 132 InterruptLineEnable = new InterruptLineEnable(), 133 GlobalFilterConfiguration = new GlobalFilterConfiguration(), 134 StandardIDFilterConfiguration = new StandardIDFilterConfiguration(), 135 ExtendedIDFilterConfiguration = new ExtendedIDFilterConfiguration(), 136 ExtendedIdANDMask = new ExtendedIdANDMask(), 137 HighPriorityMessageStatus = new HighPriorityMessageStatus(), 138 NewData1 = new NewData1(), 139 NewData2 = new NewData2(), 140 RxFIFO0Configuration = new RxFIFO0Configuration(), 141 RxFIFO0Status = new RxFIFO0Status(), 142 RxFIFO0Acknowledge = new RxFIFO0Acknowledge(), 143 RxBufferConfiguration = new RxBufferConfiguration(), 144 RxFIFO1Configuration = new RxFIFO1Configuration(), 145 RxFIFO1Status = new RxFIFO1Status(), 146 RxFIFO1Acknowledge = new RxFIFO1Acknowledge(), 147 RxBufferFIFOElementSizeConfiguration = new RxBufferFIFOElementSizeConfiguration(), 148 TxBufferConfiguration = new TxBufferConfiguration(), 149 TxFIFOQueueStatus = new TxFIFOQueueStatus(), 150 TxBufferElementSizeConfiguration = new TxBufferElementSizeConfiguration(), 151 TxBufferRequestPending = new TxBufferRequestPending(), 152 TxBufferAddRequest = new TxBufferAddRequest(), 153 TxBufferCancellationRequest = new TxBufferCancellationRequest(), 154 TxBufferTransmissionOccurred = new TxBufferTransmissionOccurred(), 155 TxBufferCancellationFinished = new TxBufferCancellationFinished(), 156 TxBufferTransmissionInterruptEnable = new TxBufferTransmissionInterruptEnable(), 157 TxBufferCancellationFinishedInterruptEnable = new TxBufferCancellationFinishedInterruptEnable(), 158 TxEventFIFOConfiguration = new TxEventFIFOConfiguration(), 159 TxEventFIFOStatus = new TxEventFIFOStatus(), 160 TxEventFIFOAcknowledge = new TxEventFIFOAcknowledge() 161 }; 162 } 163 164 public long Size => 0x400; 165 166 public GPIO Line0 { get; private set; } 167 public GPIO Line1 { get; private set; } 168 public GPIO Calibration { get; private set; } 169 public event Action<CANMessageFrame> FrameSent; 170 171 private bool IsProtectedWrite => rv.CCControlRegister.ControlFields[(int)Control.Initialization].Value && rv.CCControlRegister.ControlFields[(int)Control.ConfigurationChangeEnable].Value; 172 173 private readonly IMachine machine; 174 private IMultibyteWritePeripheral messageRAM; 175 private DoubleWordRegisterCollection registers; 176 private RegisterMapView rv; 177 private RxFIFOView rxFIFO0; 178 private RxFIFOView rxFIFO1; 179 private FilterConfigurationView filterConfigurationStandard; 180 private FilterConfigurationView filterConfigurationExtended; 181 private RxBufferView rxBuffer; 182 private TxBufferView txBuffers; 183 private TxFIFOQueueView txFIFOQueue; 184 private TxEventFIFOView txEventFIFO; 185 186 private const int ExtendedFilterSizeInBytes = 8; 187 private const int StandardFilterSizeInBytes = 4; 188 private const int BufferElementHeaderSizeInBytes = 8; 189 private const int TxEventFIFOElementSizeInBytes = 8; 190 private const int NumberOfRxFIFOs = 2; 191 private const byte PaddingByte = 0xcc; 192 193 private static readonly IReadOnlyDictionary<ulong, int> DataFieldSizeToBytesCountMap = new Dictionary<ulong, int> 194 { 195 {0b000, 8}, 196 {0b001, 12}, 197 {0b010, 16}, 198 {0b011, 20}, 199 {0b100, 24}, 200 {0b101, 32}, 201 {0b110, 48}, 202 {0b111, 64}, 203 }; 204 205 private static readonly IReadOnlyDictionary<int, byte> FDBytesCountToDataLengthCodeMap = new Dictionary<int, byte> 206 { 207 {12, 9}, 208 {16, 10}, 209 {20, 11}, 210 {24, 12}, 211 {32, 13}, 212 {48, 14}, 213 {64, 15}, 214 }; 215 216 private static readonly IReadOnlyDictionary<int, byte> DataLengthCodeToFDBytesCountMap = new Dictionary<int, byte> 217 { 218 {9, 12}, 219 {10, 16}, 220 {11, 20}, 221 {12, 24}, 222 {13, 32}, 223 {14, 48}, 224 {15, 64}, 225 }; 226 227 private enum TxScanModeInternal 228 { 229 Dedicated, 230 FIFO, 231 Queue, 232 MixedDedicatedFIFO, 233 MixedDedicatedQueue, 234 } 235 236 private enum RxBufferOrDebugDestination 237 { 238 StoreInRxBuffer = 0b00, 239 DebugMessageA = 0b01, 240 DebugMessageB = 0b10, 241 DebugMessageC = 0b11 242 } 243 244 private enum LastErrorCode 245 { 246 NoError = 0, 247 StuffError = 1, 248 FormError = 2, 249 AckError = 3, 250 Bit1Error = 4, 251 Bit0Error = 5, 252 CRCError = 6, 253 NoChange = 7 254 } 255 256 private enum Activity 257 { 258 Synchronizing = 0b00, 259 Idle = 0b01, 260 Receiver = 0b10, 261 Transmitter = 0b11 262 } 263 264 private enum FIFOOperationMode 265 { 266 Blocking = 0, 267 Overwrite = 1 268 } 269 270 private enum DebugMessageStatus 271 { 272 IdleState = 0b00, 273 DebugMessageA = 0b01, 274 DebugMessageAB = 0b10, 275 DebugMessageABC = 0b11 276 } 277 278 private enum NonMatchingFrameTarget 279 { 280 AcceptInRxFIFO0 = 0b00, 281 AcceptInRxFIFO1 = 0b01, 282 Reject_ = 0b10, 283 Reject__ = 0b11 284 } 285 286 private enum MessageStorageIndicator 287 { 288 NoFIFOselected = 0b00, 289 FIFOMessageLost = 0b01, 290 MessageInFIFO0 = 0b10, 291 MessageInFIFO1 = 0b11, 292 } 293 294 private enum Interrupt 295 { 296 RxFIFO0NewMessage = 0, // RF0N 297 RxFIFO0WatermarkReached = 1, // RF0W 298 RxFIFO0Full = 2, // RF0F 299 RxFIFO0MessageLost = 3, // RF0L 300 RxFIFO1NewMessage = 4, // RF1N 301 RxFIFO1WatermarkReached = 5, // RF1W 302 RxFIFO1Full = 6, // RF1F 303 RxFIFO1MessageLost = 7, // RF1L 304 HighPriorityMessage = 8, // HPM 305 TransmissionCompleted = 9, // TC 306 TransmissionCancellationFinished = 10, // TCF 307 TxFIFOEmpty = 11, // TFE 308 TxEventFIFONewEntry = 12, // TEFN 309 TxEventFIFOWatermarkReached = 13, // TEFW 310 TxEventFIFOFull = 14, // TEFF 311 TxEventFIFOElementLost = 15, // TEFL 312 TimestampWraparound = 16, // TSW 313 MessageRAMAccessFailure = 17, // MRAF 314 TimeoutOccurred = 18, // TOO 315 MessageStoredToDedicatedRxBuffer = 19, // DRX 316 BitErrorCorrected = 20, // BEC 317 BitErrorUncorrected = 21, // BEU 318 ErrorLoggingOverflow = 22, // ELO 319 ErrorPassive = 23, // EP 320 WarningStatus = 24, // EW 321 BusOffStatus = 25, // BO 322 WatchdogInterrupt = 26, // WDI 323 ProtocolErrorInArbitrationPhase = 27, // PEA 324 ProtocolErrorInDataPhase = 28, // PED 325 AccessToReservedAddress = 29 // ARA 326 } 327 328 private enum Control 329 { 330 Initialization = 0, // INIT 331 ConfigurationChangeEnable = 1, // CCE 332 RestrictedOperationMode = 2, // ASM 333 ClockStopAcknowledge = 3, // CSA 334 ClockStopRequest = 4, // CSR 335 BusMonitoringMode = 5, // MON 336 DisableAutomaticRetransmission = 6, // DAR 337 TestModeEnable = 7, // TEST 338 FDOperationEnable = 8, // FDOE 339 BitRateSwitchEnable = 9, // BRSE 340 UseTimestampingUnit = 10, // UTSU 341 WideMessageMarker = 11, // WMM 342 ProtocolExceptionHandlingDisable = 12, // PXHD 343 EdgeFilteringDuringBusIntegration = 13, // EFBI 344 TransmitPause = 14, // TXP 345 NonISOOperation = 15 // NISO 346 } 347 348 private enum Register 349 { 350 CoreReleaseRegister = 0x000, // CREL 351 EndianRegister = 0x004, // ENDN 352 CustomerRegister = 0x008, // CUST 353 DataBitTimingAndPrescalerRegister = 0x00c, // DBTP 354 TestRegister = 0x010, // TEST 355 RAMWatchdog = 0x014, // RWD 356 CCControlRegister = 0x018, // CCCR 357 NominalBitTimingAndPrescalerRegister = 0x01C, // NBTP 358 TimestampCounterConfiguration = 0x020, // TSCC 359 TimestampCounterValue = 0x024, // TSCV 360 TimeoutCounterConfiguration = 0x028, // TOCC 361 TimeoutCounterValue = 0x02C, // TOCV 362 ErrorCounterRegister = 0x040, // ECR 363 ProtocolStatusRegister = 0x044, // PSR 364 TransmitterDelayCompensationRegister = 0x048, // TDCR 365 InterruptRegister = 0x050, // IR 366 InterruptEnable = 0x054, // IE 367 InterruptLineSelect = 0x058, // ILS 368 InterruptLineEnable = 0x05C, // ILE 369 GlobalFilterConfiguration = 0x080, // GFC 370 StandardIDFilterConfiguration = 0x084, // SIDFC 371 ExtendedIDFilterConfiguration = 0x088, // XIDFC 372 ExtendedIdANDMask = 0x090, // XIDAM 373 HighPriorityMessageStatus = 0x094, // HPMS 374 NewData1 = 0x098, // NDAT1 375 NewData2 = 0x09C, // NDAT2 376 RxFIFO0Configuration = 0x0A0, // RXF0C 377 RxFIFO0Status = 0x0A4, // RXF0S 378 RxFIFO0Acknowledge = 0x0A8, // RXF0A 379 RxBufferConfiguration = 0x0AC, // RXBC 380 RxFIFO1Configuration = 0x0B0, // RXF1C 381 RxFIFO1Status = 0x0B4, // RXF1S 382 RxFIFO1Acknowledge = 0x0B8, // RXF1A 383 RxBufferFIFOElementSizeConfiguration = 0x0BC, // RXESC 384 TxBufferConfiguration = 0x0C0, // TXBC 385 TxFIFOQueueStatus = 0x0C4, // TXFQS 386 TxBufferElementSizeConfiguration = 0x0C8, // TXESC 387 TxBufferRequestPending = 0x0CC, // TXBRP 388 TxBufferAddRequest = 0x0D0, // TXBAR 389 TxBufferCancellationRequest = 0x0D4, // TXBCR 390 TxBufferTransmissionOccurred = 0x0D8, // TXBTO 391 TxBufferCancellationFinished = 0x0DC, // TXBCF 392 TxBufferTransmissionInterruptEnable = 0x0E0, // TXBTIE 393 TxBufferCancellationFinishedInterruptEnable = 0x0E4, // TXBCIE 394 TxEventFIFOConfiguration = 0x0F0, // TXEFC 395 TxEventFIFOStatus = 0x0F4, // TXEFS 396 TxEventFIFOAcknowledge = 0x0F8 // TXEFA 397 } 398 399 private enum FilterType 400 { 401 Range = 0b00, 402 DualID = 0b01, 403 Classic = 0b10, 404 RangeWithoutMask = 0b11 // valid only for Extended Filter 405 } 406 407 private enum FilterElementConfiguration 408 { 409 DisableFilter = 0b000, 410 RxFIFO0OnMatch = 0b001, 411 RxFIFO1OnMatch = 0b010, 412 RejectIDOnMatch = 0b011, 413 SetPriorityOnMatch = 0b100, 414 SetPriorityAndRxFIFO0OnMatch = 0b101, 415 SetPriorityAndRxFIFO1OnMatch = 0b110, 416 RxBufferOrDebugMessageOnMatch = 0b111 417 } 418 #pragma warning disable 649, 169 419 [LeastSignificantByteFirst] 420 private struct RxBufferElementHeader 421 { 422 [PacketField, Offset(doubleWords:0, bits: 0), Width(29)] 423 public uint Identifier; // ID 424 [PacketField, Offset(doubleWords:0, bits: 29), Width(1)] 425 public bool RemoteTransmissionRequest; // RTR 426 [PacketField, Offset(doubleWords:0, bits: 30), Width(1)] 427 public bool ExtendedIdentifier; // XTD 428 [PacketField, Offset(doubleWords:0, bits: 31), Width(1)] 429 public bool ErrorStateIndicator; // ESI 430 [PacketField, Offset(doubleWords:1, bits: 0), Width(16)] 431 public ushort RxTimestamp; // RXTS 432 [PacketField, Offset(doubleWords:1, bits: 16), Width(4)] 433 public byte DataLengthCode; // DLC 434 [PacketField, Offset(doubleWords:1, bits: 20), Width(1)] 435 public bool BitRateSwitch; // BRS 436 [PacketField, Offset(doubleWords:1, bits: 21), Width(1)] 437 public bool FDFormat; // FDF 438 [PacketField, Offset(doubleWords:1, bits: 22), Width(2)] 439 private byte Reserved; 440 [PacketField, Offset(doubleWords:1, bits: 24), Width(7)] 441 public byte FilterIndex; // FIDX 442 [PacketField, Offset(doubleWords:1, bits: 31), Width(1)] 443 public bool AcceptedNonMatchingFrame; // ANMF 444 } 445 446 [LeastSignificantByteFirst] 447 private struct RxBufferElementHeaderTSU 448 { 449 [PacketField, Offset(doubleWords:0, bits: 0), Width(29)] 450 public uint Identifier; // ID 451 [PacketField, Offset(doubleWords:0, bits: 29), Width(1)] 452 public bool RemoteTransmissionRequest; // RTR 453 [PacketField, Offset(doubleWords:0, bits: 30), Width(1)] 454 public bool ExtendedIdentifier; // XTD 455 [PacketField, Offset(doubleWords:0, bits: 31), Width(1)] 456 public bool ErrorStateIndicator; // ESI 457 [PacketField, Offset(doubleWords:1, bits: 0), Width(4)] 458 public byte RxTimestampPointer; // RXTSP 459 [PacketField, Offset(doubleWords:1, bits: 4), Width(1)] 460 public bool TimestampCaptured; // TSC 461 [PacketField, Offset(doubleWords:1, bits: 5), Width(11)] 462 private ushort Reserved0; 463 [PacketField, Offset(doubleWords:1, bits: 16), Width(4)] 464 public byte DataLengthCode; // DLC 465 [PacketField, Offset(doubleWords:1, bits: 20), Width(1)] 466 public bool BitRateSwitch; // BRS 467 [PacketField, Offset(doubleWords:1, bits: 21), Width(1)] 468 public bool FDFormat; // FDF 469 [PacketField, Offset(doubleWords:1, bits: 22), Width(2)] 470 private byte Reserved1; 471 [PacketField, Offset(doubleWords:1, bits: 24), Width(7)] 472 public byte FilterIndex; // FIDX 473 [PacketField, Offset(doubleWords:1, bits: 31), Width(1)] 474 public bool AcceptedNonMatchingFrame; // ANMF 475 } 476 477 [LeastSignificantByteFirst] 478 private struct TxScanBufferAndEventFIFOCommonHeader 479 { 480 [PacketField, Offset(doubleWords:0, bits: 0), Width(29)] 481 public uint Identifier; // ID 482 [PacketField, Offset(doubleWords:0, bits: 29), Width(1)] 483 public bool RemoteTransmissionRequest; // RTR 484 [PacketField, Offset(doubleWords:0, bits: 30), Width(1)] 485 public bool ExtendedIdentifier; // XTD 486 [PacketField, Offset(doubleWords:0, bits: 31), Width(1)] 487 public bool ErrorStateIndicator; // ESI 488 } 489 490 [LeastSignificantByteFirst] 491 private struct TxBufferElementHeader 492 { 493 [PacketField, Offset(doubleWords:0, bits: 0), Width(29)] 494 public uint Identifier; // ID 495 [PacketField, Offset(doubleWords:0, bits: 29), Width(1)] 496 public bool RemoteTransmissionRequest; // RTR 497 [PacketField, Offset(doubleWords:0, bits: 30), Width(1)] 498 public bool ExtendedIdentifier; // XTD 499 [PacketField, Offset(doubleWords:0, bits: 31), Width(1)] 500 public bool ErrorStateIndicator; // ESI 501 [PacketField, Offset(doubleWords:1, bits: 0), Width(8)] 502 private byte Reserved; 503 [PacketField, Offset(doubleWords:1, bits: 8), Width(8)] 504 public byte MessageMarkerHigh; // MM 505 [PacketField, Offset(doubleWords:1, bits: 16), Width(4)] 506 public byte DataLengthCode; // DLC 507 [PacketField, Offset(doubleWords:1, bits: 20), Width(1)] 508 public bool BitRateSwitch; // BRS 509 [PacketField, Offset(doubleWords:1, bits: 21), Width(1)] 510 public bool FDFormat; // FDF 511 [PacketField, Offset(doubleWords:1, bits: 22), Width(1)] 512 public bool TimeStampCaptureEnable; // TSCE 513 [PacketField, Offset(doubleWords:1, bits: 23), Width(1)] 514 public bool EventFIFOControl; // EFC 515 [PacketField, Offset(doubleWords:1, bits: 24), Width(8)] 516 public byte MessageMarkerLow; // MM 517 } 518 519 [LeastSignificantByteFirst] 520 private struct TxEventFIFOElement 521 { 522 [PacketField, Offset(doubleWords:0, bits: 0), Width(29)] 523 public uint Identifier; // ID 524 [PacketField, Offset(doubleWords:0, bits: 29), Width(1)] 525 public bool RemoteTransmissionRequest; // RTR 526 [PacketField, Offset(doubleWords:0, bits: 30), Width(1)] 527 public bool ExtendedIdentifier; // XTD 528 [PacketField, Offset(doubleWords:0, bits: 31), Width(1)] 529 public bool ErrorStateIndicator; // ESI 530 [PacketField, Offset(doubleWords:1, bits: 0), Width(16)] 531 public ushort TxTimestamp; // TXTS 532 [PacketField, Offset(doubleWords:1, bits: 16), Width(4)] 533 public byte DataLengthCode; // DLC 534 [PacketField, Offset(doubleWords:1, bits: 20), Width(1)] 535 public bool BitRateSwitch; // BRS 536 [PacketField, Offset(doubleWords:1, bits: 21), Width(1)] 537 public bool FDFormat; // FDF 538 [PacketField, Offset(doubleWords:1, bits: 22), Width(2)] 539 public byte EventType; // ET 540 [PacketField, Offset(doubleWords:1, bits: 24), Width(8)] 541 public byte MessageMarker; // MM 542 } 543 544 [LeastSignificantByteFirst] 545 private struct TxEventFIFOElementTSU 546 { 547 [PacketField, Offset(doubleWords:0, bits: 0), Width(29)] 548 public uint Identifier; // ID 549 [PacketField, Offset(doubleWords:0, bits: 29), Width(1)] 550 public bool RemoteTransmissionRequest; // RTR 551 [PacketField, Offset(doubleWords:0, bits: 30), Width(1)] 552 public bool ExtendedIdentifier; // XTD 553 [PacketField, Offset(doubleWords:0, bits: 31), Width(1)] 554 public bool ErrorStateIndicator; // ESI 555 [PacketField, Offset(doubleWords:1, bits: 0), Width(4)] 556 public byte TxTimestampPointer; // TXTSP 557 [PacketField, Offset(doubleWords:1, bits: 4), Width(1)] 558 public bool TimestampCaptured; // TSC 559 [PacketField, Offset(doubleWords:1, bits: 5), Width(3)] 560 private bool Reserved; 561 [PacketField, Offset(doubleWords:1, bits: 8), Width(8)] 562 public byte MessageMarkerHigh; // MM 563 [PacketField, Offset(doubleWords:1, bits: 16), Width(4)] 564 public byte DataLengthCode; // DLC 565 [PacketField, Offset(doubleWords:1, bits: 20), Width(1)] 566 public bool BitRateSwitch; // BRS 567 [PacketField, Offset(doubleWords:1, bits: 21), Width(1)] 568 public bool FDFormat; // FDF 569 [PacketField, Offset(doubleWords:1, bits: 22), Width(2)] 570 public byte EventType; // ET 571 [PacketField, Offset(doubleWords:1, bits: 24), Width(8)] 572 public byte MessageMarkerLow; // MM 573 } 574 575 [LeastSignificantByteFirst] 576 private struct StandardMessageIDFilterElement 577 { 578 [PacketField, Offset(doubleWords:0, bits: 0), Width(11)] 579 public ushort StandardFilterID2; // SFID2 580 [PacketField, Offset(doubleWords:0, bits: 11), Width(4)] 581 private byte Reserved; 582 [PacketField, Offset(doubleWords:0, bits: 15), Width(1)] 583 public bool StandardSyncMessage; // SSYNC 584 [PacketField, Offset(doubleWords:0, bits: 16), Width(11)] 585 public ushort StandardFilterID1; // SFID1 586 [PacketField, Offset(doubleWords:0, bits: 27), Width(3)] 587 public FilterElementConfiguration StandardFilterElementConfiguration; // SFEC 588 [PacketField, Offset(doubleWords:0, bits: 30), Width(2)] 589 public FilterType StandardFilterType; // SFT 590 } 591 592 [LeastSignificantByteFirst] 593 private struct ExtendedMessageIDFilterElement 594 { 595 [PacketField, Offset(doubleWords:0, bits: 0), Width(29)] 596 public uint ExtendedFilterID1; // EFID1 597 [PacketField, Offset(doubleWords:0, bits: 29), Width(3)] 598 public FilterElementConfiguration ExtendedFilterElementConfiguration; // EFEC 599 [PacketField, Offset(doubleWords:1, bits: 0), Width(29)] 600 public uint ExtendedFilterID2; // EFID2 601 [PacketField, Offset(doubleWords:1, bits: 29), Width(1)] 602 public bool ExtendedSyncMessage; // ESYNC 603 [PacketField, Offset(doubleWords:1, bits: 30), Width(2)] 604 public FilterType ExtendedFilterType; // EFT 605 } 606 #pragma warning restore 649, 169 607 608 // StandardMessageIDFilterElement and ExtendedMessageIDFilterElement have different layout in memory, 609 // but their fields have the same meaning, so we store them in a common structure for universal access. 610 private struct MessageIDFilterElement 611 { 612 public uint ID1; 613 public uint ID2; 614 public bool SyncMessage; 615 public FilterElementConfiguration FilterElementConfiguration; 616 public FilterType FilterType; 617 public bool IsExtended; 618 } 619 620 // RxFIFOnConfiguration + RxFIFOnStatus + RxFIFOnAcknowledge + RxBufferFIFOElementSizeConfiguration 621 // InterruptFlags: RxFIFOnMessageLost + RxFIFOnWatermarkReached + RxFIFOnFull + RxFIFOnNewMessage 622 private struct RxFIFOView 623 { 624 public IValueRegisterField StartAddress; 625 public IValueRegisterField Size; 626 public IValueRegisterField Watermark; 627 public IEnumRegisterField<FIFOOperationMode> OperationMode; 628 629 public IValueRegisterField GetIndexRaw; 630 public IValueRegisterField PutIndexRaw; 631 public IFlagRegisterField Full; 632 public IFlagRegisterField MessageLost; 633 634 public IValueRegisterField AcknowledgeIndex; 635 636 public IValueRegisterField DataFieldSize; 637 638 public IFlagRegisterField InterruptMessageLost; 639 public IFlagRegisterField InterruptWatermarkReached; 640 public IFlagRegisterField InterruptFull; 641 public IFlagRegisterField InterruptNewMessage; 642 643 public ulong RxFIFOFillLevel 644 { 645 get 646 { 647 if(Full.Value) 648 { 649 return Size.Value; 650 } 651 else if(PutIndexRaw.Value >= GetIndexRaw.Value) 652 { 653 return PutIndexRaw.Value - GetIndexRaw.Value; 654 } 655 else 656 { 657 return Size.Value - (GetIndexRaw.Value - PutIndexRaw.Value); 658 } 659 } 660 } 661 662 public ulong RxFIFOPutIndex 663 { 664 get 665 { 666 return PutIndexRaw.Value; 667 } 668 669 set 670 { 671 PutIndexRaw.Value = value % Size.Value; // circular queue 672 } 673 } 674 675 public ulong RxFIFOGetIndex 676 { 677 get 678 { 679 return GetIndexRaw.Value; 680 } 681 682 set 683 { 684 GetIndexRaw.Value = value % Size.Value; // circular queue 685 } 686 } 687 } 688 689 private struct FilterConfigurationView 690 { 691 public IFlagRegisterField RejectRemoteFrames; 692 public IEnumRegisterField<NonMatchingFrameTarget> AcceptNonMatchingFrames; 693 public IValueRegisterField FilterListStartAddress; 694 public IValueRegisterField ListSize; 695 } 696 697 private struct RxBufferView 698 { 699 public IValueRegisterField StartAddress; 700 public IValueRegisterField DataFieldSize; 701 } 702 703 private struct TxFIFOQueueView 704 { 705 public IValueRegisterField Offset; 706 public IValueRegisterField Size; 707 public IFlagRegisterField QueueMode; 708 public IValueRegisterField GetIndexRaw; 709 public IValueRegisterField PutIndexRaw; 710 public IFlagRegisterField FullRaw; 711 public IFlagRegisterField[] TransmissionRequestPendingFlags; 712 713 public bool Full 714 { 715 get 716 { 717 return FillLevel == Size.Value; 718 } 719 } 720 721 public ulong FillLevel 722 { 723 get 724 { 725 if(QueueMode.Value) 726 { 727 return Size.Value - FreeLevel; 728 } 729 else if(FullRaw.Value) 730 { 731 return Size.Value; 732 } 733 else if(PutIndexRaw.Value >= GetIndexRaw.Value) 734 { 735 return PutIndexRaw.Value - GetIndexRaw.Value; 736 } 737 else 738 { 739 return Size.Value - (GetIndexRaw.Value - PutIndexRaw.Value); 740 } 741 } 742 } 743 744 public ulong FreeLevel 745 { 746 get 747 { 748 if(QueueMode.Value) 749 { 750 var offset = (int)Offset.Value; 751 var size = (int)Size.Value; 752 var freeLevel = 0; 753 for(var i = offset; i < offset + size; i++) 754 { 755 if(!TransmissionRequestPendingFlags[i].Value) 756 { 757 freeLevel++; 758 } 759 } 760 return (ulong)freeLevel; 761 } 762 else 763 { 764 return Size.Value - FillLevel; 765 } 766 } 767 } 768 769 public ulong PutIndex 770 { 771 get 772 { 773 if(QueueMode.Value) 774 { 775 var offset = (int)Offset.Value; 776 var size = (int)Size.Value; 777 var putIndex = 0; 778 for(var i = offset; i < offset + size; i++) 779 { 780 if(!TransmissionRequestPendingFlags[i].Value) 781 { 782 putIndex = i; 783 break; 784 } 785 } 786 return (ulong)putIndex; 787 } 788 else 789 { 790 return PutIndexRaw.Value; 791 } 792 } 793 794 set 795 { 796 PutIndexRaw.Value = (value - Offset.Value) % Size.Value + Offset.Value; 797 } 798 } 799 800 public ulong GetIndex 801 { 802 get 803 { 804 return QueueMode.Value ? 0 : GetIndexRaw.Value; 805 } 806 807 set 808 { 809 GetIndexRaw.Value = (value - Offset.Value) % Size.Value + Offset.Value; 810 } 811 } 812 } 813 814 private struct TxBufferView 815 { 816 public IValueRegisterField StartAddress; 817 public IValueRegisterField NumberOfDedicatedTxBuffers; 818 public IValueRegisterField TxFIFOQueueSize; 819 public IFlagRegisterField TxFIFOQueueMode; 820 public IValueRegisterField DataFieldSize; 821 } 822 823 private struct TxEventFIFOView 824 { 825 public IValueRegisterField StartAddress; 826 public IValueRegisterField Size; 827 public IValueRegisterField Watermark; 828 public IValueRegisterField GetIndexRaw; 829 public IValueRegisterField PutIndexRaw; 830 public IFlagRegisterField Full; 831 public IFlagRegisterField ElementLost; 832 public IValueRegisterField AcknowledgeIndex; 833 834 public IFlagRegisterField InterruptNewEntry; 835 public IFlagRegisterField InterruptWatermarkReached; 836 public IFlagRegisterField InterruptFull; 837 public IFlagRegisterField InterruptElementLost; 838 839 public ulong FillLevel 840 { 841 get 842 { 843 if(Full.Value) 844 { 845 return Size.Value; 846 } 847 else if(PutIndexRaw.Value >= GetIndexRaw.Value) 848 { 849 return PutIndexRaw.Value - GetIndexRaw.Value; 850 } 851 else 852 { 853 return Size.Value - (GetIndexRaw.Value - PutIndexRaw.Value); 854 } 855 } 856 } 857 858 public ulong PutIndex 859 { 860 get 861 { 862 return PutIndexRaw.Value; 863 } 864 865 set 866 { 867 PutIndexRaw.Value = value % Size.Value; // circular queue 868 } 869 } 870 871 public ulong GetIndex 872 { 873 get 874 { 875 return GetIndexRaw.Value; 876 } 877 878 set 879 { 880 GetIndexRaw.Value = value % Size.Value; // circular queue 881 } 882 } 883 } 884 885 private struct RegisterMapView 886 { 887 public TestRegister TestRegister; 888 public CCControlRegister CCControlRegister; 889 public ProtocolStatusRegister ProtocolStatusRegister; 890 public InterruptRegister InterruptRegister; 891 public InterruptEnable InterruptEnable; 892 public InterruptLineSelect InterruptLineSelect; 893 public InterruptLineEnable InterruptLineEnable; 894 public GlobalFilterConfiguration GlobalFilterConfiguration; 895 public StandardIDFilterConfiguration StandardIDFilterConfiguration; 896 public ExtendedIDFilterConfiguration ExtendedIDFilterConfiguration; 897 public ExtendedIdANDMask ExtendedIdANDMask; 898 public HighPriorityMessageStatus HighPriorityMessageStatus; 899 public NewData1 NewData1; 900 public NewData2 NewData2; 901 public RxFIFO0Configuration RxFIFO0Configuration; 902 public RxFIFO0Status RxFIFO0Status; 903 public RxFIFO0Acknowledge RxFIFO0Acknowledge; 904 public RxBufferConfiguration RxBufferConfiguration; 905 public RxFIFO1Configuration RxFIFO1Configuration; 906 public RxFIFO1Status RxFIFO1Status; 907 public RxFIFO1Acknowledge RxFIFO1Acknowledge; 908 public RxBufferFIFOElementSizeConfiguration RxBufferFIFOElementSizeConfiguration; 909 public TxBufferConfiguration TxBufferConfiguration; 910 public TxFIFOQueueStatus TxFIFOQueueStatus; 911 public TxBufferElementSizeConfiguration TxBufferElementSizeConfiguration; 912 public TxBufferRequestPending TxBufferRequestPending; 913 public TxBufferAddRequest TxBufferAddRequest; 914 public TxBufferCancellationRequest TxBufferCancellationRequest; 915 public TxBufferTransmissionOccurred TxBufferTransmissionOccurred; 916 public TxBufferCancellationFinished TxBufferCancellationFinished; 917 public TxBufferTransmissionInterruptEnable TxBufferTransmissionInterruptEnable; 918 public TxBufferCancellationFinishedInterruptEnable TxBufferCancellationFinishedInterruptEnable; 919 public TxEventFIFOConfiguration TxEventFIFOConfiguration; 920 public TxEventFIFOStatus TxEventFIFOStatus; 921 public TxEventFIFOAcknowledge TxEventFIFOAcknowledge; 922 } 923 924 private struct TestRegister 925 { 926 public IFlagRegisterField LoopBackMode; 927 public IValueRegisterField TxBufferNumberPrepared; 928 public IFlagRegisterField PreparedValid; 929 public IValueRegisterField TxBufferNumberStarted; 930 public IFlagRegisterField StartedValid; 931 } 932 933 private struct CCControlRegister { 934 public IFlagRegisterField[] ControlFields; 935 } 936 937 private struct ProtocolStatusRegister 938 { 939 public IEnumRegisterField<LastErrorCode> LastErrorCode; 940 public IEnumRegisterField<Activity> Activity; 941 public IFlagRegisterField ReceivedCANFDMessage; 942 } 943 944 private struct InterruptRegister 945 { 946 public IFlagRegisterField[] InterruptFlags; 947 } 948 949 private struct InterruptEnable 950 { 951 public IFlagRegisterField[] InterruptEnableFlags; 952 } 953 954 private struct InterruptLineSelect 955 { 956 public IFlagRegisterField[] InterruptLineSelectFlags; 957 } 958 959 private struct InterruptLineEnable 960 { 961 public IFlagRegisterField EnableInterruptLine0; 962 public IFlagRegisterField EnableInterruptLine1; 963 } 964 965 private struct GlobalFilterConfiguration 966 { 967 public IFlagRegisterField RejectRemoteFramesExtended; 968 public IFlagRegisterField RejectRemoteFramesStandard; 969 public IEnumRegisterField<NonMatchingFrameTarget> AcceptNonMatchingFramesExtended; 970 public IEnumRegisterField<NonMatchingFrameTarget> AcceptNonMatchingFramesStandard; 971 } 972 973 private struct StandardIDFilterConfiguration 974 { 975 public IValueRegisterField FilterListStandardStartAddress; 976 public IValueRegisterField ListSizeStandard; 977 } 978 979 private struct ExtendedIDFilterConfiguration 980 { 981 public IValueRegisterField FilterListExtendedStartAddress; 982 public IValueRegisterField ListSizeExtended; 983 } 984 985 private struct ExtendedIdANDMask 986 { 987 public IValueRegisterField ExtendedIDANDMask; 988 } 989 990 private struct HighPriorityMessageStatus 991 { 992 public IValueRegisterField BufferIndex; 993 public IEnumRegisterField<MessageStorageIndicator> MessageStorageIndicator; 994 public IValueRegisterField FilterIndex; 995 public IFlagRegisterField FilterList; 996 } 997 998 private struct NewData1 999 { 1000 public IFlagRegisterField[] NewData1Flags; 1001 } 1002 1003 private struct NewData2 1004 { 1005 public IFlagRegisterField[] NewData2Flags; 1006 } 1007 1008 private struct RxFIFO0Configuration 1009 { 1010 public IValueRegisterField RxFIFO0StartAddress; 1011 public IValueRegisterField RxFIFO0Size; 1012 public IValueRegisterField RxFIFO0Watermark; 1013 public IEnumRegisterField<FIFOOperationMode> FIFO0OperationMode; 1014 } 1015 1016 private struct RxFIFO0Status 1017 { 1018 public IValueRegisterField RxFIFO0GetIndex; 1019 public IValueRegisterField RxFIFO0PutIndex; 1020 public IFlagRegisterField RxFIFO0Full; 1021 public IFlagRegisterField RxFIFO0MessageLost; 1022 } 1023 1024 private struct RxFIFO0Acknowledge 1025 { 1026 public IValueRegisterField RxFIFO0AcknowledgeIndex; 1027 } 1028 1029 private struct RxBufferConfiguration 1030 { 1031 public IValueRegisterField RxBufferStartAddress; 1032 } 1033 1034 private struct RxFIFO1Configuration 1035 { 1036 public IValueRegisterField RxFIFO1StartAddress; 1037 public IValueRegisterField RxFIFO1Size; 1038 public IValueRegisterField RxFIFO1Watermark; 1039 public IEnumRegisterField<FIFOOperationMode> FIFO1OperationMode; 1040 } 1041 1042 private struct RxFIFO1Status 1043 { 1044 public IValueRegisterField RxFIFO1GetIndex; 1045 public IValueRegisterField RxFIFO1PutIndex; 1046 public IFlagRegisterField RxFIFO1Full; 1047 public IFlagRegisterField RxFIFO1MessageLost; 1048 public IEnumRegisterField<DebugMessageStatus> DebugMessageStatus; 1049 } 1050 1051 private struct RxFIFO1Acknowledge 1052 { 1053 public IValueRegisterField RxFIFO1AcknowledgeIndex; 1054 } 1055 1056 private struct RxBufferFIFOElementSizeConfiguration 1057 { 1058 public IValueRegisterField RxFIFO0DataFieldSize; 1059 public IValueRegisterField RxFIFO1DataFieldSize; 1060 public IValueRegisterField RxBufferDataFieldSize; 1061 } 1062 1063 private struct TxBufferConfiguration 1064 { 1065 public IValueRegisterField TxBuffersStartAddress; 1066 public IValueRegisterField NumberOfDedicatedTxBuffers; 1067 public IValueRegisterField TxFIFOQueueSize; 1068 public IFlagRegisterField TxFIFOQueueMode; 1069 } 1070 1071 private struct TxFIFOQueueStatus 1072 { 1073 public IValueRegisterField TxFIFOGetIndex; 1074 public IValueRegisterField TxFIFOQueuePutIndex; 1075 public IFlagRegisterField TxFIFOQueueFull; 1076 } 1077 1078 private struct TxBufferElementSizeConfiguration 1079 { 1080 public IValueRegisterField TxBufferDataFieldSize; 1081 } 1082 1083 private struct TxBufferRequestPending 1084 { 1085 public IFlagRegisterField[] TransmissionRequestPendingFlags; 1086 } 1087 1088 private struct TxBufferAddRequest 1089 { 1090 public IFlagRegisterField[] AddRequestFlags; 1091 } 1092 1093 private struct TxBufferCancellationRequest 1094 { 1095 public IFlagRegisterField[] CancellationRequestFlags; 1096 } 1097 1098 private struct TxBufferTransmissionOccurred 1099 { 1100 public IFlagRegisterField[] TransmissionOccurredFlags; 1101 } 1102 1103 private struct TxBufferCancellationFinished 1104 { 1105 public IFlagRegisterField[] CancellationFinishedFlags; 1106 } 1107 1108 private struct TxBufferTransmissionInterruptEnable 1109 { 1110 public IFlagRegisterField[] TransmissionInterruptEnableFlags; 1111 } 1112 1113 private struct TxBufferCancellationFinishedInterruptEnable 1114 { 1115 public IFlagRegisterField[] CancellationFinishedInterruptEnableFlags; 1116 } 1117 1118 private struct TxEventFIFOConfiguration 1119 { 1120 public IValueRegisterField EventFIFOStartAddress; 1121 public IValueRegisterField EventFIFOSize; 1122 public IValueRegisterField EventFIFOWatermark; 1123 } 1124 1125 private struct TxEventFIFOStatus 1126 { 1127 public IValueRegisterField EventFIFOGetIndex; 1128 public IValueRegisterField EventFIFOPutIndex; 1129 public IFlagRegisterField EventFIFOFull; 1130 public IFlagRegisterField TxEventFIFOElementLost; 1131 } 1132 1133 private struct TxEventFIFOAcknowledge 1134 { 1135 public IValueRegisterField EventFIFOAcknowledgeIndex; 1136 } 1137 } 1138 } 1139