Example #1
0
 public void WriteDoubleWord(long offset, uint value)
 {
     WriteBytes(offset, BitHelper.GetBytesFromValue(value, sizeof(uint)));
 }
        public PSE_GPIO(Machine machine) : base(machine, 32)
        {
            locker     = new object();
            IRQ        = new GPIO();
            irqManager = new GPIOInterruptManager(IRQ, State);

            var registersMap = new Dictionary <long, DoubleWordRegister>
            {
                { (long)Registers.InterruptRegister, new DoubleWordRegister(this)
                  .WithValueField(0, 32,
                                  writeCallback: (_, val) =>
                    {
                        foreach (var i in BitHelper.GetSetBits(val))
                        {
                            irqManager.ClearInterrupt((uint)i);
                            if ((irqManager.PinDirection[i] & GPIOInterruptManager.Direction.Input) != 0)
                            {
                                Connections[i].Set(false);
                            }
                        }
                    },
                                  valueProviderCallback: _ => BitHelper.GetValueFromBitsArray(irqManager.ActiveInterrupts), name: "INTR") },

                { (long)Registers.InputRegister, new DoubleWordRegister(this)
                  .WithValueField(0, 32, out inputReg, FieldMode.Read,
                                  valueProviderCallback: val =>
                    {
                        var readOperations = irqManager.PinDirection.Select(x => x == GPIOInterruptManager.Direction.Input);
                        var result         = readOperations.Zip(BitHelper.GetBits(inputReg.Value), (operation, bit) => operation && bit);
                        return(BitHelper.GetValueFromBitsArray(result));
                    }, name: "GPIN") },

                { (long)Registers.OutputRegister, new DoubleWordRegister(this)
                  .WithValueField(0, 32,
                                  valueProviderCallback: val =>
                    {
                        var writeOperations = irqManager.PinDirection.Select(x => x == GPIOInterruptManager.Direction.Output);
                        var result          = writeOperations.Zip(BitHelper.GetBits(val), (operation, bit) => operation && bit);
                        return(BitHelper.GetValueFromBitsArray(result));
                    },
                                  writeCallback: (_, val) =>
                    {
                        // Potentially we should raise an exception, as GPIO is bidirectional,
                        // but we do not have such infrastructure.
                        var bits = BitHelper.GetBits(val);
                        for (var i = 0; i < bits.Length; i++)
                        {
                            if ((irqManager.PinDirection[i] & GPIOInterruptManager.Direction.Output) != 0)
                            {
                                Connections[i].Set(bits[i]);
                            }
                        }
                    }, name: "GPOUT") },

                { (long)Registers.ClearRegister, new DoubleWordRegister(this)
                  .WithValueField(0, 32, writeCallback: (_, val) => SetRegisterBits(val, false), name: "CLEAR_BITS") },

                { (long)Registers.SetRegister, new DoubleWordRegister(this)
                  .WithValueField(0, 32, writeCallback: (_, val) => SetRegisterBits(val, true), name: "SET_BITS") },
            };

            var intTypeToVal = new TwoWayDictionary <GPIOInterruptManager.InterruptTrigger, uint>();

            intTypeToVal.Add(GPIOInterruptManager.InterruptTrigger.ActiveHigh, 0);
            intTypeToVal.Add(GPIOInterruptManager.InterruptTrigger.ActiveLow, 1);
            intTypeToVal.Add(GPIOInterruptManager.InterruptTrigger.RisingEdge, 2);
            intTypeToVal.Add(GPIOInterruptManager.InterruptTrigger.FallingEdge, 3);
            intTypeToVal.Add(GPIOInterruptManager.InterruptTrigger.BothEdges, 4);

            for (var i = 0; i < RegisterLength; i++)
            {
                var j = i;
                registersMap.Add(i * RegisterOffset, new DoubleWordRegister(this)
                                 .WithFlag(0,
                                           writeCallback: (_, val) =>
                {
                    if (val)
                    {
                        irqManager.PinDirection[j] |= GPIOInterruptManager.Direction.Output;
                    }
                    else
                    {
                        irqManager.PinDirection[j] &= ~GPIOInterruptManager.Direction.Output;
                    }
                },
                                           valueProviderCallback: _ => (irqManager.PinDirection[j] & GPIOInterruptManager.Direction.Output) != 0, name: "OutputRegEnable")
                                 .WithFlag(1,
                                           writeCallback: (_, value) =>
                {
                    if (value)
                    {
                        irqManager.PinDirection[j] |= GPIOInterruptManager.Direction.Input;
                    }
                    else
                    {
                        irqManager.PinDirection[j] &= ~GPIOInterruptManager.Direction.Input;
                    }
                },
                                           valueProviderCallback: _ => (irqManager.PinDirection[j] & GPIOInterruptManager.Direction.Input) != 0, name: "InputRegEnable")
                                 .WithTag("OutputBufferEnable", 2, 1)
                                 .WithFlag(3, writeCallback: (_, v) => { irqManager.InterruptEnable[j] = v; }, valueProviderCallback: _ => irqManager.InterruptEnable[j], name: "InterruptEnable")
                                 .WithReservedBits(4, 1)
                                 .WithValueField(5, 3,
                                                 writeCallback: (_, value) =>
                {
                    if (!intTypeToVal.TryGetValue(value, out var type))
                    {
                        this.Log(LogLevel.Warning, "Invalid interrupt type for pin #{0}: {1}", j, value);
                        return;
                    }
                    irqManager.InterruptType[j] = type;
                },
                                                 valueProviderCallback: _ => intTypeToVal[irqManager.InterruptType[j]], name: "InterruptType"));
            }
            registers = new DoubleWordRegisterCollection(this, registersMap);
        }
Example #3
0
        public void WriteDoubleWord(long offset, uint value)
        {
            if (offset >= SetEnableStart && offset < SetEnableEnd)
            {
                EnableOrDisableInterrupt((int)offset - SetEnableStart, value, true);
                return;
            }
            if (offset >= PriorityStart && offset < PriorityEnd)
            {
                HandlePriorityWrite(offset - PriorityStart, true, value);
                return;
            }
            if (offset >= ClearEnableStart && offset < ClearEnableEnd)
            {
                EnableOrDisableInterrupt((int)offset - ClearEnableStart, value, false);
                return;
            }
            if (offset >= ClearPendingStart && offset < ClearPendingEnd)
            {
                SetOrClearPendingInterrupt((int)offset - ClearPendingStart, value, false);
                return;
            }
            if (offset >= SetPendingStart && offset < SetPendingEnd)
            {
                SetOrClearPendingInterrupt((int)offset - SetPendingStart, value, true);
                return;
            }
            switch ((Registers)offset)
            {
            case Registers.SysTickControl:
                systick.EventEnabled = ((value & 2) >> 1) != 0;
                this.NoisyLog("Systick interrupt {0}.", systick.EventEnabled ? "enabled" : "disabled");
                systick.Enabled = (value & 1) != 0;
                this.NoisyLog("Systick timer {0}.", systick.Enabled ? "enabled" : "disabled");
                break;

            case Registers.SysTickReloadValue:
                systick.Limit = value & SysTickMaximumValue;
                if (value > SysTickMaximumValue)
                {
                    this.Log(LogLevel.Warning, "Given value {0} exceeds maximum available {1}. Writing {2}", value, SysTickMaximumValue, systick.Limit);
                }
                break;

            case Registers.SysTickValue:
                systick.Value = systick.Limit;
                break;

            case Registers.InterruptControlState:
                if ((value & (1u << 28)) != 0)
                {
                    SetPendingIRQ(14);
                }
                if ((value & (1u << 31)) != 0)
                {
                    SetPendingIRQ(2);
                }
                break;

            case Registers.VectorTableOffset:
                cpu.VectorTableOffset = value & 0xFFFFFF80;
                break;

            case Registers.ApplicationInterruptAndReset:
                var key = value >> 16;
                if (key != VectKey)
                {
                    this.DebugLog("Wrong key while accessing Application Interrupt and Reset Control register 0x{0:X}.", key);
                    break;
                }
                binaryPointPosition = (int)(value >> 8) & 7;
                if (BitHelper.IsBitSet(value, 2))
                {
                    resetMachine();
                }
                break;

            case Registers.SystemControlRegister:
                if ((value & DeepSleep) != 0)
                {
                    systick.Enabled = false;
                    this.NoisyLog("Entering deep sleep");
                }
                else if ((value & ~DeepSleep) != 0)
                {
                    this.Log(LogLevel.Warning, "Unhandled value written to System Control Register: 0x{0:X}.", value & ~DeepSleep);
                }
                break;

            case Registers.SystemHandlerPriority1:
                // 7th interrupt is ignored
                priorities[4] = (byte)value;
                priorities[5] = (byte)(value >> 8);
                priorities[6] = (byte)(value >> 16);
                this.DebugLog("Priority of IRQs 4, 5, 6 set to 0x{0:X}, 0x{1:X}, 0x{2:X} respectively.", (byte)value, (byte)(value >> 8), (byte)(value >> 16));
                break;

            case Registers.SystemHandlerPriority2:
                // only 11th is not ignored
                priorities[11] = (byte)(value >> 24);
                this.DebugLog("Priority of IRQ 11 set to 0x{0:X}.", (byte)(value >> 24));
                break;

            case Registers.SystemHandlerPriority3:
                priorities[14] = (byte)(value >> 16);
                priorities[15] = (byte)(value >> 24);
                this.DebugLog("Priority of IRQs 14, 15 set to 0x{0:X}, 0x{1:X} respectively.", (byte)(value >> 16), (byte)(value >> 24));
                break;

            case Registers.SystemHandlerControlAndState:
                this.DebugLog("Write to SHCS register. This is not yet implemented. Value written was 0x{0:X}.", value);
                break;

            case Registers.CoprocessorAccessControl:
                // for ARM v8 and CP10 values:
                //      0b11 Full access to the FP Extension and MVE
                //      0b01 Privileged access only to the FP Extension and MVE
                //      0b00 No access to the FP Extension and MVE
                //      0b10 Reserved
                // Any attempted use without access generates a NOCP UsageFault.
                // same for ARM v7, but if values of CP11 and CP10 differ then effects are unpredictable
                cpu.CPACR = value;
                // Enable FPU if any access is permitted, privilege checks in tlib use CPACR register.
                if ((value & 0x100000) == 0x100000)
                {
                    this.DebugLog("Enabling FPU.");
                    cpu.FpuEnabled = true;
                }
                else
                {
                    this.DebugLog("Disabling FPU.");
                    cpu.FpuEnabled = false;
                }
                break;

            case Registers.SoftwareTriggerInterruptRegister:
                // This register is implemented only in ARMv7m and ARMv8m
                if (cpu.Model == "cortex-m3" || cpu.Model == "cortex-m4" || cpu.Model == "cortex-m7")
                {
                    SetPendingIRQ((int)(16 + value));
                }
                else
                {
                    this.Log(LogLevel.Error, "Software Trigger Interrupt Register not implemented for {0}", cpu.Model);
                }
                break;

            case Registers.FPContextControl:
                if (!IsPrivilegedMode())
                {
                    this.Log(LogLevel.Warning, "Writing to FPContextControl requires privileged access.");
                    break;
                }
                cpu.FPCCR = value;
                break;

            case Registers.FPContextAddress:
                if (!IsPrivilegedMode())
                {
                    this.Log(LogLevel.Warning, "Writing to FPContextAddress requires privileged access.");
                    break;
                }
                // address must be 8-byte aligned
                cpu.FPCAR = value & ~0x3u;
                break;

            case Registers.FPDefaultStatusControl:
                if (!IsPrivilegedMode())
                {
                    this.Log(LogLevel.Warning, "Writing to FPDefaultStatusControl requires privileged access.");
                    break;
                }
                // set only not reserved values
                cpu.FPDSCR = value & 0x07c00000;
                break;

            default:
                this.LogUnhandledWrite(offset, value);
                break;
            }
        }
Example #4
0
 /// <summary>
 /// Sets a binary tag in a WMA encoding.
 /// </summary>
 /// <param name="Handle">The encoder handle.</param>
 /// <param name="Tag">The tag to set.</param>
 /// <param name="Length">The number of bytes provided as binary data in the tag.</param>
 /// <param name="Value">The byte[] containing the binary tag's data.</param>
 /// <returns>If succesful, <see langword="true" /> is returned, else <see langword="false" /> is returned. Use <see cref="Bass.LastError" /> to get the error code.</returns>
 /// <remarks>
 /// Where the tags are located in the encoded stream depends on when this function is used.
 /// Calling this function before beginning encoding data puts the tags in the stream's header.
 /// Calling this function after encoding has begun puts the tags in the actual stream data, at the current encoding position.
 /// <para>Header tags must be set before encoding any data - no more header tags can be set once <see cref="EncodeWrite(int,IntPtr,int)" /> has been called.</para>
 /// <para>
 /// To set tags mid-stream (after encoding has begun), the <see cref="WMAEncodeFlags.Script"/> flag needs to have been specified in the encoder's creation.
 /// A mid-stream tag typically used is "Caption", which get's displayed in Windows Media Player 9 and above (if the user has enabled captions).
 /// </para>
 /// <para>
 /// When using a network encoder, it should be noted that while all header tags are sent to newly connecting clients, prior mid-stream tags are not.
 /// So if, for example, you're using the "Caption" tag to indicate the current song title, it should be sent at fairly regular intervals (not only at the start of the song).
 /// </para>
 /// <para>On the playback side, mid-stream tags can be processed using <see cref="Bass.ChannelSetSync" /> (with <see cref="SyncFlags.MetadataReceived"/>).</para>
 /// </remarks>
 /// <exception cref="Errors.Handle"><paramref name="Handle" /> is not valid.</exception>
 /// <exception cref="Errors.NotAvailable">The encoder does not have mid-stream tags enabled, so tags can not be set once encoding has begun.</exception>
 /// <exception cref="Errors.Parameter"><paramref name="Tag" /> and/or <paramref name="Value" /> is invalid.</exception>
 /// <exception cref="Errors.Unknown">Some other mystery problem!</exception>
 public static bool EncodeSetTag(int Handle, string Tag, byte[] Value, int Length)
 {
     return(BASS_WMA_EncodeSetTag(Handle, Tag, Value, (WMATagFormat)BitHelper.MakeLong((short)WMATagFormat.Binary, (short)Length)));
 }
Example #5
0
        public void WriteDoubleWord(long offset, uint value)
        {
            if (offset >= SetEnableStart && offset < SetEnableEnd)
            {
                EnableOrDisableInterrupt((int)offset - SetEnableStart, value, true);
                return;
            }
            if (offset >= PriorityStart && offset < PriorityEnd)
            {
                HandlePriorityWrite(offset - PriorityStart, true, value);
                return;
            }
            if (offset >= ClearEnableStart && offset < ClearEnableEnd)
            {
                EnableOrDisableInterrupt((int)offset - ClearEnableStart, value, false);
                return;
            }
            if (offset >= ClearPendingStart && offset < ClearPendingEnd)
            {
                SetOrClearPendingInterrupt((int)offset - ClearPendingStart, value, false);
                return;
            }
            if (offset >= SetPendingStart && offset < SetPendingEnd)
            {
                SetOrClearPendingInterrupt((int)offset - SetPendingStart, value, true);
                return;
            }
            switch ((Registers)offset)
            {
            case Registers.SysTickControl:
                systick.EventEnabled = ((value & 2) >> 1) != 0;
                this.NoisyLog("Systick interrupt {0}.", systick.EventEnabled ? "enabled" : "disabled");
                systick.Enabled = (value & 1) != 0;
                this.NoisyLog("Systick timer {0}.", systick.Enabled ? "enabled" : "disabled");
                break;

            case Registers.SysTickReloadValue:
                systick.Limit = value & SysTickMaximumValue;
                if (value > SysTickMaximumValue)
                {
                    this.Log(LogLevel.Warning, "Given value {0} exceeds maximum available {1}. Writing {2}", value, SysTickMaximumValue, systick.Limit);
                }
                break;

            case Registers.SysTickValue:
                systick.Value = systick.Limit;
                break;

            case Registers.InterruptControlState:
                if ((value & (1u << 28)) != 0)
                {
                    SetPendingIRQ(14);
                }
                if ((value & (1u << 31)) != 0)
                {
                    SetPendingIRQ(2);
                }
                break;

            case Registers.VectorTableOffset:
                cpu.VectorTableOffset = value & 0xFFFFFF80;
                break;

            case Registers.ApplicationInterruptAndReset:
                var key = value >> 16;
                if (key != VectKey)
                {
                    this.DebugLog("Wrong key while accessing Application Interrupt and Reset Control register 0x{0:X}.", key);
                    break;
                }
                binaryPointPosition = (int)(value >> 8) & 7;
                if (BitHelper.IsBitSet(value, 2))
                {
                    resetMachine();
                }
                break;

            case Registers.SystemControlRegister:
                if ((value & DeepSleep) != 0)
                {
                    systick.Enabled = false;
                    this.NoisyLog("Entering deep sleep");
                }
                else if ((value & ~DeepSleep) != 0)
                {
                    this.Log(LogLevel.Warning, "Unhandled value written to System Control Register: 0x{0:X}.", value & ~DeepSleep);
                }
                break;

            case Registers.SystemHandlerPriority1:
                // 7th interrupt is ignored
                priorities[4] = (byte)value;
                priorities[5] = (byte)(value >> 8);
                priorities[6] = (byte)(value >> 16);
                this.DebugLog("Priority of IRQs 4, 5, 6 set to 0x{0:X}, 0x{1:X}, 0x{2:X} respectively.", (byte)value, (byte)(value >> 8), (byte)(value >> 16));
                break;

            case Registers.SystemHandlerPriority2:
                // only 11th is not ignored
                priorities[11] = (byte)(value >> 24);
                this.DebugLog("Priority of IRQ 11 set to 0x{0:X}.", (byte)(value >> 24));
                break;

            case Registers.SystemHandlerPriority3:
                priorities[14] = (byte)(value >> 16);
                priorities[15] = (byte)(value >> 24);
                this.DebugLog("Priority of IRQs 14, 15 set to 0x{0:X}, 0x{1:X} respectively.", (byte)(value >> 16), (byte)(value >> 24));
                break;

            case Registers.SystemHandlerControlAndState:
                this.DebugLog("Write to SHCS register. This is not yet implemented. Value written was 0x{0:X}.", value);
                break;

            case Registers.CoprocessorAccessControl:
                // if CP10 and CP11 both are set to full access (0b11) - turn on FPU
                if ((value & 0xF00000) == 0xF00000)
                {
                    this.DebugLog("Enabling FPU.");
                    cpu.FpuEnabled = true;
                }
                else
                {
                    this.DebugLog("Disabling FPU.");
                    cpu.FpuEnabled = false;
                }
                break;

            default:
                this.LogUnhandledWrite(offset, value);
                break;
            }
        }
        private void DecodeBtn_Click(object sender, RoutedEventArgs e)
        {
            int?   errorPosition;
            string correctMessage;

            int[] controlBits;
            recived = hamming.Receive(
                DisturbedBits.Where(x => !x.IsSeparator).Select(x => x.Value ? 1 : 0).ToArray(),
                out errorPosition, out correctMessage, out controlBits);
            string recivedBits = BitHelper.IntsToString(recived);

            recivedBitsTxt.Text = recivedBits;
            Debug.WriteLine($"correct message: {correctMessage}");
            byte[] recivedBytes = BinaryToBytes(recivedBits);
            recivedTxt.Text = GetString(recivedBytes);
            if (errorPosition == null)
            {
                errorsNumberTxt.Text = "Brak błędów";
            }
            else
            {
                errorsNumberTxt.Text = errorPosition.Value.ToString();
            }

            var errors = new List <BitStatus>();

            foreach (var bit in DisturbedBits)
            {
                errors.Add(new BitStatus()
                {
                    Value       = bit.Value,
                    IsSeparator = bit.IsSeparator,
                    Status      = bit.Status == ErroCode.Null ? ErroCode.Ok : bit.Status
                });
            }

            okBitsLbl.Content      = new NumberToLabelConverter().Convert(errors.Where(x => x.Status == ErroCode.Ok && !x.IsSeparator).Count(), typeof(string), null, Thread.CurrentThread.CurrentCulture);
            controlBitsLbl.Content = new NumberToLabelConverter().Convert(errors.Where(x => x.Status == ErroCode.ControlBit).Count(), typeof(string), null, Thread.CurrentThread.CurrentCulture);

            if (errorPosition != null)
            {
                errors.Reverse();
                fixedBitsLbl.Content    = string.Empty;
                fixedControlLbl.Content = string.Empty;

                if (errors.Where(x => !x.IsSeparator).ToArray()[errorPosition.Value - 1].Status == ErroCode.ControllBitError)
                {
                    errors.Where(x => !x.IsSeparator).ToArray()[errorPosition.Value - 1].Status = ErroCode.ControlBitFixed;
                    fixedControlLbl.Content = new NumberToLabelConverter().Convert(1, typeof(string), null, Thread.CurrentThread.CurrentCulture);
                }
                else
                {
                    errors.Where(x => !x.IsSeparator).ToArray()[errorPosition.Value - 1].Status = ErroCode.ErrorFixed;
                    fixedBitsLbl.Content = new NumberToLabelConverter().Convert(1, typeof(string), null, Thread.CurrentThread.CurrentCulture);
                }
                errors.Where(x => !x.IsSeparator).ToArray()[errorPosition.Value - 1].Value ^= true;
                errors.Reverse();
                notDetectdLbl.Content = new NumberToLabelConverter().Convert(errors.Where(x => x.Status == ErroCode.ErrorNotDetected).Count(), typeof(string), null, Thread.CurrentThread.CurrentCulture);
            }
            ErrorsBx.ItemsSource = errors;

            if (controlBits.Where(x => x != 0).Count() > 0)
            {
                controBitsTxt.Text = string.Join(", ", controlBits.Where(x => x != 0).Select(x => $"p{x}"));
            }
        }
        public PlatformLevelInterruptController(Machine machine, int numberOfSources, int numberOfTargets = 1, bool prioritiesEnabled = true)
        {
            if (numberOfTargets != 1)
            {
                throw new ConstructionException($"Current {this.GetType().Name} implementation does not support more than one target");
            }
            // numberOfSources has to fit between these two registers, one bit per source
            if (Math.Ceiling((numberOfSources + 1) / 32.0) * 4 > Registers.Target1Enables - Registers.Target0Enables)
            {
                throw new ConstructionException($"Current {this.GetType().Name} implementation more than {Registers.Target1Enables - Registers.Target0Enables} sources");
            }

            this.prioritiesEnabled = prioritiesEnabled;

            this.machine = machine;
            IRQ          = new GPIO();
            // irqSources are initialized from 1, as the source "0" is not used.
            irqSources = new IrqSource[numberOfSources + 1];
            for (var i = 1; i <= numberOfSources; i++)
            {
                irqSources[i] = new IrqSource();
            }
            activeInterrupts = new Stack <uint>();

            var registersMap = new Dictionary <long, DoubleWordRegister>
            {
                { (long)Registers.Target0ClaimComplete, new DoubleWordRegister(this).WithValueField(0, 32, valueProviderCallback: _ =>
                    {
                        return(AcknowledgePendingInterrupt());
                    }, writeCallback: (_, value) =>
                    {
                        CompleteHandlingInterrupt(value);
                    }
                                                                                                    ) }
            };

            registersMap.Add((long)Registers.Source0Priority, new DoubleWordRegister(this)
                             .WithValueField(0, 3, FieldMode.Read,
                                             writeCallback: (_, value) => { if (value != 0)
                                                                            {
                                                                                this.Log(LogLevel.Warning, $"Trying to set priority {value} to Source 0, which is illegal");
                                                                            }
                                             }));
            for (var i = 1; i <= numberOfSources; i++)
            {
                var j = i;
                registersMap[(long)Registers.Source1Priority * i] = new DoubleWordRegister(this)
                                                                    .WithValueField(0, 3,
                                                                                    valueProviderCallback: (_) => irqSources[j].Priority,
                                                                                    writeCallback: (_, value) => { if (prioritiesEnabled)
                                                                                                                   {
                                                                                                                       irqSources[j].Priority = value;
                                                                                                                   }
                                                                                    });
            }

            var vectorWidth = (uint)Registers.Target1Enables - (uint)Registers.Target0Enables;
            var maximumSourceDoubleWords = (int)Math.Ceiling((numberOfSources + 1) / 32.0) * 4;

            // When writing to TargetXEnables registers, the user will get an error in log when he tries to write to an
            // unused bit of a register that is at least partially used. A warning will be issued on a usual undefined register access otherwise.
            for (var target = 0u; target < numberOfTargets; target++)
            {
                for (var offset = 0u; offset < maximumSourceDoubleWords; offset += 4)
                {
                    var lTarget = target;
                    var lOffset = offset;
                    registersMap.Add((long)Registers.Target0Enables + (vectorWidth * target) + offset, new DoubleWordRegister(this).WithValueField(0, 32, writeCallback: (_, value) =>
                    {
                        lock (irqSources)
                        {
                            // Each source is represented by one bit. offset and lOffset indicate the offset in double words from TargetXEnables,
                            // `bit` is the bit number in the given double word,
                            // and `sourceIdBase + bit` indicate the source number.
                            var sourceIdBase = lOffset * 8;
                            var bits         = BitHelper.GetBits(value);
                            for (var bit = 0u; bit < bits.Length; bit++)
                            {
                                if (sourceIdBase + bit == 0)
                                {
                                    //Source number 0 is not used.
                                    continue;
                                }
                                if (irqSources.Length <= (sourceIdBase + bit))
                                {
                                    if (bits[bit])
                                    {
                                        this.Log(LogLevel.Error, "Trying to enable non-existing source: {0}", sourceIdBase + bit);
                                    }
                                    continue;
                                }
                                var targets = irqSources[sourceIdBase + bit].EnabledTargets;
                                if (bits[bit])
                                {
                                    targets.Add(lTarget);
                                }
                                else
                                {
                                    targets.Remove(lTarget);
                                }
                            }
                            RefreshInterrupts();
                        }
                    }));
                }
            }

            registers = new DoubleWordRegisterCollection(this, registersMap);
        }
Example #8
0
        public void WriteDoubleWord(long offset, uint value)
        {
            lock (localLock)
            {
                var val = -1;
                if ((val = IsOffsetInRange((uint)offset, (uint)Register.SourceModeRegister0, 0x04, 32)) != -1)
                {
                    this.Log(LogLevel.Noisy, "This was write to Source Mode Register {0}", val);
                    sourceModeRegisters[val] = value;
                    return;
                }

                if ((val = IsOffsetInRange((uint)offset, (uint)Register.SourceVectorRegister0, 0x04, 32)) != -1)
                {
                    this.Log(LogLevel.Noisy, "This was write to Source Vector Register {0}", val);
                    sourceVectorRegisters[val] = value;
                    return;
                }

                switch ((Register)offset)
                {
                case Register.EndofInterruptCommandRegister:

                    if (nestedInterruptStack.Count > 0)
                    {
                        var irq = nestedInterruptStack.Pop();
                        //CurrentIRQ = irq.Item1;
                        BitHelper.SetBit(ref interruptPendingRegister, (byte)irq.Item1, true);
                    }
                    else
                    {
                        if (CurrentIRQ.HasValue)
                        {
                            BitHelper.SetBit(ref interruptPendingRegister, (byte)CurrentIRQ, false);
                        }
                        this.Log(LogLevel.Noisy, "IRQ set to false");
                        IRQ.Set(false);
                    }

                    CurrentIRQ = null;

                    // save to this register indicates the end of the interrupt handling
                    break;

                case Register.InterruptEnableCommandRegister:
                    interruptMaskRegister |= value;
                    break;

                case Register.SpuriousInterruptVectorRegister:
                    spouriousInterruptVectorRegister = value;
                    break;

                //case Register.DebugControlRegister:
                //debugControlRegister = value;
                //    break;

                case Register.InterruptClearCommandRegister:

                    foreach (var irq in BitHelper.GetSetBits(value))
                    {
                        if (IsInternalPositiveEdgeTriggered(irq))
                        {
                            BitHelper.SetBit(ref interruptPendingRegister, (byte)irq, false);
                        }
                    }

                    break;

                case Register.InterruptDisableCommandRegister:
                    interruptMaskRegister &= ~value;
                    //interruptPendingRegister &= ~value;
                    break;

                default:
                    this.LogUnhandledWrite(offset, value);
                    return;
                }
            }
        }
        private void DefineRegisters()
        {
            PhyRegisters.CardDetect.Define(this)
            // note: `true` means *no* card
            .WithFlag(0, FieldMode.Read, name: "card_detect", valueProviderCallback: _ => RegisteredPeripheral == null)
            .WithReservedBits(1, 31);

            CoreRegisters.Argument.DefineMany(coreRegistersCollection, 4, (register, idx) =>
            {
                register
                .WithValueField(0, 8, name: $"argument{idx}", writeCallback: (_, val) =>
                {
                    BitHelper.ReplaceBits(ref argumentValue, width: 8, source: val, destinationPosition: 24 - idx * 8);
                })
                .WithIgnoredBits(8, 24);
            });

            CoreRegisters.Command0.Define(coreRegistersCollection)
            .WithIgnoredBits(0, 32);

            CoreRegisters.Command1.Define(coreRegistersCollection)
            .WithIgnoredBits(0, 32);

            CoreRegisters.Command2.Define(coreRegistersCollection)
            .WithValueField(0, 7, out commandIndexField, name: "command_index")
            .WithReservedBits(7, 1)
            .WithIgnoredBits(8, 24);

            CoreRegisters.Command3.Define(coreRegistersCollection)
            .WithEnumField <DoubleWordRegister, ResponseType>(0, 3, out responseTypeField, name: "respone_type")
            .WithReservedBits(3, 2)
            .WithEnumField <DoubleWordRegister, TransferType>(5, 3, out transferTypeField, name: "transfer_type")
            .WithIgnoredBits(8, 24);

            CoreRegisters.IssueCommand.Define(coreRegistersCollection)
            .WithFlag(0, FieldMode.WriteOneToClear, name: "issue_command", writeCallback: (_, val) =>
            {
                if (!val)
                {
                    // we are only interested in `true`
                    return;
                }

                if (RegisteredPeripheral == null)
                {
                    this.Log(LogLevel.Warning, "Issued a 0x{0:X} command with 0x{1:X} argument, but there is no SD card attached", commandIndexField.Value, argumentValue);
                    return;
                }

                this.Log(LogLevel.Noisy, "Issuing command #{0}, transfer type is {1}, response type is {2}", commandIndexField.Value, transferTypeField.Value, responseTypeField.Value);

                var resp = RegisteredPeripheral.HandleCommand(commandIndexField.Value, argumentValue).AsByteArray();

                this.Log(LogLevel.Noisy, "Received response of size {0}", resp.Length);
#if DEBUG_PACKETS
                this.Log(LogLevel.Noisy, Misc.PrettyPrintCollectionHex(resp));
#endif

                var expectedResponseLength = 0;

                switch (responseTypeField.Value)
                {
                case ResponseType.Short:
                    expectedResponseLength = 4;
                    break;

                case ResponseType.Long:
                    expectedResponseLength = 16;
                    break;
                }

                if (resp.Length != expectedResponseLength)
                {
                    this.Log(LogLevel.Warning, "Expected response of length {0} bytes, but received {1} bytes", expectedResponseLength, resp.Length);
                    return;
                }

                for (var i = 0; i < resp.Length; i++)
                {
                    responseBuffer[ResponseBufferLength - 1 - i] = resp[i];
                }

                switch (transferTypeField.Value)
                {
                case TransferType.Read:
                    if (readerStartFlag.Value)
                    {
                        readerStartFlag.Value = false;
                        ReadData();
                    }
                    break;

                case TransferType.Write:
                    if (writerStartFlag.Value)
                    {
                        writerStartFlag.Value = false;
                        WriteData();
                    }
                    break;
                }
            })
            .WithReservedBits(1, 7)
            .WithReservedBits(8, 24);

            CoreRegisters.Response.DefineMany(coreRegistersCollection, ResponseBufferLength, (register, idx) =>
            {
                register
                .WithValueField(0, 8, FieldMode.Read, name: $"Response{idx}", valueProviderCallback: _ =>
                {
                    return(responseBuffer[idx]);
                })
                .WithIgnoredBits(8, 24);
            });

            CoreRegisters.CommandEvent0.Define(coreRegistersCollection)
            .WithIgnoredBits(0, 32);

            CoreRegisters.CommandEvent1.Define(coreRegistersCollection)
            .WithIgnoredBits(0, 32);

            CoreRegisters.CommandEvent2.Define(coreRegistersCollection)
            .WithIgnoredBits(0, 32);

            CoreRegisters.CommandEvent3.Define(coreRegistersCollection)
            .WithFlag(0, FieldMode.Read, name: "cmddone", valueProviderCallback: _ => true)
            .WithReservedBits(1, 1)
            .WithTag("cerrtimeout", 2, 1)
            .WithTag("cerrcrc", 3, 1)
            .WithReservedBits(4, 4)
            .WithIgnoredBits(8, 24);

            CoreRegisters.DataEvent0.Define(coreRegistersCollection)
            .WithIgnoredBits(0, 32);

            CoreRegisters.DataEvent1.Define(coreRegistersCollection)
            .WithIgnoredBits(0, 32);

            CoreRegisters.DataEvent2.Define(coreRegistersCollection)
            .WithIgnoredBits(0, 32);

            CoreRegisters.DataEvent3.Define(coreRegistersCollection)
            .WithFlag(0, FieldMode.Read, name: "datadone", valueProviderCallback: _ => true)
            .WithTag("derrwrite", 1, 1)
            .WithTag("derrtimeout", 2, 1)
            .WithTag("derrcrc", 3, 1)
            .WithReservedBits(4, 4)
            .WithIgnoredBits(8, 24);
            ;

            CoreRegisters.BlockSize.DefineMany(coreRegistersCollection, 2, (register, idx) =>
            {
                register
                .WithValueField(0, 8, name: $"BlockSize{idx}", writeCallback: (_, val) =>
                {
                    BitHelper.ReplaceBits(ref blockSize, width: 8, source: val, destinationPosition: 8 - idx * 8);
                })
                .WithIgnoredBits(8, 24);
            });

            CoreRegisters.BlockCount.DefineMany(coreRegistersCollection, 4, (register, idx) =>
            {
                register
                .WithValueField(0, 8, name: $"BlockCount{idx}", writeCallback: (_, val) =>
                {
                    BitHelper.ReplaceBits(ref blockCount, width: 8, source: val, destinationPosition: 24 - idx * 8);
                })
                .WithIgnoredBits(8, 24);
            });

            ReaderRegisters.ReaderReset.Define(readerRegistersCollection)
            .WithIgnoredBits(0, 1)     // reset bit, no need for handling this
            .WithReservedBits(1, 7)
            .WithIgnoredBits(8, 24);

            ReaderRegisters.ReaderStart.Define(readerRegistersCollection)
            .WithFlag(0, out readerStartFlag, name: "start")
            .WithReservedBits(1, 7)
            .WithIgnoredBits(8, 24);

            ReaderRegisters.ReaderDone.Define(readerRegistersCollection)
            .WithFlag(0, FieldMode.Read, name: "done", valueProviderCallback: _ => true)
            .WithReservedBits(1, 7)
            .WithIgnoredBits(8, 24);

            WriterRegisters.WriterReset.Define(writerRegistersCollection)
            .WithIgnoredBits(0, 1)     // reset bit, no need for handling this
            .WithReservedBits(1, 7)
            .WithIgnoredBits(8, 24);

            WriterRegisters.WriterStart.Define(writerRegistersCollection)
            .WithFlag(0, out writerStartFlag, name: "start")
            .WithReservedBits(1, 7)
            .WithIgnoredBits(8, 24);

            WriterRegisters.WriterDone.Define(writerRegistersCollection)
            .WithFlag(0, FieldMode.Read, name: "done", valueProviderCallback: _ => true)
            .WithReservedBits(1, 7)
            .WithIgnoredBits(8, 24);
        }
Example #10
0
 private void F(ref uint a, uint b, uint c, uint d, uint k, ushort s, uint i)
 {
     a = b + BitHelper.RotateLeft(a + ((b & c) | (~b & d)) + _x[k] + T[i - 1], s);
 }
Example #11
0
        private void HandleClockRising(bool[] signals)
        {
            switch (state)
            {
            case State.Address:
            {
                this.Log(LogLevel.Noisy, "Appending address bit #{0}: {1}", bufferToDevice.Count, signals[DataSignal]);
                bufferToDevice.Push(signals[DataSignal]);

                if (bufferToDevice.Count == 7)
                {
                    var address = (int)BitHelper.GetValueFromBitsArray(bufferToDevice.PopAll());

                    this.Log(LogLevel.Noisy, "Address decoded: 0x{0:X}", address);
                    state = State.Operation;

                    if (!TryGetByAddress(address, out slave))
                    {
                        this.Log(LogLevel.Warning, "Trying to access a non-existing I2C device at address 0x{0:X}", address);
                    }
                }
                break;
            }

            case State.Operation:
            {
                isRead = signals[DataSignal];
                this.Log(LogLevel.Noisy, "Operation decoded: {0}", isRead ? "read" : "write");

                state = State.AddressAck;
                break;
            }

            case State.AddressAck:
            {
                // write ACK(false) or NACK(true)
                bufferFromDevice.Enqueue(slave == null);

                if (slave == null)
                {
                    // ignore the rest of transmission until the next (repeated) start condition
                    state = State.Idle;
                }
                else if (isRead)
                {
                    this.Log(LogLevel.Noisy, "Reading from device");
                    foreach (var @byte in slave.Read(6))
                    {
                        foreach (var bit in BitHelper.GetBits(@byte).Take(8).Reverse())
                        {
                            this.Log(LogLevel.Noisy, "Enqueuing bit: {0}", bit);
                            bufferFromDevice.Enqueue(bit);
                        }
                    }

                    tickCounter = 0;
                    state       = State.Read;
                }
                else     // it must be write
                {
                    state = State.Write;
                }
                break;
            }

            case State.Read:
            {
                tickCounter++;
                if (tickCounter == 8)
                {
                    state = State.ReadAck;
                }
                break;
            }

            case State.ReadAck:
            {
                tickCounter = 0;
                state       = State.Read;
                break;
            }

            case State.Write:
            {
                this.Log(LogLevel.Noisy, "Latching data bit #{0}: {1}", bufferToDevice.Count, signals[DataSignal]);
                bufferToDevice.Push(signals[DataSignal]);

                if (bufferToDevice.Count == 8)
                {
                    state = State.WriteAck;
                }
                break;
            }

            case State.WriteAck:
            {
                DebugHelper.Assert(bufferToDevice.Count == 8);

                var dataByte = (byte)BitHelper.GetValueFromBitsArray(bufferToDevice.PopAll());
                this.Log(LogLevel.Noisy, "Decoded data byte #{0}: 0x{1:X}", bytesToDevice.Count, dataByte);

                bytesToDevice.Enqueue(dataByte);

                // ACK
                this.Log(LogLevel.Noisy, "Enqueuing ACK");
                bufferFromDevice.Enqueue(false);

                state = State.Write;
                break;
            }
            }
        }
Example #12
0
        internal void Encode()
        {
            //Psd Header: 26 bytes.
            InternalStream.WriteBytes(Encoding.ASCII.GetBytes("8BPS"));        //Chunk type, 4 bytes.
            InternalStream.WriteUInt16(BitHelper.ConvertEndian((ushort)1));    //File version, 1 - PSD, 2 - PSB, 2 bytes.
            InternalStream.Position += 6;                                      //Must be zero, 6 bytes.
            InternalStream.WriteUInt16(BitHelper.ConvertEndian((ushort)4));    //Number of channels, ARGB, 2 bytes.
            InternalStream.WriteUInt32(BitHelper.ConvertEndian((uint)Height)); //Height of the image, 4 bytes.
            InternalStream.WriteUInt32(BitHelper.ConvertEndian((uint)Width));  //Width of the image, 4 bytes.
            InternalStream.WriteUInt16(BitHelper.ConvertEndian((ushort)8));    //Number of bits per channel, 2 bytes.
            InternalStream.WriteUInt16(BitHelper.ConvertEndian((ushort)3));    //The color mode of the file, 3 - RGB, 2 bytes.

            //Color mode data. 4 bytes.
            InternalStream.WriteUInt32(BitHelper.ConvertEndian(0u)); //The size of the color mode data block, 0 bytes for RGB mode, 4 bytes.

            //Image resources. XX bytes.
            InternalStream.WriteBytes(ImageResources.Content);

            //LayerAndMaskInformation. 4 + XX bytes.
            var layerAndMask = LayerAndMask.Content;

            InternalStream.WriteUInt32(BitHelper.ConvertEndian((uint)layerAndMask.Length)); //Length of the LayerAndMask block, 4 bytes.
            InternalStream.WriteBytes(layerAndMask);                                        //Content of the LayerAndMask block.

            //ImageData. XX bytes.
            if (Compress)
            {
                InternalStream.WriteUInt16(BitHelper.ConvertEndian((ushort)1)); //The type of encoding, PackBit/RLE, 2 bytes.
                foreach (var layer in LayerAndMask.LayerInfo.ImageChannelDataList)
                {
                    //Writes all byte counts for all the scan lines (rows * channels), with each count stored as a two-byte value.
                    foreach (var channel in layer.ChannelList)
                    {
                        foreach (var b in channel.RleCompressedContent)
                        {
                            InternalStream.WriteInt16(BitHelper.ConvertEndian((short)b.Length));
                        }
                    }

                    //Writes down each layer, in planar order: AAA RRR GGG BBB.
                    foreach (var channel in layer.ChannelList)
                    {
                        foreach (var b in channel.RleCompressedContent)
                        {
                            InternalStream.WriteBytes(b);
                        }
                    }

                    break;
                }
            }
            else
            {
                InternalStream.WriteUInt16(BitHelper.ConvertEndian((ushort)0)); //The type of encoding, Raw data, 2 bytes.
                foreach (var layer in LayerAndMask.LayerInfo.ImageChannelDataList)
                {
                    //Writes down each layer, in planar order: AAA RRR GGG BBB.
                    foreach (var channel in layer.ChannelList)
                    {
                        InternalStream.WriteBytes(channel.RawContent);
                    }

                    break;
                }
            }
        }
Example #13
0
 public uint ReadUInt32(int offset)
 {
     return((offset > buffer.Length - 4)
         ? 0
         : BitHelper.ToUInt32(buffer, offset, 4, true));
 }
Example #14
0
        public void TestMS1BMask()
        {
            TestingHelper testingHelper = new TestingHelper();
            Initialiser bitboards = new Initialiser();
            UInt64[] rankDiags = bitboards.InitialiseRankDiagonals();
            UInt64 diag = rankDiags[1];

            BitHelper bitHelper = new BitHelper();

            UInt64 mask = bitHelper.GetMostSignificant1BitMask(diag);
            Debug.WriteLine("Diagonal:");
            Debug.WriteLine(testingHelper.BitboardToBoardString(diag));
            Debug.WriteLine("Mask:");
            Debug.WriteLine(testingHelper.BitboardToBoardString(mask));
        }
Example #15
0
        public void WriteDoubleWord(long offset, uint value)
        {
            this.NoisyLog("Write {0:X} to {1}", value, (Registers)offset);
            switch ((Registers)offset)
            {
            case Registers.MACConfiguration:
                macConfiguration          = value;
                crcStrippingForTypeFrames = (macConfiguration & 1u << 25) != 0;
                automaticPadCRCStripping  = (macConfiguration & 1u << 7) != 0;
                break;

            case Registers.MACFrameFilter:
                macFrameFilter = value;
                break;

            case Registers.MACMIIAddress:
                macMiiAddress = value;
                var busyClear = (value & 0x1) != 0;
                if (busyClear)
                {
                    macMiiAddress = macMiiAddress & ~0x1u;
                }
                var phyId    = (value >> 11) & 0x1F;
                var register = (ushort)((value >> 6) & 0x1F);
                var isRead   = ((value >> 1) & 0x1) == 0;
                if (!phys.ContainsKey(phyId))
                {
                    this.Log(LogLevel.Warning, "Access to unknown phy {0}", phyId);
                    break;
                }
                if (isRead)
                {
                    macMiiData = phys[phyId].Read(register);
                }
                else
                {
                    phys[phyId].Write(register, macMiiData);
                }

                break;

            case Registers.MACMIIData:
                macMiiData = (ushort)value;
                break;

            case Registers.MACFlowControl:
                macFlowControl = value;
                break;

            case Registers.MACAddress0High:
                MAC = MAC.WithNewOctets(f: (byte)(value >> 8), e: (byte)value);
                break;

            case Registers.MACAddress0Low:
                MAC = MAC.WithNewOctets(d: (byte)(value >> 24), c: (byte)(value >> 16), b: (byte)(value >> 8), a: (byte)value);
                break;

            case Registers.DMABusMode:
                dmaBusMode = value & ~0x1u;
                if ((value & 0x1) != 0)
                {
                    Reset();
                }
                break;

            case Registers.DMATransmitPollDemand:
                if ((dmaStatus | StartStopTransmission) != 0)
                {
                    SendFrames();
                }
                break;

            case Registers.DMAReceiveDescriptorListAddress:
                this.Log(LogLevel.Info, "Setting RDLA to 0x{0:X}.", value);
                dmaReceiveDescriptorListAddress      = value & ~3u;
                dmaReceiveDescriptorListAddressBegin = dmaReceiveDescriptorListAddress;
                break;

            case Registers.DMATransmitDescriptorListAddress:
                dmaTransmitDescriptorListAddress      = value & ~3u;
                dmaTransmitDescriptorListAddressBegin = dmaReceiveDescriptorListAddress;
                break;

            case Registers.DMAStatusRegister:
                dmaStatus &= ~value; //write 1 to clear;
                if ((value & 0x10000) > 0)
                {
                    IRQ.Unset();
                    TryDequeueFrame();
                }
                break;

            case Registers.DMAOperationMode:
                dmaOperationMode = value;
                if ((value & StartStopTransmission) != 0)
                {
                    SendFrames();
                }
                break;

            case Registers.DMAInterruptEnable:
                if (BitHelper.IsBitSet(value, 16)) //normal interrupt summary enable
                {
                    value |= (1u << 14) | (1u << 6) | (1u << 2) | 1u;
                }
                dmaInterruptEnable = value;
                break;

            default:
                this.LogUnhandledWrite(offset, value);
                break;
            }
        }
Example #16
0
        private void DefineRegisters()
        {
            Registers.ReaderEvPending.Define(this)
            .WithFlag(0, out readerEventPending, FieldMode.Read | FieldMode.WriteOneToClear, writeCallback: (_, __) => RefreshIrq())
            ;

            Registers.WriterLength0.DefineMany(this, NumberOfWriterLengthSubRegisters, (reg, idx) =>
                                               reg.WithValueField(0, DataWidth, FieldMode.Read, name: $"writer_length_{idx}", valueProviderCallback: _ =>
            {
                return(BitHelper.GetValue(writeSlots[writerSlotNumber.Value].DataLength,
                                          offset: (NumberOfWriterLengthSubRegisters - idx - 1) * DataWidth,
                                          size: DataWidth));
            }))
            ;

            Registers.WriterEvPending.Define(this)
            .WithFlag(0, out writerEventPending, FieldMode.Read | FieldMode.WriteOneToClear, writeCallback: (_, val) =>
            {
                if (!val)
                {
                    return;
                }

                if (latchedWriterSlot == -1)
                {
                    // if no slot has been latched, release all (this might happen at startup when resetting the state)
                    foreach (var slot in writeSlots)
                    {
                        slot.Release();
                    }
                }
                else
                {
                    writeSlots[latchedWriterSlot].Release();
                }

                latchedWriterSlot = -1;

                // update writerSlotNumber
                writerSlotNumber.Value = (uint)writeSlots
                                         .Select((v, idx) => new { v, idx })
                                         .Where(x => x.v.IsBusy)
                                         .Select(x => x.idx)
                                         .FirstOrDefault();

                UpdateEvents();
            })
            ;

            Registers.ReaderSlot.Define(this)
            .WithValueField(0, 32, out readerSlotNumber, name: "reader_slot", writeCallback: (_, val) =>
            {
                if (val >= readSlots.Length)
                {
                    this.Log(LogLevel.Warning, "Trying to set reader slot number out of range ({0}). Forcing value of 0", val);
                    readerSlotNumber.Value = 0;
                }
            })
            ;

            Registers.WriterSlot.Define(this)
            .WithValueField(0, 32, out writerSlotNumber, FieldMode.Read, name: "writer_slot", readCallback: (_, val) =>
            {
                // this is a bit hacky - here we remember the last returned writer slot number to release it later
                latchedWriterSlot = (int)val;
            })
            ;

            Registers.ReaderLengthHi.DefineMany(this, NumberOfReaderLengthSubRegisters, (reg, idx) =>
                                                reg.WithValueField(0, DataWidth, name: $"reader_length_{idx}",
                                                                   writeCallback: (_, val) =>
            {
                readSlots[readerSlotNumber.Value].DataLength =
                    BitHelper.ReplaceBits(readSlots[readerSlotNumber.Value].DataLength, val,
                                          width: DataWidth,
                                          destinationPosition: (int)((NumberOfReaderLengthSubRegisters - idx - 1) * DataWidth));
            },
                                                                   valueProviderCallback: _ =>
            {
                return(BitHelper.GetValue(readSlots[readerSlotNumber.Value].DataLength,
                                          offset: (NumberOfReaderLengthSubRegisters - idx - 1) * DataWidth,
                                          size: DataWidth));
            }))
            ;

            Registers.ReaderReady.Define(this)
            .WithFlag(0, FieldMode.Read, name: "reader_ready", valueProviderCallback: _ => true)
            ;

            Registers.ReaderStart.Define(this)
            .WithFlag(0, FieldMode.Write, name: "reader_start", writeCallback: (_, __) => SendPacket())
            ;

            Registers.ReaderEvEnable.Define(this)
            .WithFlag(0, out readerEventEnabled, name: "reader_event_enable", writeCallback: (_, __) => RefreshIrq())
            ;

            Registers.WriterEvEnable.Define(this)
            .WithFlag(0, out writerEventEnabled, name: "writer_event_enable", writeCallback: (_, __) => RefreshIrq())
            ;
        }
Example #17
0
        private void MineLabels(byte[] Bytes, ILGenerator Gen, Dictionary <int, Label[]> LabelOrigins, Dictionary <int, Label> LabelTargets)
        {
            for (int i = 0; i < Bytes.Length; i++)
            {
                OpCode Code  = GetOpcode(Bytes, ref i);
                int    Start = i;

                // Reference: http://msdn.microsoft.com/en-us/library/system.reflection.emit.opcodes.switch(VS.80).aspx
                if (Code == OpCodes.Switch)
                {
                    int Count = (int)BitHelper.ReadUnsignedInteger(Bytes, ref i);

                    // Jumps are relative to the first byte of the instruction following the switchmap
                    int          Zero   = i + Count * 4 + 1;
                    List <Label> Labels = new List <Label>();

                    for (int j = 0; j < Count; j++)
                    {
                        int Absolute = Zero + BitHelper.ReadInteger(Bytes, ref i);

                        if (!LabelTargets.ContainsKey(Absolute))
                        {
                            Label At = Gen.DefineLabel();
                            LabelTargets.Add(Absolute, At);
                            Labels.Add(At);
                        }
                        // If there is a label already defined for this position, reuse that for this switchmap too
                        else
                        {
                            Labels.Add(LabelTargets[Absolute]);
                        }
                    }

                    LabelOrigins.Add(Start, Labels.ToArray());
                }
                else if (Code.OperandType == OperandType.InlineBrTarget ||
                         Code.OperandType == OperandType.ShortInlineBrTarget)
                {
                    int Zero, Target;

                    if (Code.OperandType == OperandType.InlineBrTarget)
                    {
                        Zero   = i + 5;
                        Target = Zero + BitHelper.ReadInteger(Bytes, ref i);
                    }
                    else
                    {
                        Zero   = i + 2;
                        Target = Zero + ((sbyte)Bytes[++i]);
                    }

                    if (!LabelTargets.ContainsKey(Target))
                    {
                        Label At = Gen.DefineLabel();
                        LabelTargets.Add(Target, At);
                        LabelOrigins.Add(Start, new Label[] { At });
                    }
                    else
                    {
                        LabelOrigins.Add(Start, new Label[] { LabelTargets[Target] });
                    }
                }
                else
                {
                    i += CodeArgumentSize(Code);
                }
            }
        }
Example #18
0
 private bool IsIRQEnabled(int irq)
 {
     return(BitHelper.IsBitSet(interruptMaskRegister, (byte)irq));
 }
 public uint ReadDoubleWord(long offset)
 {
     return(xipMode.Value
         ? RegisteredPeripheral.UnderlyingMemory.ReadDoubleWord(BitHelper.SetBitsFrom((uint)offset, upperAddress.Value, 24, 8))
         : registers.Read(offset));
 }
        public Raptor_GPIO(Machine machine) : base(machine, NumberOfPins)
        {
            locker = new object();
            pins   = new Pin[NumberOfPins];

            var registersMap = new Dictionary <long, DoubleWordRegister>
            {
                { (long)Registers.GPIO_DATA, new DoubleWordRegister(this)
                  .WithValueField(0, 16,
                                  valueProviderCallback: val =>
                    {
                        var readOperations = pins.Select(x => (x.pinOperation & Operation.Read) != 0);            // select pins configured as input pins
                        var result         = readOperations.Zip(State, (operation, state) => operation && state); //  update with the incoming signals
                        return(BitHelper.GetValueFromBitsArray(result));                                          // register value after adjusting the read value for read pins
                    })

                  .WithValueField(16, 16,
                                  valueProviderCallback: val =>
                    {
                        var writeOperations = pins.Select(x => (x.pinOperation & Operation.Write) != 0);                               // select pins configured as output pins
                        var result          = writeOperations.Zip(Connections.Values, (operation, state) => operation && state.IsSet); // update with outgoing signals
                        return(BitHelper.GetValueFromBitsArray(result));
                    }) },

                { (long)Registers.GPIO_ENB, new DoubleWordRegister(this)
                  .WithValueField(0, 16,
                                  writeCallback: (_, val) =>
                    {
                        var bits = BitHelper.GetBits(val);          // put the register bits in an array after they are written
                        for (var i = 0; i < bits.Length; i++)
                        {
                            if (bits[i])             // input
                            {
                                pins[i].pinOperation = Operation.Read;
                            }
                            else              // output
                            {
                                pins[i].pinOperation = Operation.Write;
                            }
                        }
                    })
                  .WithTag("RESERVED", 16, 16) },

                { (long)Registers.GPIO_PUB, new DoubleWordRegister(this)
                  .WithValueField(0, 16,
                                  writeCallback: (_, val) =>
                    {
                        var bits = BitHelper.GetBits(val);          // put the register bits in an array after they are written
                        for (var i = 0; i < bits.Length; i++)
                        {
                            //if(bits[i] == 1)  // pullup
                            // todo: not currently supported
                        }
                    })
                  .WithTag("RESERVED", 16, 16) },

                { (long)Registers.GPIO_PDB, new DoubleWordRegister(this)
                  .WithValueField(0, 16,
                                  writeCallback: (_, val) =>
                    {
                        var bits = BitHelper.GetBits(val);          // put the register bits in an array after they are written
                        for (var i = 0; i < bits.Length; i++)
                        {
                            //if(bits[i] == 1)  // pulldown
                            // todo: not currently supported
                        }
                    })
                  .WithTag("RESERVED", 16, 16) }
            };

            registers = new DoubleWordRegisterCollection(this, registersMap);
        }
        public MPFS_QSPI(Machine machine) : base(machine)
        {
            locker = new object();
            IRQ    = new GPIO();

            var registerMap = new Dictionary <long, DoubleWordRegister>
            {
                { (long)Registers.Control, new DoubleWordRegister(this, 0x402) //the docs report 0x502, but this lights up a reserved bit.
                  .WithFlag(0, out enabled, name: "ENABLE")
                  .WithFlag(1, FieldMode.Read, valueProviderCallback: _ => true, name: "MASTER")
                  .WithFlag(2, out xipMode, name: "XIP")
                  .WithEnumField(3, 1, out xipAddressBytes, name: "XIPADDR")
                  .WithReservedBits(4, 6)
                  .WithTag("CLKIDLE", 10, 1)
                  .WithTag("SAMPLE", 11, 2)
                  .WithTag("QSPIMODE[0]", 13, 1)
                  .WithTag("QSPIMODE[1]", 14, 2)
                  .WithFlag(16, out x4Enabled, name: "FLAGS4X")
                  .WithTag("CLKRATE", 24, 4) },

                { (long)Registers.Frames, new DoubleWordRegister(this)
                  .WithValueField(0, 16, writeCallback: (_, value) =>
                    {
                        BitHelper.UpdateWith(ref totalBytes, value, 0, 16);
                        bytesSent = 0;
                    }, valueProviderCallback: _ => totalBytes, name: "TOTALBYTES")
                  .WithValueField(16, 9, out commandBytes, name: "CMDBYTES")
                  .WithTag("QSPI", 25, 1)
                  .WithTag("IDLE", 26, 4)
                  .WithFlag(30, valueProviderCallback: _ => false,
                            // If set then the FIFO flags are set to byte mode
                            changeCallback: (_, value) => x4Enabled.Value = false, name: "FLAGBYTE")
                  .WithFlag(31, valueProviderCallback: _ => false,
                            // If set then the FIFO flags are set to word mode
                            changeCallback: (_, value) => x4Enabled.Value = true, name: "FLAGWORD")
                  .WithWriteCallback((_, __) =>
                    {
                        txDone.Value = false;
                        rxDone.Value = false;
                        RefreshInterrupt();
                    }) },

                { (long)Registers.InterruptEnable, new DoubleWordRegister(this)
                  .WithFlag(0, out txDoneInterruptEnabled, name: "TXDONE")
                  .WithFlag(1, out rxDoneInterruptEnabled, name: "RXDONE")
                  .WithFlag(2, out rxAvailableInterruptEnabled, name: "RXAVAILABLE")
                  .WithFlag(3, out txAvailableInterruptEnabled, name: "TXAVAILABLE")
                  .WithFlag(4, out rxFifoEmptyInterruptEnabled, name: "RXFIFOEMPTY")
                  .WithFlag(5, name: "TXFIFOFULL")   //we keep the value, but not do anything with it, as this never happens
                  .WithChangeCallback((_, __) => RefreshInterrupt()) },

                { (long)Registers.Status, new DoubleWordRegister(this)
                  .WithFlag(0, out txDone, FieldMode.WriteOneToClear | FieldMode.Read, name: "TXDONE")
                  .WithFlag(1, out rxDone, FieldMode.WriteOneToClear | FieldMode.Read, name: "RXDONE")
                  .WithFlag(2, valueProviderCallback: _ => IsRxAvailable(), name: "RXAVAILABLE")
                  .WithFlag(3, valueProviderCallback: _ => true, name: "TXAVAILABLE")
                  .WithFlag(4, valueProviderCallback: _ => !IsRxAvailable(), name: "RXFIFOEMPTY")
                  .WithFlag(5, valueProviderCallback: _ => false, name: "TXFIFOFULL")
                  .WithReservedBits(6, 1)
                  .WithFlag(7, valueProviderCallback: _ => true, name: "READY")
                  .WithFlag(8, valueProviderCallback: _ => x4Enabled.Value, name: "FLAGSX4")
                  .WithWriteCallback((_, __) => RefreshInterrupt()) },

                { (long)Registers.UpperAddress, new DoubleWordRegister(this)
                  .WithValueField(0, 8, out upperAddress, name: "ADDRUP") },

                { (long)Registers.RxData1, new DoubleWordRegister(this)
                  .WithValueField(0, 8, FieldMode.Read,
                                  valueProviderCallback: _ =>
                    {
                        lock (locker)
                        {
                            return(receiveFifo.Count > 0 ? receiveFifo.Dequeue() : 0u);
                        }
                    },
                                  name: "RXDATA")
                  .WithWriteCallback((_, __) => RefreshInterrupt()) },

                { (long)Registers.TxData1, new DoubleWordRegister(this)
                  .WithValueField(0, 8, FieldMode.Write, writeCallback: (_, val) => HandleByte(val), name: "TXDATA") },

                { (long)Registers.RxData4, new DoubleWordRegister(this)
                  // The documentation is ambiguous on this register.
                  // It says 4 bytes must be read from the FIFO, but does not state precisely what happens
                  // when there is not enough data. This model ignores the read until there are at least 4 bytes to be read.
                  .WithValueField(0, 32, FieldMode.Read, valueProviderCallback: _ =>
                    {
                        lock (locker)
                        {
                            if (receiveFifo.Count >= 4)
                            {
                                var value = 0u;
                                for (var i = 0; i < 4; ++i)
                                {
                                    value |= (uint)receiveFifo.Dequeue() << (8 * i);
                                }
                                return(value);
                            }
                        }
                        this.Log(LogLevel.Warning, "Trying to read 4 bytes from the receive FIFO, but there are only {0} bytes available.", receiveFifo.Count);
                        return(0);
                    },
                                  name: "RXDATA4")
                  .WithWriteCallback((_, __) => RefreshInterrupt()) },

                { (long)Registers.TxData4, new DoubleWordRegister(this)
                  .WithValueField(0, 32, FieldMode.Write,
                                  writeCallback: (_, val) =>
                    {
                        for (var i = 0; i < 4; i++)
                        {
                            HandleByte(BitHelper.GetValue(val, i * 8, 8));
                        }
                    },
                                  name: "TXDATA4") },
                // this register intentionally exposes the whole register for reading and the upper bytes for writing
                { (long)Registers.FramesUpper, new DoubleWordRegister(this)
                  .WithValueField(0, 16, FieldMode.Read, valueProviderCallback: _ => totalBytes, name: "BYTESLOWER")
                  .WithValueField(16, 16, writeCallback: (_, value) => BitHelper.UpdateWithShifted(ref totalBytes, value, 16, 16),
                                  valueProviderCallback: _ => totalBytes >> 16, name: "BYTESUPPER") }
            };

            registers = new DoubleWordRegisterCollection(this, registerMap);
        }
Example #22
0
        //多线程处理有问题重新实现
        //private void AfterReceive(object sender, SocketAsyncEventArgs e)
        //{
        //    if (e.BytesTransferred > 0 && e.SocketError == SocketError.Success)
        //    {
        //            //读取数据
        //            byte[] data = new byte[e.BytesTransferred];
        //            //_log.InfoFormat("接收到的包长度:{0}-时间:{1}", e.BytesTransferred,DateTime.Now.Ticks);
        //            lock (m_buffer)
        //            {
        //                Array.Copy(e.Buffer, e.Offset, data, 0, e.BytesTransferred);
        //                m_buffer.AddRange(data);
        //            }
        //            //if (e.BytesTransferred < 21)
        //            //{
        //            //    var buff_1 = BitConverter.ToString(e.Buffer);
        //            //    var buff_2 = BitConverter.ToString(data);
        //            //    var buff_3 = BitConverter.ToString(m_buffer.ToArray());
        //            //    _log.InfoFormat("Buffer:{0}\r\n-Data:{1}\r\n-M_buff:{2}", buff_1, buff_2, buff_3);
        //            //}
        //            do
        //            {
        //                if (m_buffer.Count <= 12)
        //                {
        //                    //_log.InfoFormat("不够一个消息头需要继续接收:{0}", m_buffer.Count);
        //                    break;
        //                }
        //                byte[] lenBytes = new byte[4];
        //                lock (m_buffer)
        //                {
        //                    if (m_buffer.Count >= 4)
        //                    {
        //                        lenBytes = m_buffer.GetRange(0, 4).ToArray();
        //                    }
        //                    else
        //                        break;
        //                }
        //                int packageLen = (int)BitHelper.SubUInt32(lenBytes, 0);
        //                if (packageLen <= m_buffer.Count)
        //                {
        //                    //包够长时,则提取出来,交给后面的程序去处理
        //                    byte[] rev = new byte[packageLen];
        //                    lock (m_buffer)
        //                    {
        //                        if (m_buffer.Count >= packageLen)
        //                        {
        //                            rev = m_buffer.GetRange(0, packageLen).ToArray();
        //                            m_buffer.RemoveRange(0, packageLen);
        //                        }
        //                        else
        //                        {
        //                            break;
        //                        }
        //                    }
        //                    //将数据包交给前台去处理
        //                    HandleCap(rev);
        //                }
        //                else
        //                {   //长度不够,还得继续接收,需要跳出循环
        //                    //_log.InfoFormat("包长度不够:{0},{1}", packageLen, m_buffer.Count);
        //                    //lock (m_buffer)
        //                    //{
        //                    //    var buff_2 = BitConverter.ToString(data);
        //                    //    var buff_3 = BitConverter.ToString(m_buffer.ToArray());
        //                    //    _log.InfoFormat("接收内容:{0}\r\n当前内容:{1}",buff_2, buff_3);
        //                    //}
        //                    break;
        //                }
        //            } while (m_buffer.Count > 4);
        //            //if (m_buffer.Count > 0)
        //            //{
        //            //    _log.InfoFormat("本次未处理长度:{0}", m_buffer.Count);
        //            //}

        //        if (receivePool.Count < Size)
        //        {
        //            SocketManager.Clear(e);
        //            lock (((ICollection)receivePool).SyncRoot)
        //            {
        //                receivePool.Enqueue(e);
        //            }
        //        }
        //        else
        //        {
        //            e.Dispose();
        //        }
        //    }
        //}

        private void AfterReceive(object sender, SocketAsyncEventArgs e)
        {
            if (e.BytesTransferred > 0 && e.SocketError == SocketError.Success)
            {
                //读取数据
                byte[] data = new byte[e.BytesTransferred];
                //lock (m_buffer)
                //{
                try
                {
                    Array.Copy(e.Buffer, e.Offset, data, 0, e.BytesTransferred);
                    lock (obj)
                    {
                        m_buffer.AddRange(data);
                        do
                        {
                            if (m_buffer.Count < 12)
                            {
                                break;
                            }
                            CmppRespHeader header = new CmppRespHeader(m_buffer.GetRange(0, 12).ToArray());
                            if (!header.IsRespHeader())
                            {
                                _log.ErrorFormat("接收到的消息体不合法,直接丢弃。丢弃的包大小:{0}", m_buffer.Count);
                                m_buffer.Clear();
                                break;
                            }
                            byte[] lenBytes = new byte[4];
                            lenBytes = m_buffer.GetRange(0, 4).ToArray();
                            int packageLen = (int)BitHelper.SubUInt32(lenBytes, 0);
                            //_log.ErrorFormat("解析的数据包大小:{0}", packageLen);
                            if (packageLen <= m_buffer.Count)
                            {
                                byte[] rev = new byte[packageLen];
                                rev = m_buffer.GetRange(0, packageLen).ToArray();
                                m_buffer.RemoveRange(0, packageLen);
                                //if (m_buffer.Count >= packageLen)
                                //{
                                //    //lock (m_buffer)
                                //    //{
                                //        rev = m_buffer.GetRange(0, packageLen).ToArray();
                                //        m_buffer.RemoveRange(0, packageLen);
                                //    //}
                                //}
                                //else
                                //{
                                //    break;
                                //}
                                //HandleCap(rev);
                                DoReceiveEvent(rev);
                            }
                            else
                            {   //长度不够,还得继续接收,需要跳出循环
                                break;
                            }
                        } while (m_buffer.Count >= 12);
                    }
                }
                catch (Exception ex)
                {
                    _log.ErrorFormat("解析报数据出现异常:{0}", ex);
                    m_buffer.Clear();
                }
                finally
                {
                    //}
                    if (receivePool.Count < Size)
                    {
                        SocketManager.Clear(e);
                        lock (((ICollection)receivePool).SyncRoot)
                        {
                            receivePool.Enqueue(e);
                        }
                    }
                    else
                    {
                        e.Dispose();
                    }
                }
            }
        }
Example #23
0
 private void G(ref uint a, uint b, uint c, uint d, uint k, ushort s, uint i)
 {
     a = b + BitHelper.RotateLeft(a + ((b & d) | (c & ~d)) + X[k] + T[i - 1], s);
 }
Example #24
0
 private uint GetPending(int offset)
 {
     return(BitHelper.GetValueFromBitsArray(irqs.Skip(16 + offset * 8).Take(32).Select(irq => (irq & IRQState.Pending) != 0)));
 }
Example #25
0
 private void H(ref uint a, uint b, uint c, uint d, uint k, ushort s, uint i)
 {
     a = b + BitHelper.RotateLeft(a + (b ^ c ^ d) + X[k] + T[i - 1], s);
 }
Example #26
0
        public DeviceStatus ParsePosition()
        {
            // orden del array

            //0   Encabezado del paquete
            //1   IMEI del equipo
            //2   Número de paquete            string[] parse = _command.Split(new[] { "<", ">" }, StringSplitOptions.RemoveEmptyEntries);
            //3   Evento que generó el paquete            var eventoLength = (_command.Length == 48 || _command.Length == 46 ? 3 : 2);
            //4   Nivel de señal GSM. (Entre 0 y 31)            var evento = (byte)0;
            //5   U1 en voltios            var hdop = (byte)0;
            //6   I1 en Ampere por 10. (10 equivale a 1.0 Amp)            var entradas = Convert.ToByte("0", 16);
            //7   U2 en voltios            var time = DateTimeUtils.SafeParseFormat(parse[10] + parse[2].Split('.')[0], "ddMMyyHHmmss");
            //8   I2 en Ampere por 10. (27 equivale a 2.7 Amp)
            //9   D1 Entrada DIN1 inactiva            /*
            //10  D2 Entrada D2 activa                Latitude: DD MM.MMMM
            //11  T1 Temperatura 25ºC                Longitude: DDD MM.MMMM   T1:valor,T2:valor
            //12  T2 Temperatura 23ºC             3259.816776,N
            //13  T3 Sensor NTC3 abierto             09642.858868,W
            //14  T4 Sensor NTC4 en cortocircuito             latitud max -90 +90
            //15  Latitud             32*59.816776
            //16  Longitud             longitud max -180 + 180
            //17  Modelo y versión de firmware del equipo             096*42.858868
            //18  Fecha y hora de la generación del evento GMT0             */
            //19  Fin de paquete


            string[] parse    = _command.Split(new[] { "<", ">" }, StringSplitOptions.RemoveEmptyEntries);
            var      entradas = Convert.ToByte("0", 16);
            var      time     = DateTimeUtils.SafeParseFormat(parse[17], "yyyy-MM-dd HH:mm:ss");

            //-34.603718 Latitud
            //-58.38158 Longitud
            var lat    = Convert.ToSingle(parse[14].Split('.')[0]);
            var lon    = Convert.ToSingle(parse[15].Split('.')[0]);
            var hdop   = Convert.ToByte(parse[3]);
            var evento = Convert.ToByte(parse[3]);
            var vel    = Convert.ToSingle(0);
            var dir    = Convert.ToSingle(1); // (0 ..359), Norte = 0, Este = 90, Sur = 180, Oeste = 270

            _node.Imei = parse[3];

            var devId = (Int32?)null;

            if (_node != null)
            {
                devId = _node.Id;
            }


            GPSPoint gpoint = null;

            try
            {
                gpoint = new GPSPoint(time, lat, lon, vel, GPSPoint.SourceProviders.Unespecified, 0)
                {
                    Course         = new Course(dir),
                    HDOP           = hdop,
                    IgnitionStatus = BitHelper.AreBitsSet(entradas, 7) ? IgnitionStatus.On : IgnitionStatus.Off
                };
                if (devId != null)
                {
                    gpoint.DeviceId = devId.Value;
                }
            }
            catch (ArgumentOutOfRangeException e)
            {
                STrace.Exception(typeof(AbsolutDeviceCommand).FullName, e, IdNum ?? 0, String.Format("Posición inválida {0}", getCommand()));
                gpoint = null;
            }

            var result = new DeviceStatus(devId, gpoint, evento, entradas);

            return(result);
        }
Example #27
0
 private void I(ref uint a, uint b, uint c, uint d, uint k, ushort s, uint i)
 {
     a = b + BitHelper.RotateLeft(a + (c ^ (b | ~d)) + X[k] + T[i - 1], s);
 }
Example #28
0
        protected void WriteInner(uint value)
        {
            var baseValue        = UnderlyingValue;
            var difference       = UnderlyingValue ^ value;
            var setRegisters     = value & (~UnderlyingValue);
            var changedRegisters = new List <RegisterField>();

            foreach (var registerField in registerFields)
            {
                //switch is OK, because write modes are exclusive.
                switch (registerField.fieldMode.WriteBits())
                {
                case FieldMode.Write:
                    if (BitHelper.AreAnyBitsSet(difference, registerField.position, registerField.width))
                    {
                        BitHelper.UpdateWith(ref UnderlyingValue, value, registerField.position, registerField.width);
                        changedRegisters.Add(registerField);
                    }
                    break;

                case FieldMode.Set:
                    if (BitHelper.AreAnyBitsSet(setRegisters, registerField.position, registerField.width))
                    {
                        BitHelper.OrWith(ref UnderlyingValue, setRegisters, registerField.position, registerField.width);
                        changedRegisters.Add(registerField);
                    }
                    break;

                case FieldMode.Toggle:
                    if (BitHelper.AreAnyBitsSet(value, registerField.position, registerField.width))
                    {
                        BitHelper.XorWith(ref UnderlyingValue, value, registerField.position, registerField.width);
                        changedRegisters.Add(registerField);
                    }
                    break;

                case FieldMode.WriteOneToClear:
                    if (BitHelper.AreAnyBitsSet(value, registerField.position, registerField.width))
                    {
                        BitHelper.AndWithNot(ref UnderlyingValue, value, registerField.position, registerField.width);
                        changedRegisters.Add(registerField);
                    }
                    break;

                case FieldMode.WriteZeroToClear:
                    if (BitHelper.AreAnyBitsSet(~value, registerField.position, registerField.width))
                    {
                        BitHelper.AndWithNot(ref UnderlyingValue, ~value, registerField.position, registerField.width);
                        changedRegisters.Add(registerField);
                    }
                    break;
                }
            }
            foreach (var registerField in registerFields)
            {
                registerField.CallWriteHandler(baseValue, value);
            }
            foreach (var changedRegister in changedRegisters.Distinct())
            {
                changedRegister.CallChangeHandler(baseValue, UnderlyingValue);
            }

            var unhandledWrites = value & ~definedFieldsMask;

            if (unhandledWrites != 0)
            {
                parent.Log(LogLevel.Warning, TagLogger(unhandledWrites));
            }
        }
Example #29
0
 // NOTE these methods aren't in the P4 - they are generated to help packet_in, etc.
 public override void Extract(byte[] data, uint offset)
 {
     dstAddr   = BitHelper.Extract48(data, offset);
     srcAddr   = BitHelper.Extract48(data, offset + 5);
     etherType = BitHelper.Extract16(data, offset + 10);
 }
Example #30
0
        public void TestMS1BIndex()
        {
            TestingHelper testingHelper = new TestingHelper();
            Initialiser bitboards = new Initialiser();
            UInt64[] rankDiags = bitboards.InitialiseRankDiagonals();
            UInt64 diag = rankDiags[1];

            BitHelper bitHelper = new BitHelper();

            int ms1bIndex = BitHelper.GetMostSignificant1BitIndex2(diag);
                // bitHelper.GetMostSignificant1BitIndex(diag);
            Debug.WriteLine("Diagonal:");
            Debug.WriteLine(testingHelper.BitboardToBoardString(diag));
        }
Example #31
0
 public override void Write(byte[] data, uint offset)
 {
     BitHelper.Write48(data, offset, dstAddr);
     BitHelper.Write48(data, offset + 5, srcAddr);
     BitHelper.Write16(data, offset + 10, etherType);
 }
Example #32
0
        public void TestMS1B()
        {
            TestingHelper testingHelper = new TestingHelper();
            Initialiser bitboards = new Initialiser();
            UInt64[] rankDiags = bitboards.InitialiseRankDiagonals();
            UInt64 diag = Constants.MainDiagonal;
                //rankDiags[1];

            BitHelper bitHelper = new BitHelper();

            UInt64 ms1b = bitHelper.GetMostSignificant1Bit(diag);
            Debug.WriteLine("Diagonal:");
            Debug.WriteLine(testingHelper.BitboardToBoardString(diag));
            Debug.WriteLine("MS1B:");
            Debug.WriteLine(testingHelper.BitboardToBoardString(ms1b));
        }
Example #33
0
        public void WriteDoubleWordOverMDIO(long offset, uint value)
        {
            this.Log(LogLevel.Noisy, "Writing to PHY: offset 0x{0:X}, value 0x{1:X}", offset, value);

            if (offset != (long)MDIORegisters.Write)
            {
                this.Log(LogLevel.Warning, "Unhandled write to PHY register: 0x{0:X}", offset);
                return;
            }

            var dataDecoded = bbHelper.Update(value, dataBit: 2, clockBit: 0);

            if (!dataDecoded)
            {
                return;
            }

            this.Log(LogLevel.Noisy, "Got a 16-bit packet in {0} state, the value is 0x{1:X}", phyState, bbHelper.DecodedOutput);

            switch (phyState)
            {
            case PhyState.Idle:
            {
                if (bbHelper.DecodedOutput == 0xffff)
                {
                    // sync, move on
                    phyState = PhyState.Syncing;
                }
                // if not, wait for sync pattern
                break;
            }

            case PhyState.Syncing:
            {
                if (bbHelper.DecodedOutput == 0xffff)
                {
                    phyState = PhyState.WaitingForCommand;
                }
                else
                {
                    this.Log(LogLevel.Warning, "Unexpected bit pattern when syncing (0x{0:X}), returning to idle state", bbHelper.DecodedOutput);
                    phyState = PhyState.Idle;
                }
                break;
            }

            case PhyState.WaitingForCommand:
            {
                const int OpCodeRead  = 0x1;
                const int OpCodeWrite = 0x2;

                var startField      = bbHelper.DecodedOutput & 0x3;
                var opCode          = (bbHelper.DecodedOutput >> 2) & 0x3;
                var phyAddress      = (ushort)(BitHelper.ReverseBits((ushort)((bbHelper.DecodedOutput >> 4) & 0x1f)) >> 11);
                var registerAddress = (ushort)(BitHelper.ReverseBits((ushort)((bbHelper.DecodedOutput >> 9) & 0x1f)) >> 11);

                if (startField != 0x2 ||
                    (opCode != OpCodeRead && opCode != OpCodeWrite))
                {
                    this.Log(LogLevel.Warning, "Received an invalid PHY command: 0x{0:X}. Ignoring it", bbHelper.DecodedOutput);
                    phyState = PhyState.Idle;
                    break;
                }

                if (opCode == OpCodeWrite)
                {
                    phyState = PhyState.WaitingForData;
                    this.Log(LogLevel.Noisy, "Write command to PHY 0x{0:X}, register 0x{1:X}. Waiting for data", phyAddress, registerAddress);

                    lastPhyAddress      = phyAddress;
                    lastRegisterAddress = registerAddress;
                }
                else
                {
                    ushort readValue = 0;
                    if (!phys.TryGetValue(phyAddress, out var phy))
                    {
                        this.Log(LogLevel.Warning, "Trying to read from non-existing PHY #{0}", phyAddress);
                    }
                    else
                    {
                        readValue = (ushort)phy.Read(registerAddress);
                    }

                    this.Log(LogLevel.Noisy, "Read value 0x{0:X} from PHY 0x{1:X}, register 0x{2:X}", readValue, phyAddress, registerAddress);

                    bbHelper.SetInputBuffer(readValue);
                    phyState = PhyState.Idle;
                }
                break;
            }

            case PhyState.WaitingForData:
            {
                if (!phys.TryGetValue(lastPhyAddress, out var phy))
                {
                    this.Log(LogLevel.Warning, "Trying to write to non-existing PHY #{0}", lastPhyAddress);
                }
                else
                {
                    this.Log(LogLevel.Noisy, "Writing value 0x{0:X} to PHY 0x{1:X}, register 0x{2:X}", bbHelper.DecodedOutput, lastPhyAddress, lastRegisterAddress);
                    phy.Write(lastRegisterAddress, (ushort)bbHelper.DecodedOutput);
                }

                phyState = PhyState.Idle;
                break;
            }

            default:
                throw new ArgumentOutOfRangeException("Unexpected PHY state: {0}".FormatWith(phyState));
            }
        }