コード例 #1
0
        public Rhd2000EvalBoard()
        {
            BitFileName        = "main.bit";
            SampleRate         = AmplifierSampleRate.SampleRate20000Hz;
            LowerBandwidth     = 0.1;
            UpperBandwidth     = 7500.0;
            DspCutoffFrequency = 1.0;
            DspEnabled         = true;

            source = Observable.Create <Rhd2000DataFrame>((observer, cancellationToken) =>
            {
                var activeTtlOut = ttlOut = 0;
                return(Task.Factory.StartNew(() =>
                {
                    Load();
                    var ledSequence = LedSequence();
                    try
                    {
                        evalBoard.SetTtlMode(0);
                        evalBoard.SetTtlOut(activeTtlOut);
                        evalBoard.SetContinuousRunMode(true);
                        evalBoard.EnableExternalFastSettle(ExternalFastSettleEnabled);
                        evalBoard.Run();

                        var blocksToRead = GetDataBlockReadCount(SampleRate);
                        var fifoCapacity = Rhythm.Net.Rhd2000EvalBoard.FifoCapacityInWords();

                        var queue = new Queue <Rhd2000DataBlock>();
                        ledSequence.MoveNext();
                        while (!cancellationToken.IsCancellationRequested)
                        {
                            if (activeTtlOut != ttlOut)
                            {
                                activeTtlOut = ttlOut;
                                evalBoard.SetTtlOut(activeTtlOut);
                            }

                            if (evalBoard.ReadDataBlocks(blocksToRead, queue))
                            {
                                var wordsInFifo = evalBoard.NumWordsInFifo();
                                var bufferPercentageCapacity = 100.0 * wordsInFifo / fifoCapacity;
                                foreach (var dataBlock in queue)
                                {
                                    observer.OnNext(new Rhd2000DataFrame(dataBlock, bufferPercentageCapacity));
                                }
                                queue.Clear();
                                ledSequence.MoveNext();
                            }
                        }
                    }
                    finally
                    {
                        ledSequence.Dispose();
                        evalBoard.ClearTtlOut();
                        evalBoard.SetContinuousRunMode(false);
                        evalBoard.SetMaxTimeStep(0);
                        evalBoard.Flush();
                        evalBoard.Close();
                        evalBoard = null;
                        chipRegisters = null;
                    }
                },
                                             cancellationToken,
                                             TaskCreationOptions.LongRunning,
                                             TaskScheduler.Default));
            })
                     .PublishReconnectable()
                     .RefCount();
        }
コード例 #2
0
        void ChangeSampleRate(AmplifierSampleRate amplifierSampleRate)
        {
            evalBoard.SetSampleRate(amplifierSampleRate);

            // Now that we have set our sampling rate, we can set the MISO sampling delay
            // which is dependent on the sample rate.
            evalBoard.SetCableLengthMeters(BoardPort.PortA, cableLengthPortA);
            evalBoard.SetCableLengthMeters(BoardPort.PortB, cableLengthPortB);
            evalBoard.SetCableLengthMeters(BoardPort.PortC, cableLengthPortC);
            evalBoard.SetCableLengthMeters(BoardPort.PortD, cableLengthPortD);

            // Set up an RHD2000 register object using this sample rate to
            // optimize MUX-related register settings.
            var sampleRate = evalBoard.GetSampleRate();

            chipRegisters = new Rhd2000Registers(sampleRate);
            var commandList = new List <int>();

            // Create a command list for the AuxCmd1 slot.  This command sequence will create a 250 Hz,
            // zero-amplitude sine wave (i.e., a flatline).  We will change this when we want to perform
            // impedance testing.
            var sequenceLength = chipRegisters.CreateCommandListZcheckDac(commandList, 250, 0);

            evalBoard.UploadCommandList(commandList, AuxCmdSlot.AuxCmd1, 0);
            evalBoard.SelectAuxCommandLength(AuxCmdSlot.AuxCmd1, 0, sequenceLength - 1);
            evalBoard.SelectAuxCommandBank(BoardPort.PortA, AuxCmdSlot.AuxCmd1, 0);
            evalBoard.SelectAuxCommandBank(BoardPort.PortB, AuxCmdSlot.AuxCmd1, 0);
            evalBoard.SelectAuxCommandBank(BoardPort.PortC, AuxCmdSlot.AuxCmd1, 0);
            evalBoard.SelectAuxCommandBank(BoardPort.PortD, AuxCmdSlot.AuxCmd1, 0);

            // Next, we'll create a command list for the AuxCmd2 slot.  This command sequence
            // will sample the temperature sensor and other auxiliary ADC inputs.
            sequenceLength = chipRegisters.CreateCommandListTempSensor(commandList);
            evalBoard.UploadCommandList(commandList, AuxCmdSlot.AuxCmd2, 0);
            evalBoard.SelectAuxCommandLength(AuxCmdSlot.AuxCmd2, 0, sequenceLength - 1);
            evalBoard.SelectAuxCommandBank(BoardPort.PortA, AuxCmdSlot.AuxCmd2, 0);
            evalBoard.SelectAuxCommandBank(BoardPort.PortB, AuxCmdSlot.AuxCmd2, 0);
            evalBoard.SelectAuxCommandBank(BoardPort.PortC, AuxCmdSlot.AuxCmd2, 0);
            evalBoard.SelectAuxCommandBank(BoardPort.PortD, AuxCmdSlot.AuxCmd2, 0);

            // For the AuxCmd3 slot, we will create three command sequences.  All sequences
            // will configure and read back the RHD2000 chip registers, but one sequence will
            // also run ADC calibration.  Another sequence will enable amplifier 'fast settle'.

            // Before generating register configuration command sequences, set amplifier
            // bandwidth parameters.
            chipRegisters.SetDspCutoffFreq(DspCutoffFrequency);
            chipRegisters.SetLowerBandwidth(LowerBandwidth);
            chipRegisters.SetUpperBandwidth(UpperBandwidth);
            chipRegisters.EnableDsp(DspEnabled);

            // Upload version with ADC calibration to AuxCmd3 RAM Bank 0.
            sequenceLength = chipRegisters.CreateCommandListRegisterConfig(commandList, true);
            evalBoard.UploadCommandList(commandList, AuxCmdSlot.AuxCmd3, 0);
            evalBoard.SelectAuxCommandLength(AuxCmdSlot.AuxCmd3, 0, sequenceLength - 1);

            // Upload version with no ADC calibration to AuxCmd3 RAM Bank 1.
            sequenceLength = chipRegisters.CreateCommandListRegisterConfig(commandList, false);
            evalBoard.UploadCommandList(commandList, AuxCmdSlot.AuxCmd3, 1);
            evalBoard.SelectAuxCommandLength(AuxCmdSlot.AuxCmd3, 0, sequenceLength - 1);

            // Upload version with fast settle enabled to AuxCmd3 RAM Bank 2.
            chipRegisters.SetFastSettle(true);
            sequenceLength = chipRegisters.CreateCommandListRegisterConfig(commandList, false);
            evalBoard.UploadCommandList(commandList, AuxCmdSlot.AuxCmd3, 2);
            evalBoard.SelectAuxCommandLength(AuxCmdSlot.AuxCmd3, 0, sequenceLength - 1);
            chipRegisters.SetFastSettle(false);

            UpdateRegisterConfiguration(fastSettle: false);
        }
コード例 #3
0
        void ImpedanceMeasurement()
        {
            var actualImpedanceFreq = 0.0;

            var sampleRate    = evalBoard.GetSampleRate();
            var chipRegisters = new Rhd2000Registers(sampleRate);
            var ledSequence   = LedSequence();

            ledSequence.MoveNext();

            // Create a command list for the AuxCmd1 slot.
            var commandList    = new List <int>();
            var sequenceLength = chipRegisters.CreateCommandListZcheckDac(commandList, actualImpedanceFreq, 128.0);

            evalBoard.UploadCommandList(commandList, AuxCmdSlot.AuxCmd1, 1);
            evalBoard.SelectAuxCommandLength(AuxCmdSlot.AuxCmd1, 0, sequenceLength - 1);

            evalBoard.SelectAuxCommandBank(BoardPort.PortA, AuxCmdSlot.AuxCmd1, 1);
            evalBoard.SelectAuxCommandBank(BoardPort.PortB, AuxCmdSlot.AuxCmd1, 1);
            evalBoard.SelectAuxCommandBank(BoardPort.PortC, AuxCmdSlot.AuxCmd1, 1);
            evalBoard.SelectAuxCommandBank(BoardPort.PortD, AuxCmdSlot.AuxCmd1, 1);

            // Select number of periods to measure impedance over
            int numPeriods = (int)Math.Round(0.020 * actualImpedanceFreq); // Test each channel for at least 20 msec...

            if (numPeriods < 5)
            {
                numPeriods = 5;                 // ...but always measure across no fewer than 5 complete periods
            }
            double period    = sampleRate / actualImpedanceFreq;
            int    numBlocks = (int)Math.Ceiling((numPeriods + 2.0) * period / 60.0); // + 2 periods to give time to settle initially

            if (numBlocks < 2)
            {
                numBlocks = 2;                // need first block for command to switch channels to take effect.
            }
            chipRegisters.SetDspCutoffFreq(DspCutoffFrequency);
            chipRegisters.SetLowerBandwidth(LowerBandwidth);
            chipRegisters.SetUpperBandwidth(UpperBandwidth);
            chipRegisters.EnableDsp(DspEnabled);
            chipRegisters.EnableZcheck(true);

            sequenceLength = chipRegisters.CreateCommandListRegisterConfig(commandList, false);
            // Upload version with no ADC calibration to AuxCmd3 RAM Bank 1.
            evalBoard.UploadCommandList(commandList, AuxCmdSlot.AuxCmd3, 3);
            evalBoard.SelectAuxCommandLength(AuxCmdSlot.AuxCmd3, 0, sequenceLength - 1);
            evalBoard.SelectAuxCommandBank(BoardPort.PortA, AuxCmdSlot.AuxCmd3, 3);
            evalBoard.SelectAuxCommandBank(BoardPort.PortB, AuxCmdSlot.AuxCmd3, 3);
            evalBoard.SelectAuxCommandBank(BoardPort.PortC, AuxCmdSlot.AuxCmd3, 3);
            evalBoard.SelectAuxCommandBank(BoardPort.PortD, AuxCmdSlot.AuxCmd3, 3);

            evalBoard.SetContinuousRunMode(false);
            evalBoard.SetMaxTimeStep((uint)samplesPerBlock * (uint)numBlocks);

            // Create matrices of doubles of size (numStreams x 32 x 3) to store complex amplitudes
            // of all amplifier channels (32 on each data stream) at three different Cseries values.
            var numChannels       = 32;
            var numStreams        = evalBoard.GetNumEnabledDataStreams();
            var measuredMagnitude = new double[numStreams][, ];
            var measuredPhase     = new double[numStreams][, ];

            for (int i = 0; i < numStreams; i++)
            {
                measuredMagnitude[i] = new double[numChannels, 3];
                measuredPhase[i]     = new double[numChannels, 3];
            }

            // We execute three complete electrode impedance measurements: one each with
            // Cseries set to 0.1 pF, 1 pF, and 10 pF.  Then we select the best measurement
            // for each channel so that we achieve a wide impedance measurement range.
            Queue <Rhd2000DataBlock> dataQueue = new Queue <Rhd2000DataBlock>();

            for (int capRange = 0; capRange < 3; capRange++)
            {
                double cSeries;
                switch (capRange)
                {
                case 0:
                    chipRegisters.SetZcheckScale(ZcheckCs.ZcheckCs100fF);
                    cSeries = 0.1e-12;
                    break;

                case 1:
                    chipRegisters.SetZcheckScale(ZcheckCs.ZcheckCs1pF);
                    cSeries = 1.0e-12;
                    break;

                default:
                    chipRegisters.SetZcheckScale(ZcheckCs.ZcheckCs10pF);
                    cSeries = 10.0e-12;
                    break;
                }

                // Check all 32 channels across all active data streams.
                for (int channel = 0; channel < numChannels; channel++)
                {
                    chipRegisters.SetZcheckChannel(channel);
                    sequenceLength = chipRegisters.CreateCommandListRegisterConfig(commandList, false);
                    // Upload version with no ADC calibration to AuxCmd3 RAM Bank 1.
                    evalBoard.UploadCommandList(commandList, AuxCmdSlot.AuxCmd3, 3);

                    // Start SPI interface and wait for command to complete.
                    evalBoard.Run();
                    while (evalBoard.IsRunning())
                    {
                        Thread.Sleep(0);
                    }
                    evalBoard.ReadDataBlocks(numBlocks, dataQueue);
                    MeasureComplexAmplitude(measuredMagnitude, measuredPhase, null, capRange, channel, numStreams, numBlocks, sampleRate, actualImpedanceFreq, numPeriods);

                    // Advance LED display
                    ledSequence.MoveNext();
                }
            }

            evalBoard.SetContinuousRunMode(false);
            evalBoard.SetMaxTimeStep(0);
            evalBoard.Flush();

            // Switch back to flatline
            evalBoard.SelectAuxCommandBank(BoardPort.PortA, AuxCmdSlot.AuxCmd1, 0);
            evalBoard.SelectAuxCommandBank(BoardPort.PortB, AuxCmdSlot.AuxCmd1, 0);
            evalBoard.SelectAuxCommandBank(BoardPort.PortC, AuxCmdSlot.AuxCmd1, 0);
            evalBoard.SelectAuxCommandBank(BoardPort.PortD, AuxCmdSlot.AuxCmd1, 0);
            evalBoard.SelectAuxCommandLength(AuxCmdSlot.AuxCmd1, 0, 1);
            UpdateRegisterConfiguration(fastSettle: false);

            // Turn off LED.
            ledSequence.Dispose();
        }