예제 #1
0
        /// <summary>
        /// Registers the interrupt callback on the pin. Pin mode has to be set to Input.
        ///
        /// </summary>
        /// <param name="edgeDetection">The edge detection.</param>
        /// <param name="callback">The callback.</param>
        /// <exception cref="System.ArgumentException">callback</exception>
        /// <exception cref="System.InvalidOperationException">
        /// An interrupt callback was already registered.
        /// or
        /// RegisterInterruptCallback
        /// </exception>
        /// <exception cref="System.InvalidProgramException"></exception>
        public void RegisterInterruptCallback(EdgeDetection edgeDetection, InterrputServiceRoutineCallback callback)
        {
            if (callback == null)
            {
                throw new ArgumentException($"{nameof(callback)} cannot be null");
            }

            if (InterruptCallback != null)
            {
                throw new InvalidOperationException("An interrupt callback was already registered.");
            }

            if (PinMode != GpioPinDriveMode.Input)
            {
                throw new InvalidOperationException($"Unable to {nameof(RegisterInterruptCallback)} for pin {PinNumber} because operating mode is {PinMode}."
                                                    + $" Calling {nameof(RegisterInterruptCallback)} is only allowed if {nameof(PinMode)} is set to {GpioPinDriveMode.Input}");
            }

            lock (_syncLock)
            {
                var registerResult = WiringPi.wiringPiISR(PinNumber, (int)edgeDetection, callback);
                if (registerResult == 0)
                {
                    InterruptEdgeDetection = edgeDetection;
                    InterruptCallback      = callback;
                }
                else
                {
                    HardwareException.Throw(nameof(GpioPin), nameof(RegisterInterruptCallback));
                }
            }
        }
예제 #2
0
        public void ExceptionMessageIsFirstErrorMessage()
        {
            var error1    = new HardwareError(HardwareErrorSeverity.Critical, HardwareErrorClass.Device, 1, "1");
            var error2    = new HardwareError(HardwareErrorSeverity.Critical, HardwareErrorClass.Device, 2, "2");
            var exception = new HardwareException(new HardwareError[] { error1, error2 });

            Assert.AreEqual(error1.Message, exception.Message);
        }
예제 #3
0
        /// <summary>
        /// This attempts to shift your program (or thread in a multi-threaded program) to a higher priority and
        /// enables a real-time scheduling. The priority parameter should be from 0 (the default) to 99 (the maximum).
        /// This won’t make your program go any faster, but it will give it a bigger slice of time when other programs
        /// are running. The priority parameter works relative to others – so you can make one program priority 1 and
        /// another priority 2 and it will have the same effect as setting one to 10 and the other to 90
        /// (as long as no other programs are running with elevated priorities).
        /// </summary>
        /// <param name="priority">The priority.</param>
        public void SetThreadPriority(int priority)
        {
            priority = priority.Clamp(0, 99);
            var result = WiringPi.PiHiPri(priority);

            if (result < 0)
            {
                HardwareException.Throw(nameof(Timing), nameof(SetThreadPriority));
            }
        }
예제 #4
0
 /// <summary>
 /// These write an 8 or 16-bit data value into the device register indicated.
 /// </summary>
 /// <param name="address">The register.</param>
 /// <param name="data">The data.</param>
 public void WriteAddressWord(int address, ushort data)
 {
     lock (SyncLock)
     {
         var result = WiringPi.wiringPiI2CWriteReg16(FileDescriptor, address, data);
         if (result < 0)
         {
             HardwareException.Throw(nameof(I2CDevice), nameof(WriteAddressWord));
         }
     }
 }
예제 #5
0
 /// <summary>
 /// Writes a byte of data the specified file descriptor.
 /// </summary>
 /// <param name="data">The data.</param>
 public void Write(byte data)
 {
     lock (SyncLock)
     {
         var result = WiringPi.wiringPiI2CWrite(FileDescriptor, data);
         if (result < 0)
         {
             HardwareException.Throw(nameof(I2CDevice), nameof(Write));
         }
     }
 }
예제 #6
0
 /// <summary>
 /// These write an 8 or 16-bit data value into the device register indicated.
 /// </summary>
 /// <param name="address">The register.</param>
 /// <param name="data">The data.</param>
 public void WriteAddressByte(int address, byte data)
 {
     lock (_syncLock)
     {
         var result = WiringPi.WiringPiI2CWriteReg8(FileDescriptor, address, data);
         if (result < 0)
         {
             HardwareException.Throw(nameof(I2CDevice), nameof(WriteAddressByte));
         }
     }
 }
예제 #7
0
 /// <summary>
 /// Reads a byte from the specified file descriptor
 /// </summary>
 /// <returns>The byte from device</returns>
 public byte Read()
 {
     lock (SyncLock)
     {
         var result = WiringPi.wiringPiI2CRead(FileDescriptor);
         if (result < 0)
         {
             HardwareException.Throw(nameof(I2CDevice), nameof(Read));
         }
         return((byte)result);
     }
 }
예제 #8
0
        /// <summary>
        /// Writes the specified buffer the the underlying FileDescriptor.
        /// Do not use this method if you expect data back.
        /// This method is efficient if used in a fire-and-forget scenario
        /// like sending data over to those long RGB LED strips
        /// </summary>
        /// <param name="buffer">The buffer.</param>
        public void Write(byte[] buffer)
        {
            lock (_syncLock)
            {
                var result = Standard.write(FileDescriptor, buffer, buffer.Length);

                if (result < 0)
                {
                    HardwareException.Throw(nameof(SpiChannel), nameof(Write));
                }
            }
        }
예제 #9
0
        /// <summary>
        /// These read an 8 or 16-bit value from the device register indicated.
        /// </summary>
        /// <param name="address">The register.</param>
        /// <returns>The address word from device</returns>
        public ushort ReadAddressWord(int address)
        {
            lock (SyncLock)
            {
                var result = WiringPi.wiringPiI2CReadReg16(FileDescriptor, address);
                if (result < 0)
                {
                    HardwareException.Throw(nameof(I2CDevice), nameof(ReadAddressWord));
                }

                return(Convert.ToUInt16(result));
            }
        }
예제 #10
0
        /// <summary>
        /// These read an 8 or 16-bit value from the device register indicated.
        /// </summary>
        /// <param name="address">The register.</param>
        /// <returns>The address byte from device</returns>
        public byte ReadAddressByte(int address)
        {
            lock (SyncLock)
            {
                var result = WiringPi.wiringPiI2CReadReg8(FileDescriptor, address);
                if (result < 0)
                {
                    HardwareException.Throw(nameof(I2CDevice), nameof(ReadAddressByte));
                }

                return((byte)result);
            }
        }
예제 #11
0
 /// <summary>
 /// Writes a set of bytes to the specified file descriptor.
 /// </summary>
 /// <param name="data">The data.</param>
 public void Write(byte[] data)
 {
     lock (_syncLock)
     {
         foreach (var b in data)
         {
             var result = WiringPi.WiringPiI2CWrite(FileDescriptor, b);
             if (result < 0)
             {
                 HardwareException.Throw(nameof(I2CDevice), nameof(Write));
             }
         }
     }
 }
예제 #12
0
        /// <summary>
        /// Initializes a new instance of the <see cref="SpiChannel"/> class.
        /// </summary>
        /// <param name="channel">The channel.</param>
        /// <param name="frequency">The frequency.</param>
        private SpiChannel(SpiChannelNumber channel, int frequency)
        {
            lock (SyncRoot)
            {
                Frequency      = frequency.Clamp(MinFrequency, MaxFrequency);
                Channel        = (int)channel;
                FileDescriptor = WiringPi.WiringPiSPISetup((int)channel, Frequency);

                if (FileDescriptor < 0)
                {
                    HardwareException.Throw(nameof(SpiChannel), channel.ToString());
                }
            }
        }
예제 #13
0
        /// <inheritdoc />
        /// <summary>
        /// This is really nothing more than a simplified interface to the Posix threads mechanism that Linux supports.
        /// See the manual pages on Posix threads (man pthread) if you need more control over them.
        /// </summary>
        /// <exception cref="ArgumentNullException">worker.</exception>
        public void StartThread(Action worker)
        {
            if (worker == null)
            {
                throw new ArgumentNullException(nameof(worker));
            }

            var result = WiringPi.PiThreadCreate(new ThreadWorker(worker));

            if (result != 0)
            {
                HardwareException.Throw(nameof(Timing), nameof(StartThread));
            }
        }
예제 #14
0
        /// <summary>
        /// Reads a buffer of the specified length, one byte at a time
        /// </summary>
        /// <param name="length">The length.</param>
        /// <returns>The byte array from device</returns>
        public byte[] Read(int length)
        {
            lock (SyncLock)
            {
                var buffer = new byte[length];
                for (var i = 0; i < length; i++)
                {
                    var result = WiringPi.wiringPiI2CRead(FileDescriptor);
                    if (result < 0)
                    {
                        HardwareException.Throw(nameof(I2CDevice), nameof(Read));
                    }
                    buffer[i] = (byte)result;
                }

                return(buffer);
            }
        }
예제 #15
0
        /// <summary>
        /// Read a block of data from the register provided.
        /// </summary>
        /// <param name="address">The register.</param>
        /// <param name="count">The number of elements.</param>
        /// <returns>The result</returns>
        public byte[] ReadAddressBlock(int address, int count)
        {
            lock (_syncLock)
            {
                var ptr = Marshal.AllocHGlobal(count);

                var result = WiringPi.WiringPiI2CReadRegBlock(FileDescriptor, address, count, ptr);
                if (result < 0)
                {
                    HardwareException.Throw(nameof(I2CDevice), nameof(ReadAddressByte));
                }

                byte[] dest = new byte[count];
                Marshal.Copy(ptr, dest, 0, count);
                Marshal.FreeHGlobal(ptr);

                return(dest);
            }
        }
예제 #16
0
        /// <summary>
        /// Sends data and simultaneously receives the data in the return buffer
        /// </summary>
        /// <param name="buffer">The buffer.</param>
        /// <returns></returns>
        public byte[] SendReceive(byte[] buffer)
        {
            if (buffer == null || buffer.Length == 0)
            {
                return(null);
            }

            lock (_syncLock)
            {
                var spiBuffer = new byte[buffer.Length];
                Array.Copy(buffer, spiBuffer, buffer.Length);

                var result = WiringPi.wiringPiSPIDataRW(Channel, spiBuffer, spiBuffer.Length);
                if (result < 0)
                {
                    HardwareException.Throw(nameof(SpiChannel), nameof(SendReceive));
                }

                return(spiBuffer);
            }
        }