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.Core.Structure;
12 using Antmicro.Renode.Peripherals.Bus;
13 using Antmicro.Renode.Peripherals.I2C;
14 using Antmicro.Renode.Peripherals.Sensors;
15 using System.Threading;
16 using System.Diagnostics;
17 
18 namespace Antmicro.Renode.PeripheralsTests
19 {
20     [TestFixture]
21     public class EFM32GGI2CControllerTest
22     {
23         [Test]
InitTest()24         public void InitTest()
25         {
26             var machine = new Machine();
27             var efm32ggi2ccontroller = new EFM32GGI2CController(machine);
28             machine.SystemBus.Register(efm32ggi2ccontroller, new BusRangeRegistration(0x4000A000, 0x400));
29             efm32ggi2ccontroller.Reset();
30             Assert.AreEqual(efm32ggi2ccontroller.ReadDoubleWord(0x00), 0);
31             // Enable I2C controller
32             efm32ggi2ccontroller.WriteDoubleWord(0x0, 0x1);
33             Assert.AreEqual(efm32ggi2ccontroller.ReadDoubleWord(0x00), 0x1);
34             // Need check reset of interrupt flags before reading rx data (0x1C)
35             // as this will trigger RXUF if enabled
36             Assert.AreEqual(efm32ggi2ccontroller.ReadDoubleWord(0x28), 0);
37             // Check I2Cn_IEN before enabling interrupts
38             Assert.AreEqual(efm32ggi2ccontroller.ReadDoubleWord(0x34), 0);
39             // Enable all interrupts, bits 0-16
40             efm32ggi2ccontroller.WriteDoubleWord(0x34, 0x1FFFF);
41             Assert.AreEqual(efm32ggi2ccontroller.ReadDoubleWord(0x08), 0);
42             Assert.AreEqual(efm32ggi2ccontroller.ReadDoubleWord(0x0C), 0);
43             Assert.AreEqual(efm32ggi2ccontroller.ReadDoubleWord(0x10), 0);
44             Assert.AreEqual(efm32ggi2ccontroller.ReadDoubleWord(0x14), 0);
45             Assert.AreEqual(efm32ggi2ccontroller.ReadDoubleWord(0x18), 0);
46             Assert.AreEqual(efm32ggi2ccontroller.ReadDoubleWord(0x1C), 0);
47             Assert.AreEqual(efm32ggi2ccontroller.ReadDoubleWord(0x20), 0);
48             // IF - RXUF
49             Assert.AreEqual(efm32ggi2ccontroller.ReadDoubleWord(0x28), 0x2000);
50             Assert.AreEqual(efm32ggi2ccontroller.ReadDoubleWord(0x34), 0x1FFFF);
51             Assert.AreEqual(efm32ggi2ccontroller.ReadDoubleWord(0x38), 0);
52         }
53 
54         [Test]
CtrlTest()55         public void CtrlTest()
56         {
57             var machine = new Machine();
58             var efm32ggi2ccontroller = new EFM32GGI2CController(machine);
59             machine.SystemBus.Register(efm32ggi2ccontroller, new BusRangeRegistration(0x4000A000, 0x400));
60             efm32ggi2ccontroller.Reset();
61             uint ctrlValue = 0x1;
62             efm32ggi2ccontroller.WriteDoubleWord(0x0, ctrlValue);
63             Assert.AreEqual(efm32ggi2ccontroller.ReadDoubleWord(0x0), ctrlValue);
64         }
65 
66         [Test]
InterruptTest()67         public void InterruptTest()
68         {
69             var machine = new Machine();
70             var efm32ggi2ccontroller = new EFM32GGI2CController(machine);
71             machine.SystemBus.Register(efm32ggi2ccontroller, new BusRangeRegistration(0x4000A000, 0x400));
72             efm32ggi2ccontroller.Reset();
73 
74             // Enable I2C controller
75             efm32ggi2ccontroller.WriteDoubleWord(0x0, 0x1);
76             // Enable all interrupts, bits 0-16
77             efm32ggi2ccontroller.WriteDoubleWord(0x34, 0x1FFFF);
78             // Clear all interrupts
79             efm32ggi2ccontroller.WriteDoubleWord(0x30, 0x1FFFF);
80             Assert.AreEqual(efm32ggi2ccontroller.ReadDoubleWord(0x28), 0x0);
81             // Set Start, ACK, NACK interrupt flags
82             uint interruptMask = 0x1 | 0x40 | 0x80;
83             efm32ggi2ccontroller.WriteDoubleWord(0x2C, interruptMask);
84             // Check the result on interrupt register
85             Assert.AreEqual(efm32ggi2ccontroller.ReadDoubleWord(0x28), interruptMask);
86             // Clear all interrupts
87             efm32ggi2ccontroller.WriteDoubleWord(0x30, 0x1FFFF);
88             Assert.AreEqual(efm32ggi2ccontroller.ReadDoubleWord(0x28), 0x0);
89             // Send start command and check that start interrupt is flagged
90             efm32ggi2ccontroller.WriteDoubleWord(0x4, 0x1);
91             Assert.AreEqual(efm32ggi2ccontroller.ReadDoubleWord(0x28) & 0x1, 0x1);
92         }
93 
94         [Test, Ignore("Ignored")]
ReadFromSlaveTest()95         public void ReadFromSlaveTest()
96         {
97             var machine = new Machine();
98             var efm32ggi2ccontroller = new EFM32GGI2CController(machine);
99             machine.SystemBus.Register(efm32ggi2ccontroller, new BusRangeRegistration(0x4000A000, 0x400));
100             efm32ggi2ccontroller.Reset();
101             var bmp180 = new BMP180();
102             bmp180.Reset();
103             efm32ggi2ccontroller.Register(bmp180, new NumberRegistrationPoint<int>(0xEE));
104             // Enable I2C controller
105             uint ctrl = 0x1;
106             efm32ggi2ccontroller.WriteDoubleWord(0x0, ctrl);
107             // Enable all interrupts
108             uint interruptMask = 0x1FFFF;
109             efm32ggi2ccontroller.WriteDoubleWord(0x34, interruptMask);
110             // Clear all interrupts
111             efm32ggi2ccontroller.WriteDoubleWord(0x30, interruptMask);
112             // Check interrupt flags
113             uint interruptFlags = efm32ggi2ccontroller.ReadDoubleWord(0x28);
114             Assert.AreEqual(interruptFlags, 0x0);
115             // Write slave address byte to transmit buffer
116             uint txData = 0xEE; // Write address for BMP180
117             efm32ggi2ccontroller.WriteDoubleWord(0x24, txData);
118             // Check that the transmit buffers are not overflowing
119             interruptFlags = efm32ggi2ccontroller.ReadDoubleWord(0x28);
120             Assert.AreNotEqual((interruptFlags & 0x1000), 0x1000);
121             // Send start command
122             uint cmd = 0x1;
123             efm32ggi2ccontroller.WriteDoubleWord(0x4, cmd);
124             // Check slave ACK for address
125             interruptFlags = efm32ggi2ccontroller.ReadDoubleWord(0x28);
126             Assert.AreEqual((interruptFlags & 0x40), 0x40);
127             // Write slave BMP180 OutMSB Register Address
128             txData = 0xF6;
129             efm32ggi2ccontroller.WriteDoubleWord(0x24, txData);
130             // Check that the transmit buffers are not overflowing
131             interruptFlags = efm32ggi2ccontroller.ReadDoubleWord(0x28);
132             Assert.AreNotEqual((interruptFlags & 0x1000), 0x1000);
133             // Initiate read with writing BMP180 address byte with read bit set
134             // Send restart command
135             cmd = 0x1;
136             efm32ggi2ccontroller.WriteDoubleWord(0x4, cmd);
137             txData = 0xEF;
138             efm32ggi2ccontroller.WriteDoubleWord(0x24, txData);
139             // Check that the transmit buffers are not overflowing
140             interruptFlags = efm32ggi2ccontroller.ReadDoubleWord(0x28);
141             Assert.AreNotEqual((interruptFlags & 0xC), 0xC);
142             // Wait and check if the receive buffer has data
143             int loopCounter = 0;
144             do
145             {
146                 interruptFlags = efm32ggi2ccontroller.ReadDoubleWord(0x28);
147                 loopCounter++;
148                 Thread.Sleep(10);
149             }
150             while(((interruptFlags & 0x20) != 0x20) && (loopCounter < 1000));
151             Assert.AreEqual((interruptFlags & 0x20), 0x20);
152             Assert.AreNotEqual(loopCounter, 1000);
153             // Read MSB byte and see that it is the reset value 0x80
154             uint rxData = efm32ggi2ccontroller.ReadDoubleWord(0x1C);
155             Assert.AreEqual(rxData, 0x80);
156             // Send stop command
157             cmd = 0x2;
158             efm32ggi2ccontroller.WriteDoubleWord(0x4, cmd);
159             // Check that MSTOP interrupt has been issued
160             interruptFlags = efm32ggi2ccontroller.ReadDoubleWord(0x28);
161             Assert.AreEqual((interruptFlags & 0x100), 0x100);
162         }
163 
164         [Test, Ignore("Ignored")]
TemperatureMeasurementTest()165         public void TemperatureMeasurementTest()
166         {
167             var machine = new Machine();
168             var efm32ggi2ccontroller = new EFM32GGI2CController(machine);
169             machine.SystemBus.Register(efm32ggi2ccontroller, new BusRangeRegistration(0x4000A000, 0x400));
170             efm32ggi2ccontroller.Reset();
171             var bmp180 = new BMP180();
172             bmp180.Reset();
173             efm32ggi2ccontroller.Register(bmp180, new NumberRegistrationPoint<int>(0xEE));
174             // Enable I2C controller
175             uint ctrl = 0x1;
176             efm32ggi2ccontroller.WriteDoubleWord(0x0, ctrl);
177             // Enable all interrupts
178             uint interruptMask = 0x1FFFF;
179             efm32ggi2ccontroller.WriteDoubleWord(0x34, interruptMask);
180             // Send start command
181             uint cmd = 0x1;
182             efm32ggi2ccontroller.WriteDoubleWord(0x4, cmd);
183             // Check that the START flag was set
184             uint interruptFlags = efm32ggi2ccontroller.ReadDoubleWord(0x28);
185             Assert.AreEqual((interruptFlags & 0x1), 0x1);
186             // Write slave address byte to transmit buffer
187             uint txData = 0xEE; // Write address for BMP180
188             efm32ggi2ccontroller.WriteDoubleWord(0x24, txData);
189             // Check that the transmit buffers are not overflowing
190             interruptFlags = efm32ggi2ccontroller.ReadDoubleWord(0x28);
191             Assert.AreNotEqual((interruptFlags & 0x1000), 0x1000);
192             // Check slave ACK for address
193             interruptFlags = efm32ggi2ccontroller.ReadDoubleWord(0x28);
194             Assert.AreEqual((interruptFlags & 0x40), 0x40);
195             // Write more bytes for transmission, start temperature measurement
196             txData = 0xF4; // CtrlMeasurment Register Address
197             efm32ggi2ccontroller.WriteDoubleWord(0x24, txData);
198             // Check that the transmit buffers are not overflowing
199             interruptFlags = efm32ggi2ccontroller.ReadDoubleWord(0x28);
200             Assert.AreNotEqual((interruptFlags & 0x1000), 0x1000);
201             txData = 0x2E; // Temperature measurement code
202             efm32ggi2ccontroller.WriteDoubleWord(0x24, txData);
203             // Check that the transmit buffers are not overflowing
204             interruptFlags = efm32ggi2ccontroller.ReadDoubleWord(0x28);
205             Assert.AreNotEqual((interruptFlags & 0x1000), 0x1000);
206 
207             // Wait 5 milliseconds, (> 4.5 is ok - see Datasheet for BMP180)
208             Thread.Sleep(5);
209 
210             // Start read by specifying OutMSB register
211             // - this will return MSB and LSB for sequential reads
212             // Send restart command
213             cmd = 0x1;
214             efm32ggi2ccontroller.WriteDoubleWord(0x4, cmd);
215             // Write slave address byte to transmit buffer
216             txData = 0xEE; // Write address for BMP180
217             efm32ggi2ccontroller.WriteDoubleWord(0x24, txData);
218             // Check that the transmit buffers are not overflowing
219             interruptFlags = efm32ggi2ccontroller.ReadDoubleWord(0x28);
220             Assert.AreNotEqual((interruptFlags & 0x1000), 0x1000);
221             // Check slave ACK for address
222             interruptFlags = efm32ggi2ccontroller.ReadDoubleWord(0x28);
223             Assert.AreEqual((interruptFlags & 0x40), 0x40);
224             // Write OutMSB Register Address
225             txData = 0xF6;
226             efm32ggi2ccontroller.WriteDoubleWord(0x24, txData);
227             // Check that the transmit buffers are not overflowing
228             interruptFlags = efm32ggi2ccontroller.ReadDoubleWord(0x28);
229             Assert.AreNotEqual((interruptFlags & 0x1000), 0x1000);
230 
231             // Send restart command
232             cmd = 0x1;
233             efm32ggi2ccontroller.WriteDoubleWord(0x4, cmd);
234             // Tell BMP180 sensor we will read
235             txData = 0xEF; // Write address for BMP180
236             efm32ggi2ccontroller.WriteDoubleWord(0x24, txData);
237             // Check that the transmit buffers are not overflowing
238             interruptFlags = efm32ggi2ccontroller.ReadDoubleWord(0x28);
239             Assert.AreNotEqual((interruptFlags & 0x1000), 0x1000);
240 
241             // Read byte from slave through controller rx buffer (register address 0x1C)
242             // Check if read data is available - RXDATAV interrupt flag
243             bool finishedRead = false;
244             uint[] rxData = new uint[2] { 0, 0 };
245             uint index = 0;
246             uint loopCounter = 0;
247             while(!finishedRead)
248             {
249                 interruptFlags = efm32ggi2ccontroller.ReadDoubleWord(0x28);
250                 if((interruptFlags & 0x20) == 0x20)
251                 {
252                     rxData[index++] = efm32ggi2ccontroller.ReadDoubleWord(0x1C);
253                 }
254                 if(index == 2 || loopCounter == 1000)
255                 {
256                     finishedRead = true;
257                 }
258                 Thread.Sleep(10);
259                 loopCounter++;
260             }
261             Assert.AreNotEqual(loopCounter, 1000);
262             uint temperature = ((rxData[0] << 8) & 0xFF00) + rxData[1];
263             Assert.Greater(temperature, 0);
264             // Send stop command
265             cmd = 0x2;
266             efm32ggi2ccontroller.WriteDoubleWord(0x4, cmd);
267         }
268 
269         [Test]
DualI2CAddressBMC050Test()270         public void DualI2CAddressBMC050Test()
271         {
272             var machine = new Machine();
273             var efm32ggi2ccontroller = new EFM32GGI2CController(machine);
274             machine.SystemBus.Register(efm32ggi2ccontroller, new BusRangeRegistration(0x4000A000, 0x400));
275             efm32ggi2ccontroller.Reset();
276             var bmc050 = new BMC050();
277             bmc050.Reset();
278             efm32ggi2ccontroller.Register(bmc050, new NumberRegistrationPoint<int>(0x18));
279             efm32ggi2ccontroller.Register(bmc050, new NumberRegistrationPoint<int>(0x10));
280             ////////////////////////////////////////////////////////////
281             // Setup the EFM32GG I2C controller
282             // Enable I2C controller
283             uint ctrl = 0x1;
284             efm32ggi2ccontroller.WriteDoubleWord(0x0, ctrl);
285             // Enable all interrupts
286             uint interruptMask = 0x1FFFF;
287             efm32ggi2ccontroller.WriteDoubleWord(0x34, interruptMask);
288             ////////////////////////////////////////////////////////////
289             // Write BMC050 accelerometer slave address byte to transmit buffer
290             // Send start command
291             uint cmd = 0x1;
292             efm32ggi2ccontroller.WriteDoubleWord(0x4, cmd);
293             // Check that the START flag was set
294             uint interruptFlags = efm32ggi2ccontroller.ReadDoubleWord(0x28);
295             Assert.AreEqual((interruptFlags & 0x1), 0x1);
296             uint txData = 0x18; // Write address for BMC050 accelerometer
297             efm32ggi2ccontroller.WriteDoubleWord(0x24, txData);
298             // Check that the transmit buffers are not overflowing
299             interruptFlags = efm32ggi2ccontroller.ReadDoubleWord(0x28);
300             Assert.AreNotEqual((interruptFlags & 0x1000), 0x1000);
301             // Check slave ACK for address
302             interruptFlags = efm32ggi2ccontroller.ReadDoubleWord(0x28);
303             Assert.AreEqual((interruptFlags & 0x40), 0x40);
304             // Write slave BMC050 accelerometer chip ID register address
305             txData = 0x0;
306             efm32ggi2ccontroller.WriteDoubleWord(0x24, txData);
307             // Check that the transmit buffers are not overflowing
308             interruptFlags = efm32ggi2ccontroller.ReadDoubleWord(0x28);
309             Assert.AreNotEqual((interruptFlags & 0x1000), 0x1000);
310             // Initiate read with writing BMC050 acc address byte with read bit set
311             // Send restart command
312             cmd = 0x1;
313             efm32ggi2ccontroller.WriteDoubleWord(0x4, cmd);
314             txData = 0x19;
315             efm32ggi2ccontroller.WriteDoubleWord(0x24, txData);
316             // Check that the transmit buffers are not overflowing
317             interruptFlags = efm32ggi2ccontroller.ReadDoubleWord(0x28);
318             Assert.AreNotEqual((interruptFlags & 0xC), 0xC);
319             // Wait and check if the receive buffer has data
320             int loopCounter = 0;
321             do
322             {
323                 interruptFlags = efm32ggi2ccontroller.ReadDoubleWord(0x28);
324                 loopCounter++;
325                 Thread.Sleep(10);
326             }
327             while(((interruptFlags & 0x20) != 0x20) && (loopCounter < 1000));
328             Assert.AreEqual((interruptFlags & 0x20), 0x20);
329             Assert.AreNotEqual(loopCounter, 1000);
330             // Read MSB byte and see that it is the correct value
331             uint rxData = efm32ggi2ccontroller.ReadDoubleWord(0x1C);
332             Assert.AreEqual(rxData, 0x3);
333             // Send stop command
334             cmd = 0x2;
335             efm32ggi2ccontroller.WriteDoubleWord(0x4, cmd);
336             // Check that MSTOP interrupt has been issued
337             interruptFlags = efm32ggi2ccontroller.ReadDoubleWord(0x28);
338             Assert.AreEqual((interruptFlags & 0x100), 0x100);
339             ////////////////////////////////////////////////////////////
340             // Send start command
341             cmd = 0x1;
342             efm32ggi2ccontroller.WriteDoubleWord(0x4, cmd);
343             // Check that the START flag was set
344             interruptFlags = efm32ggi2ccontroller.ReadDoubleWord(0x28);
345             Assert.AreEqual((interruptFlags & 0x1), 0x1);
346             // Write BMC050 magnetometer slave address byte to transmit buffer
347             txData = 0x10; // Write address for BMC050 Magnetometer
348             efm32ggi2ccontroller.WriteDoubleWord(0x24, txData);
349             // Check that the transmit buffers are not overflowing
350             interruptFlags = efm32ggi2ccontroller.ReadDoubleWord(0x28);
351             Assert.AreNotEqual((interruptFlags & 0x1000), 0x1000);
352             // Check slave ACK for address
353             interruptFlags = efm32ggi2ccontroller.ReadDoubleWord(0x28);
354             Assert.AreEqual((interruptFlags & 0x40), 0x40);
355             // Write slave BMC050 magnetometer chip ID register address
356             txData = 0x40;
357             efm32ggi2ccontroller.WriteDoubleWord(0x24, txData);
358             // Check that the transmit buffers are not overflowing
359             interruptFlags = efm32ggi2ccontroller.ReadDoubleWord(0x28);
360             Assert.AreNotEqual((interruptFlags & 0x1000), 0x1000);
361             // Initiate read with writing BMC050 mag address byte with read bit set
362             // Send restart command
363             cmd = 0x1;
364             efm32ggi2ccontroller.WriteDoubleWord(0x4, cmd);
365             txData = 0x11;
366             efm32ggi2ccontroller.WriteDoubleWord(0x24, txData);
367             // Check that the transmit buffers are not overflowing
368             interruptFlags = efm32ggi2ccontroller.ReadDoubleWord(0x28);
369             Assert.AreNotEqual((interruptFlags & 0xC), 0xC);
370             // Wait and check if the receive buffer has data
371             loopCounter = 0;
372             do
373             {
374                 interruptFlags = efm32ggi2ccontroller.ReadDoubleWord(0x28);
375                 loopCounter++;
376                 Thread.Sleep(10);
377             }
378             while(((interruptFlags & 0x20) != 0x20) && (loopCounter < 1000));
379             Assert.AreEqual((interruptFlags & 0x20), 0x20);
380             Assert.AreNotEqual(loopCounter, 1000);
381             // Read MSB byte and see that it is the reset value 0x01
382             rxData = efm32ggi2ccontroller.ReadDoubleWord(0x1C);
383             Assert.AreEqual(rxData, 0x32);
384             // Send stop command
385             cmd = 0x2;
386             efm32ggi2ccontroller.WriteDoubleWord(0x4, cmd);
387             // Check that MSTOP interrupt has been issued
388             interruptFlags = efm32ggi2ccontroller.ReadDoubleWord(0x28);
389             Assert.AreEqual((interruptFlags & 0x100), 0x100);
390         }
391     }
392 }
393 
394