public LiteX_I2C_Zephyr(Machine machine) : base(machine) { // 0 - clock, 1 - data i2cDecoder = new BitPatternDetector(new [] { true, true }, this); i2cDecoder.RegisterPatternHandler((prev, curr) => !prev[ClockSignal] && curr[ClockSignal], name: "clockRising", action: HandleClockRising); i2cDecoder.RegisterPatternHandler((prev, curr) => prev[ClockSignal] && !curr[ClockSignal], name: "clockFalling", action: HandleClockFalling); i2cDecoder.RegisterPatternHandler((prev, curr) => prev[ClockSignal] && curr[ClockSignal] && prev[DataSignal] && !curr[DataSignal], name: "start", action: HandleStartCondition); i2cDecoder.RegisterPatternHandler((prev, curr) => prev[ClockSignal] && curr[ClockSignal] && !prev[DataSignal] && curr[DataSignal], name: "stop", action: HandleStopCondition); var registers = new Dictionary <long, DoubleWordRegister> { { (long)Registers.BitBang, new DoubleWordRegister(this, 0x5) // SCL && SDA are high by default .WithFlag(0, out var clockSignal, name: "SCL") .WithFlag(1, out var directionSignal, name: "OE") .WithFlag(2, out var dataSignal, name: "SDA") .WithWriteCallback((_, val) => i2cDecoder.AcceptState(new [] { clockSignal.Value, dataSignal.Value })) },
public LiteX_I2C_Zephyr(Machine machine) : base(machine) { // 0 - clock, 1 - data i2cDecoder = new BitPatternDetector(new [] { true, true }, this); i2cDecoder.RegisterPatternHandler((prev, curr) => !prev[ClockSignal] && curr[ClockSignal], name: "clockRising", action: HandleClockRising); i2cDecoder.RegisterPatternHandler((prev, curr) => prev[ClockSignal] && !curr[ClockSignal], name: "clockFalling", action: HandleClockFalling); i2cDecoder.RegisterPatternHandler((prev, curr) => prev[ClockSignal] && curr[ClockSignal] && prev[DataSignal] && !curr[DataSignal], name: "start", action: HandleStartCondition); i2cDecoder.RegisterPatternHandler((prev, curr) => prev[ClockSignal] && curr[ClockSignal] && !prev[DataSignal] && curr[DataSignal], name: "stop", action: HandleStopCondition); IFlagRegisterField clockSignal, directionSignal, dataSignal; var registers = new Dictionary <long, DoubleWordRegister> { { (long)Registers.BitBang, new DoubleWordRegister(this, 0x5) // SCL && SDA are high by default .WithFlag(0, out clockSignal, name: "SCL") .WithFlag(1, out directionSignal, name: "OE") .WithFlag(2, out dataSignal, name: "SDA") .WithWriteCallback((_, val) => i2cDecoder.AcceptState(new [] { clockSignal.Value, dataSignal.Value })) }, { (long)Registers.Data, new DoubleWordRegister(this) .WithFlag(0, FieldMode.Read, valueProviderCallback: _ => { if (directionSignal.Value) { this.Log(LogLevel.Warning, "Trying to read data, but the direction signal is set to OUTPUT"); return(true); } if (bufferFromDevice.Count == 0) { this.Log(LogLevel.Noisy, "There are no more output bits to read"); // SDA is high when no data return(true); } return(bufferFromDevice.Peek()); }) }, }; bufferFromDevice = new Queue <bool>(); bufferToDevice = new Stack <bool>(); bytesToDevice = new Queue <byte>(); registersCollection = new DoubleWordRegisterCollection(this, registers); Reset(); }