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); }
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; } }
/// <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))); }
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); }
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); }
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); }
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; } } }
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; } } }
public uint ReadUInt32(int offset) { return((offset > buffer.Length - 4) ? 0 : BitHelper.ToUInt32(buffer, offset, 4, true)); }
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)); }
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; } }
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()) ; }
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); } } }
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); }
//多线程处理有问题重新实现 //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(); } } } }
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); }
private uint GetPending(int offset) { return(BitHelper.GetValueFromBitsArray(irqs.Skip(16 + offset * 8).Take(32).Select(irq => (irq & IRQState.Pending) != 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); }
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); }
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); }
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)); } }
// 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); }
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)); }
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); }
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)); }
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)); } }