public void StartListening()
        {
            ConfigurationRegister configRegister = Configuration.Registers.ConfigurationRegister;

            configRegister.PWR_UP  = true;
            configRegister.PRIM_RX = true;
            configRegister.Save();

            StatusRegister statusRegister = Configuration.Registers.StatusRegister;

            statusRegister.RX_DR  = false;
            statusRegister.TX_DS  = false;
            statusRegister.MAX_RT = false;
            statusRegister.Save();

            // Restore the pipe0 address, if exists
            if (_receiveAddressPipe0 > 0)
            {
                AddressPipeRegister receiveAddressPipe0Register = Configuration.Registers.ReceiveAddressPipeRegisters[0];
                receiveAddressPipe0Register.Load(BitConverter.GetBytes(_receiveAddressPipe0));
                receiveAddressPipe0Register.Save();
            }

            TransmitPipe.FlushBuffer();
            ReceivePipes.FlushBuffer();

            ChipEnable(true);
        }
        public bool Write(byte[] data)
        {
            bool result = false;

            // Begin the write
            StartWrite(data);

            // ------------
            // At this point we could return from a non-blocking write, and then call
            // the rest after an interrupt

            // Instead, we are going to block here until we get TX_DS (transmission completed and ack'd)
            // or MAX_RT (maximum retries, transmission failed).  Also, we'll timeout in case the radio
            // is flaky and we get neither.

            // IN the end, the send should be blocking.  It comes back in 60ms worst case, or much faster
            // if I tighten up the retry logic.  (Default settings will be 1500us.
            // Monitor the send

            byte[]    observeTx = new byte[1];
            byte      status;
            Stopwatch stopwatch = new Stopwatch();

            stopwatch.Start();
            do
            {
                status = Configuration.Registers.ObserveTransmitRegister;
                //string observeTxDisplay = FormatObserveTx(observeTx[1]);
            } while ((status & (Utilities.BitValue(Properties.TX_DS) | Utilities.BitValue(Properties.MAX_RT))) != 1 && (stopwatch.ElapsedMilliseconds < 500));

            // The part above is what you could recreate with your own interrupt handler,
            // and then call this when you got an interrupt
            // ------------

            // Call this when you get an interrupt
            // The status tells us three things
            // * The send was successful (TX_DS)
            // * The send failed, too many retries (MAX_RT)
            // * There is an ack packet waiting (RX_DR)
            bool txOk, txFail;

            WhatHappened(out txOk, out txFail, out _isAckPayloadAvailable);
            result = txOk;

            // Handle the ack packet
            if (_isAckPayloadAvailable)
            {
                byte ackPayloadLength = Configuration.DynamicPayloadSize;
            }

            Status = DeviceStatus.PowerDown;
            TransmitPipe.FlushBuffer();

            return(result);
        }
        public void Begin()
        {
            RegisterManager registers = Configuration.Registers;

            ChipEnable(false);

            // Set 1500uS (minimum for 32B payload in ESB@250KBPS) timeouts, to make testing a little easier
            // WARNING: If this is ever lowered, either 250KBS mode with AA is broken or maximum packet
            // sizes must never be used. See documentation for a more complete explanation.
            Configuration.AutoRetransmitDelay = AutoRetransmitDelays.Delay4000uS;
            Configuration.AutoRetransmitCount = 15;

            // Disable auto acknowledgement
            EnableAutoAcknowledgementRegister autoAckRegister = registers.EnableAutoAcknowledgementRegister;

            autoAckRegister.EN_AA = false;
            autoAckRegister.Save();

            // Attempt to set DataRate to 250Kbps to determine if this is a plus model
            Configuration.DataRate    = DataRates.DataRate250Kbps;
            Configuration.IsPlusModel = Configuration.DataRate == DataRates.DataRate250Kbps;

            // Restore our default PA level
            Configuration.PowerLevel = PowerLevels.Max;

            // Initialize CRC and request 2-byte (16bit) CRC
            Configuration.CrcEncodingScheme = CrcEncodingSchemes.DualBytes;
            Configuration.CrcEnabled        = true;

            // Disable dynamic payload lengths
            Configuration.DynamicPayloadLengthEnabled = false;

            // Set up default configuration.  Callers can always change it later.
            // This channel should be universally safe and not bleed over into adjacent spectrum.
            Configuration.Channel = 76;

            // Then set the data rate to the slowest (and most reliable) speed supported by all hardware.
            Configuration.DataRate = DataRates.DataRate1Mbps;

            // Reset current status
            // Notice reset and flush is the last thing we do
            StatusRegister statusRegister = registers.StatusRegister;

            statusRegister.RX_DR  = false;
            statusRegister.TX_DS  = false;
            statusRegister.MAX_RT = false;
            statusRegister.Save();

            TransmitPipe.FlushBuffer();
            ReceivePipes.FlushBuffer();
        }
        public Radio(GpioPin cePin, SpiDevice spiDevice)
        {
            _checkStatus           = false;
            _isAckPayloadAvailable = false;
            _receiveAddressPipe0   = 0;
            _spiLock = new object();

            _spiDevice = spiDevice;
            _cePin     = cePin;
            _cePin.SetDriveMode(GpioPinDriveMode.Output);

            Configuration = new RadioConfiguration(this);
            TransmitPipe  = new TransmitPipe(this);
            ReceivePipes  = new ReceivePipeCollection(this);
        }
        public Radio(GpioPin cePin, SpiDevice spiDevice)
        {
            _checkStatus = false;
            _isAckPayloadAvailable = false;
            _receiveAddressPipe0 = 0;
            _spiLock = new object();

            _spiDevice = spiDevice;
            _cePin = cePin;
            _cePin.SetDriveMode(GpioPinDriveMode.Output);

            Configuration = new RadioConfiguration(this);
            TransmitPipe = new TransmitPipe(this);
            ReceivePipes = new ReceivePipeCollection(this);
        }
        public Radio(ICommandProcessor commandProcessor, ILoggerFactoryAdapter loggerFactoryAdapter, GpioPin powerPin, GpioPin cePin, GpioPin irqPin = null)
        {
            _syncRoot      = new object();
            _operatingMode = OperatingModes.PowerOff;
            _powerPin      = powerPin;
            _powerPin.Write(GpioPinValue.Low);

            _cePin = cePin;
            _cePin.Write(GpioPinValue.Low);

            _loggerFactoryAdapter = loggerFactoryAdapter;
            _logger = _loggerFactoryAdapter.GetLogger(GetType());

            _commandProcessor = commandProcessor;
            _commandProcessor.LoggerFactory    = _loggerFactoryAdapter;
            _commandProcessor.GetOperatingMode = () => OperatingMode;

            RegisterContainer = new RegisterContainer(_loggerFactoryAdapter, _commandProcessor);
            OperatingMode     = OperatingModes.PowerDown;
            RegisterContainer.ResetRegistersToDefault();

            Configuration = new Configuration(_loggerFactoryAdapter, _commandProcessor, RegisterContainer);

            TransmitPipe = new TransmitPipe(_loggerFactoryAdapter, Configuration, _commandProcessor, RegisterContainer, _cePin);
            ReceivePipes = new ReceivePipeCollection(_loggerFactoryAdapter, Configuration, _commandProcessor, RegisterContainer);

            bool useIrq = irqPin != null;

            if (useIrq)
            {
                _irqPin = irqPin;
                _irqPin.Write(GpioPinValue.High);
                _irqPin.ValueChanged += irqPin_ValueChanged;
            }
            ConfigurationRegister configurationRegister = RegisterContainer.ConfigurationRegister;

            configurationRegister.MaximunTransmitRetriesMask = !useIrq;
            configurationRegister.ReceiveDataReadyMask       = !useIrq;
            configurationRegister.TransmitDataSentMask       = !useIrq;
            configurationRegister.Save();
            OperatingMode = OperatingModes.StandBy;
        }
        public Radio(ICommandProcessor commandProcessor, ILoggerFactoryAdapter loggerFactoryAdapter, GpioPin powerPin, GpioPin cePin, GpioPin irqPin = null)
        {
            _syncRoot = new object();
            _operatingMode = OperatingModes.PowerOff;
            _powerPin = powerPin;
            _powerPin.Write(GpioPinValue.Low);

            _cePin = cePin;
            _cePin.Write(GpioPinValue.Low);

            _loggerFactoryAdapter = loggerFactoryAdapter;
            _logger = _loggerFactoryAdapter.GetLogger(GetType());

            _commandProcessor = commandProcessor;
            _commandProcessor.LoggerFactory = _loggerFactoryAdapter;
            _commandProcessor.GetOperatingMode = () => OperatingMode;

            RegisterContainer = new RegisterContainer(_loggerFactoryAdapter, _commandProcessor);
            OperatingMode = OperatingModes.PowerDown;
            RegisterContainer.ResetRegistersToDefault();

            Configuration = new Configuration(_loggerFactoryAdapter, _commandProcessor, RegisterContainer);

            TransmitPipe = new TransmitPipe(_loggerFactoryAdapter, Configuration, _commandProcessor, RegisterContainer, _cePin);
            ReceivePipes = new ReceivePipeCollection(_loggerFactoryAdapter, Configuration, _commandProcessor, RegisterContainer);

            bool useIrq = irqPin != null;
            if (useIrq)
            {
                _irqPin = irqPin;
                _irqPin.Write(GpioPinValue.High);
                _irqPin.ValueChanged += irqPin_ValueChanged;
            }
            ConfigurationRegister configurationRegister = RegisterContainer.ConfigurationRegister;
            configurationRegister.MaximunTransmitRetriesMask = !useIrq;
            configurationRegister.ReceiveDataReadyMask = !useIrq;
            configurationRegister.TransmitDataSentMask = !useIrq;
            configurationRegister.Save();
            OperatingMode = OperatingModes.StandBy;

        }
 public void StopListening()
 {
     ChipEnable(false);
     TransmitPipe.FlushBuffer();
     ReceivePipes.FlushBuffer();
 }