1 //
2 // Copyright (c) 2010-2018 Antmicro
3 // Copyright (c) 2011-2015 Realtime Embedded
4 //
5 // This file is licensed under the MIT License.
6 // Full license text is available in 'licenses/MIT.txt'.
7 //
8 using System;
9 using NUnit.Framework;
10 using Antmicro.Renode.Core;
11 using Antmicro.Renode.Peripherals.CAN;
12 using System.Threading;
13 using System.Diagnostics;
14 using System.Collections.Generic;
15 
16 namespace Antmicro.Renode.PeripheralsTests
17 {
18     [TestFixture]
19     public class STMCANTest
20     {
21         [Test]
InitTest()22         public void InitTest()
23         {
24             var stmcan = new STMCAN();
25             stmcan.Reset();
26             // Registers can only be accessed by words (32 bits)
27             // --> check this
28             // #####################################
29             // ### Check reset values of CAN control and status registers
30             // --- CAN_MCR
31             Assert.AreEqual(stmcan.ReadDoubleWord(0x00), 0x00010002);
32             // --- CAN_MSR
33             Assert.AreEqual(stmcan.ReadDoubleWord(0x04), 0x00000C02);
34             // --- CAN_TSR
35             Assert.AreEqual(stmcan.ReadDoubleWord(0x08), 0x1C000000);
36             // --- CAN_RF0R
37             Assert.AreEqual(stmcan.ReadDoubleWord(0x0C), 0x00000000);
38             // --- CAN_RF1R
39             Assert.AreEqual(stmcan.ReadDoubleWord(0x10), 0x00000000);
40             // --- CAN_IER
41             Assert.AreEqual(stmcan.ReadDoubleWord(0x14), 0x00000000);
42             // --- CAN_ESR
43             Assert.AreEqual(stmcan.ReadDoubleWord(0x18), 0x00000000);
44             // --- CAN_BTR (Can only be accessed during Initialization mode)
45             Assert.AreEqual(stmcan.ReadDoubleWord(0x1C), 0x00000000); // Cannot read
46             // Change to Initialization mode by setting INRQ (bit0) in CAN_MCR register
47             stmcan.WriteDoubleWord(0x00, 0x00010001);
48             // Verify Initialization mode by checking INAK bit set in CAN_MSR
49             // and that SLAK bit is cleared
50             Assert.AreEqual(stmcan.ReadDoubleWord(0x04), 0x00000C01);
51             Assert.AreEqual(stmcan.ReadDoubleWord(0x1C), 0x01230000);
52             // #####################################
53             // ### Check CAN mailbox registers
54             stmcan.Reset();
55             // --- CAN_TIxR - TXRQ reset value 0 (bit0)
56             Assert.AreEqual(stmcan.ReadDoubleWord(0x180) & 0x1, 0x0);
57             Assert.AreEqual(stmcan.ReadDoubleWord(0x190) & 0x1, 0x0);
58             Assert.AreEqual(stmcan.ReadDoubleWord(0x1A0) & 0x1, 0x0);
59             // --- CAN_TDTxR - bits 15:9, 7:4 are reserved
60             Assert.AreEqual(stmcan.ReadDoubleWord(0x184), 0x0);
61             Assert.AreEqual(stmcan.ReadDoubleWord(0x194), 0x0);
62             Assert.AreEqual(stmcan.ReadDoubleWord(0x1A4), 0x0);
63             // --- CAN_TDLxR - reset value undefined, model should reset to 0
64             Assert.AreEqual(stmcan.ReadDoubleWord(0x188), 0x0);
65             Assert.AreEqual(stmcan.ReadDoubleWord(0x198), 0x0);
66             Assert.AreEqual(stmcan.ReadDoubleWord(0x1A8), 0x0);
67             // --- CAN_TDHxR - reset value undefined, model should reset to 0
68             Assert.AreEqual(stmcan.ReadDoubleWord(0x18C), 0x0);
69             Assert.AreEqual(stmcan.ReadDoubleWord(0x19C), 0x0);
70             Assert.AreEqual(stmcan.ReadDoubleWord(0x1AC), 0x0);
71             // All RX registers are write protected
72             // --- CAN_RIxR - reset value undefined, bit0 reserved
73             stmcan.WriteDoubleWord(0x1B0, 0xFF0000FF);
74             stmcan.WriteDoubleWord(0x1C0, 0xFF0000FF);
75             Assert.AreEqual(stmcan.ReadDoubleWord(0x1B0) & 0x1, 0x0);
76             Assert.AreEqual(stmcan.ReadDoubleWord(0x1C0) & 0x1, 0x0);
77             // --- CAN_RDTxR - reset value undefined, bit7:4 reserved
78             stmcan.WriteDoubleWord(0x1B4, 0xFF0000FF);
79             stmcan.WriteDoubleWord(0x1C4, 0xFF0000FF);
80             Assert.AreEqual(stmcan.ReadDoubleWord(0x1B4) & 0x10, 0x0);
81             Assert.AreEqual(stmcan.ReadDoubleWord(0x1C4) & 0x10, 0x0);
82             // --- CAN_RDLxR - reset value undefined, model should reset to 0
83             stmcan.WriteDoubleWord(0x1B8, 0xFF0000FF);
84             stmcan.WriteDoubleWord(0x1C8, 0xFF0000FF);
85             Assert.AreEqual(stmcan.ReadDoubleWord(0x1B8), 0x0);
86             Assert.AreEqual(stmcan.ReadDoubleWord(0x1C8), 0x0);
87             // --- CAN_RDHxR - reset value undefined, model should reset to 0
88             stmcan.WriteDoubleWord(0x1BC, 0xFF0000FF);
89             stmcan.WriteDoubleWord(0x1CC, 0xFF0000FF);
90             Assert.AreEqual(stmcan.ReadDoubleWord(0x1BC), 0x0);
91             Assert.AreEqual(stmcan.ReadDoubleWord(0x1CC), 0x0);
92             // #####################################
93             // ### Check CAN filter registers
94             stmcan.Reset();
95             // --- CAN_FMR
96             Assert.AreEqual(stmcan.ReadDoubleWord(0x200), 0x2A1C0E01);
97             // --- CAN_FM1R - can only be written in filter initialization mode
98             Assert.AreEqual(stmcan.ReadDoubleWord(0x204), 0x00000000);
99             stmcan.WriteDoubleWord(0x204, 0xFF0000FF);
100             Assert.AreEqual(stmcan.ReadDoubleWord(0x204), 0xFF0000FF);
101             stmcan.WriteDoubleWord(0x200, 0x2A1C0E00);
102             Assert.AreEqual(stmcan.ReadDoubleWord(0x200), 0x2A1C0E00);
103             stmcan.WriteDoubleWord(0x204, 0x00FFFF00);
104             Assert.AreEqual(stmcan.ReadDoubleWord(0x204), 0xFF0000FF);
105             stmcan.WriteDoubleWord(0x200, 0x2A1C0E01);
106             // --- CAN_FS1R
107             Assert.AreEqual(stmcan.ReadDoubleWord(0x20C), 0x00000000);
108             stmcan.WriteDoubleWord(0x20C, 0xFF0000FF);
109             Assert.AreEqual(stmcan.ReadDoubleWord(0x20C), 0xFF0000FF);
110             stmcan.WriteDoubleWord(0x200, 0x2A1C0E00);
111             Assert.AreEqual(stmcan.ReadDoubleWord(0x200), 0x2A1C0E00);
112             stmcan.WriteDoubleWord(0x20C, 0x00FFFF00);
113             Assert.AreEqual(stmcan.ReadDoubleWord(0x20C), 0xFF0000FF);
114             stmcan.WriteDoubleWord(0x200, 0x2A1C0E01);
115             // --- CAN_FFA1R
116             Assert.AreEqual(stmcan.ReadDoubleWord(0x214), 0x00000000);
117             stmcan.WriteDoubleWord(0x214, 0xFF0000FF);
118             Assert.AreEqual(stmcan.ReadDoubleWord(0x214), 0xFF0000FF);
119             stmcan.WriteDoubleWord(0x200, 0x2A1C0E00);
120             Assert.AreEqual(stmcan.ReadDoubleWord(0x200), 0x2A1C0E00);
121             stmcan.WriteDoubleWord(0x214, 0x00FFFF00);
122             Assert.AreEqual(stmcan.ReadDoubleWord(0x214), 0xFF0000FF);
123             stmcan.WriteDoubleWord(0x200, 0x2A1C0E01);
124             // --- CAN_FA1R - bit 31:28 reserved
125             Assert.AreEqual(stmcan.ReadDoubleWord(0x21C), 0x00000000);
126             stmcan.WriteDoubleWord(0x21C, 0xF0000000);
127             Assert.AreEqual(stmcan.ReadDoubleWord(0x21C), 0x00000000);
128             // --- CAN_FiRx - 28 filter banks: reset value undefined, model should reset to 0
129             // Filter bank registers can only be modified when FACTx bit of CAN_FAxR register is cleared
130             // or when FINIT bit in CAN_FMR is set
131             int filterIndex = 0;
132             do
133             {
134                 Assert.AreEqual(stmcan.ReadDoubleWord(0x240 + filterIndex * 0x8), 0x00000000);
135                 stmcan.WriteDoubleWord((0x240 + filterIndex * 0x8), 0xFF0000FF);
136                 Assert.AreEqual(stmcan.ReadDoubleWord(0x240 + filterIndex * 0x8), 0xFF0000FF);
137                 stmcan.WriteDoubleWord(0x200, 0x2A1C0E00);
138                 Assert.AreEqual(stmcan.ReadDoubleWord(0x200), 0x2A1C0E00);
139                 stmcan.WriteDoubleWord((0x240 + filterIndex * 0x8), 0x00FFFF00);
140                 Assert.AreEqual(stmcan.ReadDoubleWord(0x240 + filterIndex * 0x8), 0x00FFFF00);
141                 filterIndex++;
142             }
143             while(filterIndex < 28);
144 
145         }
146 
147         [Test, Ignore("Ignored")]
LoopbackMessageTest()148         public void LoopbackMessageTest()
149         {
150             // #####################################
151             // ### Declarations
152             // CAN TX mailbox identifier register
153             uint can_tixr = 0;
154             // CAN TX mailbox data length control and time stamp register
155             uint can_tdtxr = 0;
156             // CAN TX mailbox data low register
157             uint can_tdlxr = 0;
158             // CAN TX mailbox data high register
159             uint can_tdhxr = 0;
160             // Message components
161             uint stdid = 0x321;
162             uint ide = 0; // std = 0; ext = 4
163             uint rtr = 0; // data frame = 0 ; remote frame = 2
164             uint txrq = 1;
165             uint time = 0;
166             uint tgt = 0;
167             uint dlc = 8; // data length, default to 8 bytes
168             byte[] txData = new byte[8] { 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8 };
169             // #####################################
170             // ### Setup CAN device
171             var stmcan = new STMCAN();
172             stmcan.Reset();
173             // Init mode
174             stmcan.WriteDoubleWord(0x00, 0x00010000);
175             Assert.AreEqual(stmcan.ReadDoubleWord(0x04), 0x00000C00);
176 
177             // ### Set filter for message
178             // --- CAN_FMR - init mode
179             var can_fmr = stmcan.ReadDoubleWord(0x200);
180             can_fmr |= 0x1;
181             stmcan.WriteDoubleWord(0x200, can_fmr);
182             // --- CAN_FA1R - deactivate filter nr 1
183             var can_fa1r = stmcan.ReadDoubleWord(0x21C);
184             can_fa1r &= 0xFFFFFFFD;
185             stmcan.WriteDoubleWord(0x21C, can_fa1r);
186             // Filter scale: 32-bit filter 1 identifier
187             var can_fs1r = stmcan.ReadDoubleWord(0x20C);
188             can_fs1r |= 0x1;
189             stmcan.WriteDoubleWord(0x20C, can_fs1r);
190             // Filter 1 identifiers = 0x321, 0x123 : set 0,0 currently
191             var can_fxr1 = stmcan.ReadDoubleWord(0x248);
192             can_fxr1 |= 0x0;
193             stmcan.WriteDoubleWord(0x248, can_fxr1);
194             var can_fxr2 = stmcan.ReadDoubleWord(0x250);
195             can_fxr2 |= 0x0;
196             stmcan.WriteDoubleWord(0x250, can_fxr2);
197             // --- CAN_FM1R - filter 1 is two 32-bit id list
198             var can_fm1r = stmcan.ReadDoubleWord(0x204);
199             can_fm1r |= 0x1;
200             stmcan.WriteDoubleWord(0x204, can_fm1r);
201             // --- CAN_FFA1R - assign FIFO 0
202             var can_ffa1r = stmcan.ReadDoubleWord(0x214);
203             can_ffa1r &= 0xFFFFFFFD;
204             stmcan.WriteDoubleWord(0x214, can_ffa1r);
205             // --- CAN_FA1R - activate filter nr 1
206             can_fa1r = stmcan.ReadDoubleWord(0x21C);
207             can_fa1r |= 0x1;
208             stmcan.WriteDoubleWord(0x21C, can_fa1r);
209 
210             // Enable loopback, set LBKM, bit30, in CAN_BTR
211             uint can_btr = stmcan.ReadDoubleWord(0x01C);
212             can_btr |= (1 << 30);
213             stmcan.WriteDoubleWord(0x01C, can_btr);
214             Assert.AreEqual(stmcan.ReadDoubleWord(0x01C), can_btr);
215 
216             // Set Normal mode
217             stmcan.WriteDoubleWord(0x00, 0x00010000);
218             Assert.AreEqual(stmcan.ReadDoubleWord(0x04), 0x00000C00);
219 
220             // #####################################
221             // ### Standard Identifier
222             // Setup message data registers and write to mailbox 0
223             can_tdtxr = (time << 16) | (tgt << 8) | dlc;
224             can_tdlxr = (uint)((txData[3] << 24) | (txData[2] << 16) | (txData[1] << 8) | txData[0]);
225             can_tdhxr = (uint)((txData[7] << 24) | (txData[6] << 16) | (txData[5] << 8) | txData[4]);
226             stmcan.WriteDoubleWord(0x184, can_tdtxr);
227             stmcan.WriteDoubleWord(0x188, can_tdlxr);
228             stmcan.WriteDoubleWord(0x18C, can_tdhxr);
229             // Setup id register and request transmission
230             can_tixr = (stdid << 21) | (ide << 2) | (rtr << 1) | txrq;
231             stmcan.WriteDoubleWord(0x180, can_tixr);
232             // Check RX FIFO 0, fetch message and release fifo
233             // CAN_RF0R bit 1:0 indicates pending RX messages
234             Assert.AreEqual(stmcan.ReadDoubleWord(0x0C) & 0x3, 0x1);
235             //Assert.AreEqual (stmcan.ReadDoubleWord(0x10) & 0x3, 0x1);
236             // read id from receive fifo 0 and verify 0x321 in bit 31:21
237             Assert.AreEqual(stmcan.ReadDoubleWord(0x1B0) & 0xFFE00000, (stdid << 21));
238             // read data from receive fifo 0 and verify 0x321 in bit 31:21
239             Assert.AreEqual(stmcan.ReadDoubleWord(0x1B8) & 0xFF, txData[0]);
240             // release RFOM0 fifo in CAN_RFR
241             // #####################################
242             // Extended Identifier
243             ide = 4;
244             // #####################################
245             // Remote Frame
246             rtr = 2;
247             // #####################################
248             // Error
249         }
250 
251         [Test, Ignore("Ignored")]
AnotherTest()252         public void AnotherTest()
253         {
254             var stmcan = new STMCAN();
255             stmcan.Reset();
256         }
257     }
258 }
259 
260