private static int ReadFromPipeOut(PipeOutAddress pout, int len, byte[] PipeOutData)
 {
     lock (dev)
     {
         return(dev.ReadFromPipeOut((int)pout, len, PipeOutData));
     }
 }
示例#2
0
        /// <summary>
        /// Check to see if there is at least 25 msec worth of data (40 frames) in the USB read buffer.
        /// </summary>
        /// <param name="plotQueue">Queue used for plotting data to screen.</param>
        /// <param name="saveQueue">Queue used for saving data to disk.</param>
        /// <param name="dataRate">Data rate (High, Medium, or Low).</param>
        /// <param name="hammingDecoder">Hamming decoder object.</param>
        /// <returns>Number of pages remaining in FPGA board RAM buffer.</returns>
        public int CheckForUSBData(Queue <USBData> plotQueue, Queue <USBData> saveQueue, DataRate dataRate, bool rawDataMode, HammingDecoder hammingDecoder)
        {
            bool haveEnoughData = false;
            int  i, numPagesInRAM, numPagesLeftInRAM, numBytesToRead, numBytesRead, indexUSB, indexFrame;
            int  word1, word2, word3, word4;
            int  pageThreshold = 20;

            numPagesLeftInRAM = 0;

            if (rawDataMode)
            {
                pageThreshold = 24;
            }
            else
            {
                switch (dataRate)
                {
                case DataRate.High:
                    pageThreshold = 20;
                    break;

                case DataRate.Medium:
                    pageThreshold = 11;
                    break;

                case DataRate.Low:
                    pageThreshold = 6;
                    break;
                }
            }

            if (synthDataMode)
            {
                if (newSynthDataReady)
                {
                    //HACK XXX TODO FIXME TESTING -- comment-in the following conditional to test the "no data from USB condition"
                    //long sec = System.DateTime.Now.Second;
                    //if ((sec / 4) % 2 == 0)
                    //{
                    haveEnoughData    = true;
                    newSynthDataReady = false;
                    //}
                }
            }
            else
            {
                myXEM.UpdateWireOuts();
                numPagesInRAM = (int)myXEM.GetWireOutValue(wireOutNumPages);
                //Debug.WriteLine("numPagesInRAM = " + numPagesInRAM);
                if (numPagesInRAM > pageThreshold)
                {
                    haveEnoughData = true;
                }
            }

            if (haveEnoughData)
            {
                USBData USBDataBlock;
                long    tsNow = MainForm.GetAbsTimeNS();

                if (synthDataMode)
                {
                    int    channel, j;
                    Random myRand = new Random(unchecked ((int)DateTime.Now.Ticks));

                    for (channel = 0; channel < Constant.TotalNeuralChannels; channel++)
                    {
                        for (i = 0; i < Constant.NeuralSamplesPerFrame * Constant.FramesPerBlock; i++)
                        {
                            neuralSynthData[channel, i] = synthSpikeOffset[channel] + 5.7 * gaussian(myRand);  // create realistic offset and background of 5.7 uV rms noise
                        }
                        i = 0;
                        while (i < Constant.NeuralSamplesPerFrame * Constant.FramesPerBlock - 52)   // 52 samples = 2 msec (refractory period)
                        {
                            if (myRand.NextDouble() < 0.01)
                            {
                                for (j = 0; j < synthSpikeWidth1[channel]; j++)
                                {
                                    neuralSynthData[channel, i + j] += (synthSpikeAmp1[channel] * Math.Exp(-1 * (double)j / 12.5) * Math.Sin(6.28 * (double)j / synthSpikeWidth1[channel]));
                                }
                                i += 40 + 52;    // advance by 2 msec (refractory period)
                            }
                            else if (myRand.NextDouble() < 0.02)
                            {
                                for (j = 0; j < synthSpikeWidth2[channel]; j++)
                                {
                                    neuralSynthData[channel, i + j] += (synthSpikeAmp2[channel] * Math.Exp(-1 * (double)j / 12.5) * Math.Sin(6.28 * (double)j / synthSpikeWidth2[channel]));
                                }
                                i += 40 + 52;    // advance by 2 msec (refractory period)
                            }
                            else
                            {
                                i += 26;    // advance by 1 msec
                            }
                        }
                    }

                    for (channel = 0; channel < Constant.TotalEMGChannels; channel++)
                    {
                        for (i = 0; i < Constant.FramesPerBlock; i++)
                        {
                            EMGSynthData[channel, i] = synthEMGOffset[channel] + 0.043 * gaussian(myRand);  // create realistic offset and background of 43 uV rms noise
                        }
                        i = 0;
                        while (i < Constant.FramesPerBlock - 10)   // 10 = max 'spike' width
                        {
                            if (myRand.NextDouble() < 0.004)
                            {
                                for (j = 0; j < synthEMGWidth1[channel]; j++)
                                {
                                    EMGSynthData[channel, i + j] += (synthEMGAmp1[channel] * Math.Exp(-1 * (double)j / 12.5) * Math.Sin(6.28 * (double)j / synthEMGWidth1[channel]));
                                }
                                i += 10 + 3;    // advance by 2 msec (refractory period)
                            }
                            else if (myRand.NextDouble() < 0.008)
                            {
                                for (j = 0; j < synthEMGWidth2[channel]; j++)
                                {
                                    EMGSynthData[channel, i + j] += (synthEMGAmp2[channel] * Math.Exp(-1 * (double)j / 12.5) * Math.Sin(6.28 * (double)j / synthEMGWidth2[channel]));
                                }
                                i += 10 + 3;    // advance by 2 msec (refractory period)
                            }
                            else
                            {
                                i += 2;    // advance by 1 msec
                            }
                        }
                    }

                    // USBDataBlock = new USBData(neuralSynthData, EMGSynthData);

                    USBDataFrameCreate(neuralSynthData, EMGSynthData, rawFrameBlock, dataRate, hammingDecoder, 0.001);
                    USBDataBlock      = new USBData(rawFrameBlock, dataRate, rawDataMode, hammingDecoder);
                    numPagesLeftInRAM = 1;
                }
                else
                {
                    numBytesToRead = (4 * Constant.FrameSize(dataRate, rawDataMode) / 3) * Constant.BytesPerWord * Constant.FramesPerBlock;
                    numBytesRead   = myXEM.ReadFromPipeOut(pipeOutData, numBytesToRead, USBBuf);

                    if (numBytesRead != numBytesToRead)
                    {
                        UsbException e = new UsbException("USB read error; not enough bytes read");
                        throw e;
                    }

                    if ((USBBuf[1] & 0xe0) != 0xe0) // USBBuf[1] = high byte of first word; should have the form 111xxxxx if we are in sync
                    {
                        Debug.WriteLine("Resync");

                        // Reset FIFOs
                        myXEM.SetWireInValue(wireInResetReadWrite, 0x04);
                        myXEM.UpdateWireIns();
                        myXEM.SetWireInValue(wireInResetReadWrite, 0x00);
                        myXEM.UpdateWireIns();

                        // Enable data transfers
                        myXEM.SetWireInValue(wireInResetReadWrite, 0x03); // read and write
                        myXEM.UpdateWireIns();

                        return(0);     // abandon corrupted frame; get out of here

                        // UsbException e = new UsbException("USB sync error");
                        // throw e;
                    }

                    indexUSB   = 0;
                    indexFrame = 0;
                    for (i = 0; i < (Constant.FrameSize(dataRate, rawDataMode) / 3) * Constant.FramesPerBlock; i++)
                    {
                        word1     = 256 * Convert.ToInt32(USBBuf[indexUSB + 1]) + Convert.ToInt32(USBBuf[indexUSB]);
                        indexUSB += 2;
                        word2     = 256 * Convert.ToInt32(USBBuf[indexUSB + 1]) + Convert.ToInt32(USBBuf[indexUSB]);
                        indexUSB += 2;
                        word3     = 256 * Convert.ToInt32(USBBuf[indexUSB + 1]) + Convert.ToInt32(USBBuf[indexUSB]);
                        indexUSB += 2;
                        word4     = 256 * Convert.ToInt32(USBBuf[indexUSB + 1]) + Convert.ToInt32(USBBuf[indexUSB]);
                        indexUSB += 2;

                        rawFrameBlock[indexFrame++] = Convert.ToUInt16(((word1 & 0x0f00) << 4) + (word2 & 0x0fff));
                        rawFrameBlock[indexFrame++] = Convert.ToUInt16(((word1 & 0x00f0) << 8) + (word3 & 0x0fff));
                        rawFrameBlock[indexFrame++] = Convert.ToUInt16(((word1 & 0x000f) << 12) + (word4 & 0x0fff));
                    }

                    USBDataBlock = new USBData(rawFrameBlock, dataRate, rawDataMode, hammingDecoder);

                    myXEM.UpdateWireOuts();
                    numPagesLeftInRAM = (int)myXEM.GetWireOutValue(wireOutNumPages);
                }

                if (dataJustStarted)
                {
                    USBDataBlock.InitNeuralFilterState(neuralState, neuralDelay1, neuralDelay2, neuralNotchDelay1, neuralNotchDelay2);
                    USBDataBlock.InitEMGFilterState(EMGState, EMGDelay1, EMGDelay2, EMGNotchDelay1, EMGNotchDelay2);
                    dataJustStarted = false;
                }

                if (enableHPF)
                {
                    USBDataBlock.NeuralFilterHPF(neuralState, fHPF, Constant.NeuralSampleRate);
                    USBDataBlock.EMGFilterHPF(EMGState, fHPF, Constant.EMGSampleRate);
                }

                if (enableNotch)
                {
                    USBDataBlock.NeuralFilterNotch(neuralDelay1, neuralDelay2, neuralNotchDelay1, neuralNotchDelay2, fNotch, Constant.NeuralSampleRate);
                    USBDataBlock.EMGFilterNotch(EMGDelay1, EMGDelay2, EMGNotchDelay1, EMGNotchDelay2, fNotch, Constant.EMGSampleRate);
                }

                USBDataBlock.timeStampNanos = tsNow;

                plotQueue.Enqueue(USBDataBlock);
                saveQueue.Enqueue(USBDataBlock);
            }

            return(numPagesLeftInRAM);
        }