示例#1
0
        private void HandleAnalogPinEvent(PortEvent evt)
        {
            Port port = _ports.GetPort(evt.PortId);

            if (evt.Event == Message.EventSingleSample)
            {
                PortType type = port.Type;
                if (type == PortType.AnalogInputOnDemand)
                {
                    port.PushEvent(evt);
                    return;
                }
                else
                {
                    Int32  v     = (Int32)evt.Value1;
                    double value = v < 0 ? v / 2147483648.0 : v / 2147483647.0;
                    port.LastSample = evt.Value1;

                    if (_analogInputCallbacks.TryGetValue(port.Id, out AnalogInputCallback callback))
                    {
                        callback(port.Id, value);
                    }
                }
            }
        }
示例#2
0
        private void HandleDigitalPinEvent(PortEvent evt)
        {
            Port port = _ports.GetPort(evt.PortId);

            if (evt.Event == Message.EventSingleSample)
            {
                PortType type = port.Type;
                if (type == PortType.DigitalInputOnDemand)
                {
                    port.PushEvent(evt);
                    return;
                }
                else if (type == PortType.DigitalInputPrecached || type == PortType.DigitalInputTriggering)
                {
                    bool value = evt.Value1 != 0;
                    port.LastSample = evt.Value1;

                    if (type == PortType.DigitalInputTriggering)
                    {
                        if (_digitalInputCallbacks.TryGetValue(port.Id, out DigitalInputCallback callback))
                        {
                            callback(port.Id, value);
                        }
                    }
                }
            }
            else if (evt.Event == Message.EventSetDone)
            {
                _throttler.RequestCompleted(evt.RequestId);
            }
        }
示例#3
0
        private void HandleInput(byte[] data, int offset)
        {
            byte messageType = data[offset + 2];

            if (messageType == Message.MessageTypeConfigResponse)
            {
                ConfigResponse response = new ConfigResponse();
                response.Read(data, offset);
                //response.Dump();
                if (_deviceState == DeviceState.Ready || response.RequestId == 0xffff)
                {
                    HandleConfigResponse(response);
                }
            }
            else if (messageType == Message.MessageTypePortEvent)
            {
                PortEvent evt = new PortEvent();
                //evt.Dump();
                evt.Read(data, offset);
                if (_deviceState == DeviceState.Ready)
                {
                    HandlePortEvent(evt);
                }
            }
            else
            {
                throw new WirekiteException(String.Format("Invalid message type ({0}) received", messageType));
            }
        }
示例#4
0
        /// <summary>
        /// Reads the value of the digital input.
        /// </summary>
        /// <param name="port">the digital input's port ID</param>
        /// <returns>the input value</returns>
        public bool ReadDigitalPin(int port)
        {
            Port p = _ports.GetPort(port);

            if (p == null)
            {
                throw new WirekiteException(String.Format("Invalid port ID {0}", port));
            }

            PortType type = p.Type;

            if (type == PortType.DigitalInputPrecached || type == PortType.DigitalInputTriggering)
            {
                return(p.LastSample != 0);
            }

            PortRequest request = new PortRequest {
                PortId = (UInt16)port,
                Action = Message.PortActionGetValue
            };

            SubmitPortRequest(request);

            PortEvent evt = p.WaitForEvent();

            return(evt.Value1 != 0);
        }
示例#5
0
        /// <summary>
        /// Send data to and request data from an I2C slave in a single operation
        /// </summary>
        /// <remarks>
        /// <para>
        /// The operation performs a complete I2C transaction, starting with a START condition,
        /// a RESTART condition when switching from transmission to receipt, and ending with
        /// a STOP condition.
        /// </para>
        /// <para>
        /// The request is executed sychnronously, i.e. the call blocks until the data
        /// has been transmitted and received, or the transmission has failed.
        /// </para>
        /// <para>
        /// If less than the specified number of bytes are transmitted, `nil` is returned and
        /// <see cref="GetLastI2CResult(int)"/> returns the associated reason.
        /// </para>
        /// </remarks>
        /// <param name="port">the I2C port ID</param>
        /// <param name="data">the data to transmit</param>
        /// <param name="slave">the slave address</param>
        /// <param name="receiveLength">the number of bytes of data request from the slave</param>
        /// <returns>the received data or <c>null</c> if the transaction fails</returns>
        public byte[] SendAndRequestOnI2CPort(int port, byte[] data, int slave, int receiveLength)
        {
            Port p = _ports.GetPort(port);

            if (p == null)
            {
                throw new WirekiteException(String.Format("Invalid port ID {0}", port));
            }

            PortRequest request = new PortRequest
            {
                PortId           = (UInt16)port,
                Action           = Message.PortActionTxNRxData,
                Data             = data,
                ActionAttribute2 = (UInt16)slave,
                Value1           = (UInt16)receiveLength
            };

            WaitUntilAvailable(request);
            WriteMessage(request);

            PortEvent response = _pendingRequests.WaitForResponse(request.RequestId) as PortEvent;

            p.LastSample = response.EventAttribute1; // status code
            return(response.Data);
        }
示例#6
0
        /// <summary>
        /// Reset the I2C bus
        /// </summary>
        /// <remarks>
        /// If an I2C transaction is interrupted, a slave can still hold on to SDA
        /// because it believes to be in the middle of a byte.
        /// By toggling SCL up to 9 times, most slaves let go of SDA.
        /// This method can be used if an I2C operation returns a "bus busy" error.
        /// </remarks>
        /// <param name="port">hte I2C port ID</param>
        public void ResetBusOnI2CPort(int port)
        {
            if (_deviceState == DeviceState.Closed)
            {
                return; // silently ignore
            }
            Port p = _ports.GetPort(port);

            if (p == null)
            {
                return;
            }

            PortRequest request = new PortRequest
            {
                Action = Message.PortActionReset,
                PortId = (UInt16)port
            };

            WaitUntilAvailable(request);

            PortEvent response = _pendingRequests.WaitForResponse(request.RequestId) as PortEvent;

            p.LastSample = response.EventAttribute1; // status code
        }
示例#7
0
        /// <summary>
        /// Request data from an SPI slave
        /// </summary>
        /// <para>
        /// The operation performs a complete SPI transaction, i.e. enables the clock for the duration of
        /// transation and receives the data.
        /// </para>
        /// <para>
        /// The operation is executed sychnronously, i.e.the call blocks until the
        /// transaction has been completed or has failed. If the transaction fails,
        /// use <see cref="GetLastSPIResult(int)"/> to retrieve the reason.
        /// </para>
        /// <para>
        /// SPI is a full-duplex protocol at all times. Unless they use additional connections, slaves
        /// cannot distinguish between read and write transactions.
        /// This member functions send a configurable value on the MOSI line during the read.
        /// Default value is 0xff.
        /// </para>
        /// <param name="port">the SPI port ID</param>
        /// <param name="length">the number of bytes of data requested from the slave</param>
        /// <param name="chipSelect">the digital output port ID to use as chip select (or <see cref="InvalidPortId"/> if not used)</param>
        /// <param name="mosiValue">byte value sent on MOSI signal during reading</param>
        /// <returns>the received data or <c>null</c> if it fails</returns>
        public byte[] RequestOnSPIPort(int port, int length, int chipSelect, int mosiValue = 0xff)
        {
            Port p = _ports.GetPort(port);

            if (p == null)
            {
                throw new WirekiteException(String.Format("Invalid port ID {0}", port));
            }

            PortRequest request = new PortRequest
            {
                PortId           = (UInt16)port,
                Action           = Message.PortActionRxData,
                ActionAttribute1 = (byte)mosiValue,
                ActionAttribute2 = (UInt16)chipSelect,
                Value1           = (uint)length,
                RequestId        = _ports.NextRequestId()
            };

            WaitUntilAvailable(request);
            WriteMessage(request);

            PortEvent response = _pendingRequests.WaitForResponse(request.RequestId) as PortEvent;

            p.LastSample = response.EventAttribute1; // status code
            return(response.Data);
        }
示例#8
0
            public PortEventExt(PortEvent ev)
                : base(ev.PortKey, ev.State, ev.RevNum, ev.Timestamp)
            {
                PortKey p = new PortKey(ev.PortKey);

                this.ThingUID = p.ThingKey.ThingUID;
                this.PortUID  = p.PortUID;
            }
示例#9
0
        private void HandleI2CEvent(PortEvent evt)
        {
            Port p = _ports.GetPort(evt.PortId);

            if (p == null)
            {
                throw new WirekiteException(String.Format("Invalid port ID {0}", evt.PortId));
            }

            if (evt.RequestId != 0)
            {
                _throttler.RequestCompleted(evt.RequestId);
                _pendingRequests.PutResponse(evt.RequestId, evt);
            }
        }
示例#10
0
 private void Start()
 {
     if (ipEvent == null)
     {
         ipEvent = new IPEvent();
     }
     if (portEvent == null)
     {
         portEvent = new PortEvent();
     }
     if (workModEvent == null)
     {
         workModEvent = new WorkModEvent();
     }
 }
示例#11
0
        /// <summary>
        /// Transmit and request data from an SPI slave
        /// </summary>
        /// <para>
        /// The operations is performed in a full-duplex fashion, i.e. the data is transmitted and received at
        /// the same time. For that reason, the number of received bytes equals the number of transmitted bytes.
        /// </para>
        /// <para>
        /// The operation performs a complete SPI transaction, i.e.enables the clock for the duration of
        /// transation and transmits and receives the data.
        /// </para>
        /// <para>
        /// The operation is executed sychnronously, i.e. the call blocks until the
        /// transaction has been completed or has failed. If the transaction fails,
        /// use <see cref="GetLastSPIResult(int)"/> to retrieve the reason.
        /// </para>
        /// <param name="port">the SPI port ID</param>
        /// <param name="data"> data to transmit</param>
        /// <param name="chipSelect">digital output port ID to use as chip select (or <see cref="InvalidPortId"/> if not used)</param>
        /// <returns>received data or <c>null</c> if it fails</returns>
        public byte[] TransmitAndRequestOnSPIPort(int port, byte[] data, int chipSelect)
        {
            Port p = _ports.GetPort(port);

            if (p == null)
            {
                throw new WirekiteException(String.Format("Invalid port ID {0}", port));
            }

            UInt16 requestId = SubmitSPITx(port, data, chipSelect, Message.PortActionTxNRxData);

            PortEvent response = _pendingRequests.WaitForResponse(requestId) as PortEvent;

            p.LastSample = response.EventAttribute1; // status code
            return(response.Data);
        }
示例#12
0
        /// <summary>
        /// Reads the value of the analog input.
        /// </summary>
        /// <param name="port">the analog input's port ID</param>
        /// <returns>the input value in the range between -1.0 and 1.0</returns>
        public double ReadAnalogPin(int port)
        {
            Port p = _ports.GetPort(port);

            if (p == null)
            {
                throw new WirekiteException(String.Format("Invalid port ID {0}", port));
            }

            PortRequest request = new PortRequest
            {
                PortId = (UInt16)port,
                Action = Message.PortActionGetValue
            };

            SubmitPortRequest(request);

            PortEvent evt = p.WaitForEvent();
            Int32     v   = (Int32)evt.Value1;

            return(v < 0 ? v / 2147483648.0 : v / 2147483647.0);
        }
示例#13
0
        /// <summary>
        /// Send data to an I2C slave
        /// </summary>
        /// <remarks>
        /// <para>
        /// The operation performs a complete I2C transaction, starting with a START condition
        /// and ending with a STOP condition
        /// </para>
        /// <para>
        /// The request is executed sychnronously, i.e. the call blocks until the data
        /// has been transmitted or the transmission has failed.
        /// </para>
        /// <para>
        /// If less than the specified number of bytes are transmitted,
        /// <see cref="GetLastI2CResult(int)"/> returns the associated reason.
        /// </para>
        /// </remarks>
        /// <param name="port">the I2C port ID</param>
        /// <param name="data">the data to transmit</param>
        /// <param name="slave">the slave address</param>
        /// <returns>the number of sent bytes</returns>
        public int SendOnI2CPort(int port, byte[] data, int slave)
        {
            if (_deviceState == DeviceState.Closed)
            {
                Debug.Write("Wirekite: Device has been closed or disconnected. I2C operation is ignored.");
                return(0);
            }

            Port p = _ports.GetPort(port);

            if (p == null)
            {
                throw new WirekiteException(String.Format("Invalid port ID {0}", port));
            }

            UInt16 requestId = SubmitI2CTx(port, data, slave);

            PortEvent response = _pendingRequests.WaitForResponse(requestId) as PortEvent;

            p.LastSample = response.EventAttribute1; // status code
            return(response.EventAttribute2);
        }
示例#14
0
        private void HandlePortEvent(PortEvent evt)
        {
            Port port = _ports.GetPort(evt.PortId);

            if (port == null)
            {
                throw new WirekiteException(String.Format("Port event received for invalid port ID {0}", evt.PortId));
            }

            PortType type = port.Type;

            switch (type)
            {
            case PortType.DigitalInputOnDemand:
            case PortType.DigitalInputPrecached:
            case PortType.DigitalInputTriggering:
            case PortType.DigitalOutput:
                HandleDigitalPinEvent(evt);
                break;

            case PortType.AnalogInputOnDemand:
            case PortType.AnalogInputSampling:
                HandleAnalogPinEvent(evt);
                break;

            case PortType.I2CPort:
                HandleI2CEvent(evt);
                break;

            case PortType.SPIPort:
                HandleSPIEvent(evt);
                break;

            default:
                throw new WirekiteException(String.Format("Port event received for invalid for type {0} of port ID {1}", type, evt.PortId));
            }
        }
示例#15
0
        // Token: 0x0600016F RID: 367 RVA: 0x00005F6C File Offset: 0x0000416C
        public void SendEvent(PortEvent e)
        {
            Guid id = e.ID;

            this.Port.PortEventsCP.Event(this.Port.PortSupplier.Server, this.Port, this, this, e, ref id);
        }
示例#16
0
 internal void PushEvent(PortEvent evt)
 {
     _eventQueue.TryAdd(evt);
 }