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