1 //
2 // Copyright (c) 2010-2022 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 Antmicro.Renode.Peripherals;
10 using Antmicro.Renode.Peripherals.I2C;
11 using Antmicro.Renode.Core;
12 using Antmicro.Renode.Utilities;
13 
14 namespace Antmicro.Renode.Extensions.Mocks
15 {
16     /* Example usage:
17     emulation AddMockI2CHost sysbus.i2c0
18     host.MockI2CHost WriteBytes 0x0 "010203040506070809"
19     host.MockI2CHost ReadBytes 0x0 9
20     host.MockI2CHost WriteBytes 0x0 "01"
21     */
22     public static class MockI2CHost
23     {
AddMockI2CHost(this Emulation emulation, II2CPeripheral device, string name = R)24         public static void AddMockI2CHost(this Emulation emulation, II2CPeripheral device, string name = "MockI2CHost")
25         {
26             emulation.HostMachine.AddHostMachineElement(new I2CHost(device), name);
27         }
28     }
29 
30     public class I2CHost : IHostMachineElement
31     {
I2CHost(II2CPeripheral device)32         public I2CHost(II2CPeripheral device)
33         {
34             currentSlave = device;
35         }
36 
WriteBytes(uint addr, string hexString)37         public void WriteBytes(uint addr, string hexString)
38         {
39             // addr + read_bit
40             var firstByte = (byte)(addr << 1) | 0x0;
41             var dataToSend = Misc.HexStringToByteArray(hexString);
42             var bytes = new byte[dataToSend.Length + 1];
43 
44             bytes[0] = (byte)firstByte;
45             Buffer.BlockCopy(dataToSend, 0, bytes, 1, dataToSend.Length);
46             currentSlave.Write(bytes);
47             currentSlave.FinishTransmission();
48         }
49 
ReadBytes(uint addr, int count)50         public byte[] ReadBytes(uint addr, int count)
51         {
52             var firstByte = (byte)(addr << 1) | 0x1;
53             currentSlave.Write(new byte[] { (byte)firstByte, (byte)count });
54             currentSlave.FinishTransmission();
55 
56             var returnedData = new List<byte>();
57             while(returnedData.Count != count)
58             {
59                 // Aggressive approach - this will block the monitor until finished.
60                 returnedData.AddRange(currentSlave.Read(count - returnedData.Count));
61             }
62             return returnedData.ToArray();
63         }
64 
65         private readonly II2CPeripheral currentSlave;
66     }
67 }
68