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