1 //
2 // Copyright (c) 2010-2024 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.Collections.Generic;
9 using System.Linq;
10 using Antmicro.Renode.Utilities;
11 using Antmicro.Renode.Utilities.Packets;
12 
13 namespace Antmicro.Renode.Peripherals.SENT
14 {
15     public class FastMessage
16     {
CalculateCRC(IEnumerable<byte> nibbles)17         public static byte CalculateCRC(IEnumerable<byte> nibbles)
18         {
19             // CRCEngine is not used here as it assumes working on bytes instead of nibbles
20             byte value = 5;
21             foreach(var nibble in nibbles)
22             {
23                 value = CRCTable[(value << 4) + nibble];
24             }
25             return CRCTable[value << 4];
26         }
27 
FastMessage(params byte[] nibbles)28         public FastMessage(params byte[] nibbles)
29         {
30             if(nibbles.Length < 1 || nibbles.Length > MaxFastMessageLength)
31             {
32                 throw new ArgumentException($"{nameof(nibbles)} Length ({nibbles.Length}) is out of range of [1;{MaxFastMessageLength}]");
33             }
34 
35             Nibbles = new byte[nibbles.Length + 1];
36             Array.Copy(nibbles, Nibbles, nibbles.Length);
37             Nibbles[Nibbles.Length - 1] = CalculateCRC(nibbles);
38         }
39 
40         private static readonly byte[] CRCTable = new byte[256]
41         {
42             0x0, 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8, 0x9, 0xA, 0xB, 0xC, 0xD, 0xE, 0xF,
43             0xD, 0xC, 0xF, 0xE, 0x9, 0x8, 0xB, 0xA, 0x5, 0x4, 0x7, 0x6, 0x1, 0x0, 0x3, 0x2,
44             0x7, 0x6, 0x5, 0x4, 0x3, 0x2, 0x1, 0x0, 0xF, 0xE, 0xD, 0xC, 0xB, 0xA, 0x9, 0x8,
45             0xA, 0xB, 0x8, 0x9, 0xE, 0xF, 0xC, 0xD, 0x2, 0x3, 0x0, 0x1, 0x6, 0x7, 0x4, 0x5,
46             0xE, 0xF, 0xC, 0xD, 0xA, 0xB, 0x8, 0x9, 0x6, 0x7, 0x4, 0x5, 0x2, 0x3, 0x0, 0x1,
47             0x3, 0x2, 0x1, 0x0, 0x7, 0x6, 0x5, 0x4, 0xB, 0xA, 0x9, 0x8, 0xF, 0xE, 0xD, 0xC,
48             0x9, 0x8, 0xB, 0xA, 0xD, 0xC, 0xF, 0xE, 0x1, 0x0, 0x3, 0x2, 0x5, 0x4, 0x7, 0x6,
49             0x4, 0x5, 0x6, 0x7, 0x0, 0x1, 0x2, 0x3, 0xC, 0xD, 0xE, 0xF, 0x8, 0x9, 0xA, 0xB,
50             0x1, 0x0, 0x3, 0x2, 0x5, 0x4, 0x7, 0x6, 0x9, 0x8, 0xB, 0xA, 0xD, 0xC, 0xF, 0xE,
51             0xC, 0xD, 0xE, 0xF, 0x8, 0x9, 0xA, 0xB, 0x4, 0x5, 0x6, 0x7, 0x0, 0x1, 0x2, 0x3,
52             0x6, 0x7, 0x4, 0x5, 0x2, 0x3, 0x0, 0x1, 0xE, 0xF, 0xC, 0xD, 0xA, 0xB, 0x8, 0x9,
53             0xB, 0xA, 0x9, 0x8, 0xF, 0xE, 0xD, 0xC, 0x3, 0x2, 0x1, 0x0, 0x7, 0x6, 0x5, 0x4,
54             0xF, 0xE, 0xD, 0xC, 0xB, 0xA, 0x9, 0x8, 0x7, 0x6, 0x5, 0x4, 0x3, 0x2, 0x1, 0x0,
55             0x2, 0x3, 0x0, 0x1, 0x6, 0x7, 0x4, 0x5, 0xA, 0xB, 0x8, 0x9, 0xE, 0xF, 0xC, 0xD,
56             0x8, 0x9, 0xA, 0xB, 0xC, 0xD, 0xE, 0xF, 0x0, 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7,
57             0x5, 0x4, 0x7, 0x6, 0x1, 0x0, 0x3, 0x2, 0xD, 0xC, 0xF, 0xE, 0x9, 0x8, 0xB, 0xA,
58         };
59 
60         public byte[] Nibbles { get; }
61 
62         private const int MaxFastMessageLength = 6;
63     }
64 
65     public class SlowMessage : FastMessage
66     {
SlowMessage(params byte[] nibbles)67         public SlowMessage(params byte[] nibbles) : base(nibbles)
68         {
69             if(nibbles.Length != ShortMessageNibbles)
70             {
71                 throw new ArgumentException($"Invalid nibble count. {ShortMessageNibbles} expected, got {nibbles.Length}");
72             }
73         }
74 
75         public IEnumerable<bool> Bits
76         {
77             get
78             {
79                 foreach(var nibble in Nibbles)
80                 {
81                     for(byte i = 0; i < 4; i++)
82                     {
83                         // Data from the slow messages is transmitted MSB first
84                         yield return BitHelper.IsBitSet(nibble, (byte)(3 - i));
85                     }
86                 }
87             }
88         }
89 
90         private const int ShortMessageNibbles = 3;
91     }
92 }
93