public AddressInformation(AddressingMode destinationAddressingMode, AddressingMode sourceAddressingMode, bool intraPan, ArraySegment<byte> data) { var internalOffset = 0; if(destinationAddressingMode != AddressingMode.None) { DestinationPan = GetValue(data, 0); DestinationAddress = new Address(new ArraySegment<byte>(data.Array, data.Offset + 2, destinationAddressingMode.GetBytesLength())); internalOffset = 2 + DestinationAddress.Bytes.Count; } if(sourceAddressingMode != AddressingMode.None) { if(intraPan) { SourcePan = DestinationPan; } else { SourcePan = GetValue(data, internalOffset); internalOffset += 2; } SourceAddress = new Address(new ArraySegment<byte>(data.Array, data.Offset + internalOffset, sourceAddressingMode.GetBytesLength())); } Bytes = data; }
public CC2538RF() { rxLock = new object(); rxQueue = new Queue<Frame>(); txQueue = new Queue<byte>(); shortAddress = new Address(AddressingMode.ShortAddress); extendedAddress = new Address(AddressingMode.ExtendedAddress); random = new Random(); IRQ = new GPIO(); srcShortEnabled = new bool[24]; srcExtendedEnabled = new bool[12]; matchedSourceAddresses = new bool[24]; srcShortPendEnabled = new bool[24]; srcExtendedPendEnabled = new bool[12]; ffsmMemory = new uint[96]; irqHandler = new InterruptHandler<InterruptRegister, InterruptSource>(IRQ); irqHandler.RegisterInterrupt(InterruptRegister.IrqFlag0, InterruptSource.StartOfFrameDelimiter, 1); irqHandler.RegisterInterrupt(InterruptRegister.IrqFlag0, InterruptSource.FifoP, 2); irqHandler.RegisterInterrupt(InterruptRegister.IrqFlag0, InterruptSource.SrcMatchDone, 3); irqHandler.RegisterInterrupt(InterruptRegister.IrqFlag0, InterruptSource.SrcMatchFound, 4); irqHandler.RegisterInterrupt(InterruptRegister.IrqFlag0, InterruptSource.FrameAccepted, 5); irqHandler.RegisterInterrupt(InterruptRegister.IrqFlag0, InterruptSource.RxPktDone, 6); irqHandler.RegisterInterrupt(InterruptRegister.IrqFlag0, InterruptSource.RxMaskZero, 7); irqHandler.RegisterInterrupt(InterruptRegister.IrqFlag1, InterruptSource.TxAckDone, 0); irqHandler.RegisterInterrupt(InterruptRegister.IrqFlag1, InterruptSource.TxDone, 1); irqHandler.RegisterInterrupt(InterruptRegister.IrqFlag1, InterruptSource.RfIdle, 2); irqHandler.RegisterInterrupt(InterruptRegister.IrqFlag1, InterruptSource.CommandStrobeProcessorManualInterrupt, 3); irqHandler.RegisterInterrupt(InterruptRegister.IrqFlag1, InterruptSource.CommandStrobeProcessorStop, 4); irqHandler.RegisterInterrupt(InterruptRegister.IrqFlag1, InterruptSource.CommandStrobeProcessorWait, 5); var matchedSourceIndex = new DoubleWordRegister(this); matchedSourceIndexField = matchedSourceIndex.DefineValueField(0, 8, FieldMode.Read | FieldMode.Write); var srcResMask = CreateRegistersGroup(3, this, 0, 8, valueProviderCallback: ReadSrcResMaskRegister, writeCallback: WriteSrcResMaskRegister); var srcExtendedAddressPendingEnabled = CreateRegistersGroup(3, this, 0, 8, valueProviderCallback: ReadSrcExtendedAddressPendingEnabledRegister, writeCallback: WriteSrcExtendedAddressPendingEnabledRegister); var srcShortAddressPendingEnabled = CreateRegistersGroup(3, this, 0, 8, name: "SrcShortAddressPendingEnabled", valueProviderCallback: ReadSrcShortAddressPendingEnabledRegister, writeCallback: WriteSrcShortAddressPendingEnabledRegister); var extAddress = CreateRegistersGroup(8, this, 0, 8, valueProviderCallback: i => extendedAddress.Bytes[i], writeCallback: (i, @new) => extendedAddress.SetByte((byte)@new, i)); panId = CreateRegistersGroup(2, this, 0, 8); var shortAddressRegister = CreateRegistersGroup(2, this, 0, 8, valueProviderCallback: i => shortAddress.Bytes[i], writeCallback: (i, @new) => shortAddress.SetByte((byte)@new, i)); var sourceExtendedAddressEnable = CreateRegistersGroup(3, this, 0, 8, valueProviderCallback: ReadSourceExtendedAddressEnableRegister, writeCallback: WriteSourceExtendedAddressEnableRegister); var sourceShortAddressEnable = CreateRegistersGroup(3, this, 0, 8, valueProviderCallback: ReadSourceShortAddressEnableRegister, writeCallback: WriteSourceShortAddressEnableRegister); var frameHandling0 = new DoubleWordRegister(this, 0x40); autoAck = frameHandling0.DefineFlagField(5); autoCrc = frameHandling0.DefineFlagField(6); appendDataMode = frameHandling0.DefineFlagField(7); var frameHandling1 = new DoubleWordRegister(this, 0x1); pendingOr = frameHandling1.DefineFlagField(2); var sourceAddressMatching = new DoubleWordRegister(this, 0x7); sourceAddressMatchingEnabled = sourceAddressMatching.DefineFlagField(0); autoPendEnabled = sourceAddressMatching.DefineFlagField(1); pendDataRequestOnly = sourceAddressMatching.DefineFlagField(2); var radioStatus0 = new DoubleWordRegister(this, 0x81).WithValueField(0, 8, FieldMode.Read); var radioStatus1 = new DoubleWordRegister(this, 0).WithValueField(0, 8, FieldMode.Read, valueProviderCallback: ReadRadioStatus1Register); var rssiValidStatus = new DoubleWordRegister(this, 0x1).WithFlag(0, FieldMode.Read); var interruptMask = CreateRegistersGroup(2, this, 0, 8, valueProviderCallback: i => irqHandler.GetRegisterMask(InterruptRegisterHelper.GetMaskRegister(i)), writeCallback: (i, @new) => { irqHandler.SetRegisterMask(InterruptRegisterHelper.GetMaskRegister(i), @new); }); var randomData = new DoubleWordRegister(this, 0).WithValueField(0, 2, FieldMode.Read, valueProviderCallback: _ => (uint)(random.Next() & 3)); var frameFiltering0 = new DoubleWordRegister(this, 0xD); frameFilterEnabled = frameFiltering0.DefineFlagField(0); isPanCoordinator = frameFiltering0.DefineFlagField(1); maxFrameVersion = frameFiltering0.DefineValueField(2, 2); var frameFiltering1 = new DoubleWordRegister(this, 0x78); acceptBeaconFrames = frameFiltering1.DefineFlagField(3); acceptDataFrames = frameFiltering1.DefineFlagField(4); acceptAckFrames = frameFiltering1.DefineFlagField(5); acceptMacCmdFrames = frameFiltering1.DefineFlagField(6); var rfData = new DoubleWordRegister(this, 0).WithValueField(0, 8, valueProviderCallback: _ => DequeueData(), writeCallback: (_, @new) => { EnqueueData((byte)@new); }); var interruptFlag = CreateRegistersGroup(2, this, 0, 8, valueProviderCallback: i => irqHandler.GetRegisterValue(InterruptRegisterHelper.GetValueRegister(i)), writeCallback: (i, @new) => { irqHandler.SetRegisterValue(InterruptRegisterHelper.GetValueRegister(i), @new); }); var commandStrobeProcessor = new DoubleWordRegister(this, 0).WithValueField(0, 8, FieldMode.Write, writeCallback: (_, @new) => { HandleSFRInstruction(@new); }); var addresses = new Dictionary<long, DoubleWordRegister> { { (uint)Register.RfData, rfData }, { (uint)Register.CommandStrobeProcessor, commandStrobeProcessor }, { (uint)Register.FrameFiltering0, frameFiltering0 }, { (uint)Register.FrameFiltering1, frameFiltering1 }, { (uint)Register.SourceAddressMatching, sourceAddressMatching }, { (uint)Register.FrameHandling0, frameHandling0 }, { (uint)Register.FrameHandling1, frameHandling1 }, { (uint)Register.RadioStatus0, radioStatus0 }, { (uint)Register.RadioStatus1, radioStatus1 }, { (uint)Register.RssiValidStatus, rssiValidStatus }, { (uint)Register.RandomData, randomData }, { (uint)Register.SourceAddressMatchingResult, matchedSourceIndex } }; RegisterGroup(addresses, (uint)Register.InterruptFlag, interruptFlag); RegisterGroup(addresses, (uint)Register.SourceExtendedAdressEnable, sourceExtendedAddressEnable); RegisterGroup(addresses, (uint)Register.SourceShortAddressEnable, sourceShortAddressEnable); RegisterGroup(addresses, (uint)Register.InterruptMask, interruptMask); RegisterGroup(addresses, (uint)Register.SourceAddressMatchingResultMask, srcResMask); RegisterGroup(addresses, (uint)Register.SourceExtendedAddressPendingEnabled, srcExtendedAddressPendingEnabled); RegisterGroup(addresses, (uint)Register.SourceShortAddressPendingEnabled, srcShortAddressPendingEnabled); RegisterGroup(addresses, (uint)Register.ExtendedAddress, extAddress); RegisterGroup(addresses, (uint)Register.PanId, panId); RegisterGroup(addresses, (uint)Register.ShortAddressRegister, shortAddressRegister); registers = new DoubleWordRegisterCollection(this, addresses); Reset(); }