예제 #1
0
        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 })) },
예제 #2
0
        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();
        }