Exemple #1
0
        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();
        }
Exemple #2
0
        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();
        }
Exemple #3
0
        public CC2538RF(Machine machine)
        {
            this.machine = machine;
            rxLock       = new object();
            rxQueue      = new Queue <Frame>();
            txQueue      = new Queue <byte>();

            shortAddress    = new Address(AddressingMode.ShortAddress);
            extendedAddress = new Address(AddressingMode.ExtendedAddress);
            random          = EmulationManager.Instance.CurrentEmulation.RandomGenerator;
            IRQ             = new GPIO();
            AlternativeIRQ  = new GPIO();
            irqMultiplexer  = new GPIOMultiplexer(IRQ, AlternativeIRQ);

            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>(irqMultiplexer);
            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, 0).WithValueField(0, 6, FieldMode.Read, valueProviderCallback: _ => (uint)fsmState)
                               .WithFlag(7, FieldMode.Read, valueProviderCallback: _ => true);
            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);
            //Reset value set according to the documentation, but register value is caluculated from Channel value.
            var frequencyControl = new DoubleWordRegister(this, 0xB).WithValueField(0, 7,
                                                                                    changeCallback: (_, value) => Channel = (int)(((value > 113 ? 113 : value) - 11) / 5 + 11), //FREQ = 11 + 5(channel - 11), maximum value is 113.
                                                                                    valueProviderCallback: (value) => 11 + 5 * ((uint)Channel - 11));

            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 rxFifoBytesCount = new DoubleWordRegister(this).WithValueField(0, 8, FieldMode.Read, valueProviderCallback: (_) => GetRxFifoBytesCount());

            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 },
                { (uint)Register.FrequencyControl, frequencyControl },
                { (uint)Register.RxFifoBytesCount, rxFifoBytesCount }
            };

            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();
        }