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