示例#1
0
        public override void Send(Candle.Frame frame, bool blocking = false)
        {
            var nativeFrame = new NativeFunctions.CAN_OBJ();

            nativeFrame.ID = frame.Identifier;

            if (frame.Extended)
            {
                nativeFrame.ExternFlag = 1;
            }
            else
            {
                nativeFrame.ExternFlag = 0;
            }

            if (frame.RTR)
            {
                nativeFrame.RemoteFlag = 1;
            }
            else
            {
                nativeFrame.RemoteFlag = 0;
            }

            nativeFrame.data    = new byte[8];
            nativeFrame.DataLen = (byte)frame.Data.Length;
            Buffer.BlockCopy(frame.Data, 0, nativeFrame.data, 0, frame.Data.Length);

            // Note : this shoud actually increment after we've actully sent (e.g. on thread). But since it's a heuristic this is kind of fine for now
            var lengthOnBus = frame.LengthOnBus;

            this.IncrementTx(lengthOnBus);

            if (blocking)
            {
                // Send this one frame
                this.FDevice.PerformInRightThread(() =>
                {
                    NativeFunctions.Transmit(
                        this.FDevice.DeviceType
                        , this.FDevice.DeviceIndex
                        , this.FChannelIndex
                        , new NativeFunctions.CAN_OBJ[] { nativeFrame }
                        , 1);

                    this.ThreadedUpdate();
                }, true);
            }
            else
            {
                this.FTxQueue.Add(nativeFrame);
            }
        }
示例#2
0
        public void ThreadedUpdate()
        {
            // Send frames
            {
                var framesToSend = new List <NativeFunctions.CAN_OBJ>();

                // Pull them from the queue
                {
                    NativeFunctions.CAN_OBJ frame;
                    while (this.FTxQueue.TryTake(out frame))
                    {
                        framesToSend.Add(frame);
                    }
                }

                // Send them out
                if (framesToSend.Count > 0)
                {
                    var framesSent = NativeFunctions.Transmit(
                        this.FDevice.DeviceType
                        , this.FDevice.DeviceIndex
                        , this.FChannelIndex
                        , framesToSend.ToArray()
                        , (UInt16)framesToSend.Count);

                    // Queue again anything that didn't send
                    for (int i = (int)framesSent; i < framesToSend.Count; i++)
                    {
                        this.FTxQueue.Add(framesToSend[i]);
                    }
                }

                // Alternative method : force send everything
                //int txOffset = 0;
                //while(txOffset != framesToSend.Count)
                //{
                //	var framesSent = NativeFunctions.Transmit(
                //			this.FDevice.DeviceType
                //			, this.FDevice.DeviceIndex
                //			, this.FChannelIndex
                //			, framesToSend.GetRange(txOffset, framesToSend.Count - txOffset).ToArray()
                //			, (UInt16)framesToSend.Count);
                //	txOffset += (int) framesSent;
                //}
            }

            // Receive frames
            {
                var rxCountOnDevice = NativeFunctions.GetReceiveNum(this.FDevice.DeviceType
                                                                    , this.FDevice.DeviceIndex
                                                                    , this.FChannelIndex);

                if (rxCountOnDevice > 0)
                {
                    var rxBuffer = new NativeFunctions.CAN_OBJ[rxCountOnDevice];

                    var rxCount = NativeFunctions.ReceiveArray(this.FDevice.DeviceType
                                                               , this.FDevice.DeviceIndex
                                                               , this.FChannelIndex
                                                               , rxBuffer
                                                               , (UInt32)rxBuffer.Length
                                                               , 0);

                    for (int i = 0; i < rxCount; i++)
                    {
                        var nativeFrame = rxBuffer[i];

                        var frame = new Candle.Frame();
                        {
                            frame.Identifier = nativeFrame.ID;
                            frame.Extended   = nativeFrame.ExternFlag == 1;
                            frame.RTR        = nativeFrame.RemoteFlag == 1;
                            frame.Error      = false;                        // Not sure how we get error frames with GCAN

                            frame.Data = new byte[nativeFrame.DataLen];
                            Buffer.BlockCopy(nativeFrame.data, 0, frame.Data, 0, nativeFrame.DataLen);

                            frame.Timestamp = nativeFrame.TimeStamp;
                        }

                        this.IncrementRx(frame.LengthOnBus);
                        this.FRxQueue.Add(frame);
                    }
                }
            }
        }