This commit is contained in:
2019-12-04 18:57:18 +01:00
parent 4692422c9a
commit 6263791dff
225 changed files with 33065 additions and 2 deletions
@@ -0,0 +1,28 @@
namespace Unosquare.RaspberryIO.Abstractions
{
/// <summary>
/// Represents Definitions for GPIO information.
/// </summary>
public static class Definitions
{
private static readonly int[] GpioToPhysR1 =
{
3, 5, -1, -1, 7, -1, -1, 26, 24, 21, 19, 23, -1, -1, 8, 10, -1, 11, 12, -1, -1, 13, 15, 16, 18, 22, -1, -1, -1, -1, -1, -1,
};
private static readonly int[] GpioToPhysR2 =
{
27, 28, 3, 5, 7, 29, 31, 26, 24, 21, 19, 23, 32, 33, 8, 10, 36, 11, 12, 35, 38, 40, 15, 16, 18, 22, 37, 13, // P1
3, 4, 5, 6, // P5
};
/// <summary>
/// BCMs to physical pin number.
/// </summary>
/// <param name="rev">The rev.</param>
/// <param name="bcmPin">The BCM pin.</param>
/// <returns>The physical pin number.</returns>
public static int BcmToPhysicalPinNumber(BoardRevision rev, BcmPin bcmPin) =>
rev == BoardRevision.Rev1 ? GpioToPhysR1[(int)bcmPin] : GpioToPhysR2[(int)bcmPin];
}
}
+527
View File
@@ -0,0 +1,527 @@
namespace Unosquare.RaspberryIO.Abstractions
{
/// <summary>
/// Defines the SPI channel numbers.
/// </summary>
public enum SpiChannelNumber
{
/// <summary>
/// The channel 0
/// </summary>
Channel0 = 0,
/// <summary>
/// The channel 1
/// </summary>
Channel1 = 1,
}
/// <summary>
/// Defines the GPIO Pin values 0 for low, 1 for High.
/// </summary>
public enum GpioPinValue
{
/// <summary>
/// Digital high
/// </summary>
High = 1,
/// <summary>
/// Digital low
/// </summary>
Low = 0,
}
/// <summary>
/// The GPIO pin resistor mode. This is used on input pins so that their
/// lines are not floating.
/// </summary>
public enum GpioPinResistorPullMode
{
/// <summary>
/// Pull resistor not active. Line floating
/// </summary>
Off = 0,
/// <summary>
/// Pull resistor sets a default value of 0 on no-connects
/// </summary>
PullDown = 1,
/// <summary>
/// Pull resistor sets a default value of 1 on no-connects
/// </summary>
PullUp = 2,
}
/// <summary>
/// Defines the different drive modes of a GPIO pin.
/// </summary>
public enum GpioPinDriveMode
{
/// <summary>
/// Input drive mode (perform reads)
/// </summary>
Input = 0,
/// <summary>
/// Output drive mode (perform writes)
/// </summary>
Output = 1,
/// <summary>
/// PWM output mode (only certain pins support this -- 2 of them at the moment)
/// </summary>
PwmOutput = 2,
/// <summary>
/// GPIO Clock output mode (only a pin supports this at this time)
/// </summary>
GpioClock = 3,
/// <summary>
/// The alt0 operating mode
/// </summary>
Alt0 = 4,
/// <summary>
/// The alt1 operating mode
/// </summary>
Alt1 = 5,
/// <summary>
/// The alt2 operating mode
/// </summary>
Alt2 = 6,
/// <summary>
/// The alt3 operating mode
/// </summary>
Alt3 = 7,
}
/// <summary>
/// Defines the different threading locking keys.
/// </summary>
public enum ThreadLockKey
{
/// <summary>
/// The lock 0
/// </summary>
Lock0 = 0,
/// <summary>
/// The lock 1
/// </summary>
Lock1 = 1,
/// <summary>
/// The lock 2
/// </summary>
Lock2 = 2,
/// <summary>
/// The lock 3
/// </summary>
Lock3 = 3,
}
/// <summary>
/// Defines the different edge detection modes for pin interrupts.
/// </summary>
public enum EdgeDetection
{
/// <summary>
/// Falling Edge
/// </summary>
FallingEdge,
/// <summary>
/// Rising edge
/// </summary>
RisingEdge,
/// <summary>
/// Both, falling and rising edges
/// </summary>
FallingAndRisingEdge,
}
/// <summary>
/// The hardware revision of the board.
/// </summary>
public enum BoardRevision
{
/// <summary>
/// Revision 1 (the early Model A and B's).
/// </summary>
Rev1 = 1,
/// <summary>
/// Revision 2 (everything else - it covers the B, B+ and CM).
/// </summary>
Rev2 = 2,
}
/// <summary>
/// Defines the Header connectors available.
/// </summary>
public enum GpioHeader
{
/// <summary>
/// Not defined
/// </summary>
None,
/// <summary>
/// P1 connector (main connector)
/// </summary>
P1,
/// <summary>
/// P5 connector (auxiliary, not commonly used)
/// </summary>
P5,
}
/// <summary>
/// Defines all the BCM Pin numbers available for the user.
/// </summary>
public enum BcmPin
{
/// <summary>
/// GPIO 0
/// </summary>
Gpio00 = 0,
/// <summary>
/// GPIO 1
/// </summary>
Gpio01 = 1,
/// <summary>
/// GPIO02
/// </summary>
Gpio02 = 2,
/// <summary>
/// GPIO 3
/// </summary>
Gpio03 = 3,
/// <summary>
/// GPIO 4
/// </summary>
Gpio04 = 4,
/// <summary>
/// GPIO 5
/// </summary>
Gpio05 = 5,
/// <summary>
/// GPIO 6
/// </summary>
Gpio06 = 6,
/// <summary>
/// GPIO 7
/// </summary>
Gpio07 = 7,
/// <summary>
/// GPIO 8
/// </summary>
Gpio08 = 8,
/// <summary>
/// GPIO 9
/// </summary>
Gpio09 = 9,
/// <summary>
/// GPIO 10
/// </summary>
Gpio10 = 10,
/// <summary>
/// GPIO 11
/// </summary>
Gpio11 = 11,
/// <summary>
/// GPIO 12
/// </summary>
Gpio12 = 12,
/// <summary>
/// GPIO 13
/// </summary>
Gpio13 = 13,
/// <summary>
/// GPIO 14
/// </summary>
Gpio14 = 14,
/// <summary>
/// GPIO 15
/// </summary>
Gpio15 = 15,
/// <summary>
/// GPIO 16
/// </summary>
Gpio16 = 16,
/// <summary>
/// GPIO 17
/// </summary>
Gpio17 = 17,
/// <summary>
/// GPIO 18
/// </summary>
Gpio18 = 18,
/// <summary>
/// GPIO 19
/// </summary>
Gpio19 = 19,
/// <summary>
/// GPIO 20
/// </summary>
Gpio20 = 20,
/// <summary>
/// GPIO 21
/// </summary>
Gpio21 = 21,
/// <summary>
/// GPIO 22
/// </summary>
Gpio22 = 22,
/// <summary>
/// GPIO 23
/// </summary>
Gpio23 = 23,
/// <summary>
/// GPIO 24
/// </summary>
Gpio24 = 24,
/// <summary>
/// GPIO 25
/// </summary>
Gpio25 = 25,
/// <summary>
/// GPIO 26
/// </summary>
Gpio26 = 26,
/// <summary>
/// GPIO 27
/// </summary>
Gpio27 = 27,
/// <summary>
/// GPIO 28
/// </summary>
Gpio28 = 28,
/// <summary>
/// GPIO 29
/// </summary>
Gpio29 = 29,
/// <summary>
/// GPIO 30
/// </summary>
Gpio30 = 30,
/// <summary>
/// GPIO 31
/// </summary>
Gpio31 = 31,
}
/// <summary>
/// Enumerates the different pins on the P1 Header.
/// Enumeration values correspond to the physical pin number.
/// </summary>
public enum P1
{
/// <summary>
/// Header P1 Physical Pin 3. GPIO 0 for rev1 or GPIO 2 for rev2.
/// </summary>
Pin03 = 3,
/// <summary>
/// Header P1 Physical Pin 5. GPIO 1 for rev1 or GPIO 3 for rev2.
/// </summary>
Pin05 = 5,
/// <summary>
/// Header P1 Physical Pin 7. GPIO 4.
/// </summary>
Pin07 = 7,
/// <summary>
/// Header P1 Physical Pin 11. GPIO 17.
/// </summary>
Pin11 = 11,
/// <summary>
/// Header P1 Physical Pin 13. GPIO 21 for rev1 or GPIO 27 for rev2.
/// </summary>
Pin13 = 13,
/// <summary>
/// Header P1 Physical Pin 15. GPIO 22.
/// </summary>
Pin15 = 15,
/// <summary>
/// Header P1 Physical Pin 19. GPIO 10.
/// </summary>
Pin19 = 19,
/// <summary>
/// Header P1 Physical Pin 21. GPIO 9.
/// </summary>
Pin21 = 21,
/// <summary>
/// Header P1 Physical Pin 23. GPIO 11.
/// </summary>
Pin23 = 23,
/// <summary>
/// Header P1 Physical Pin 27. GPIO 0.
/// </summary>
Pin27 = 27,
/// <summary>
/// Header P1 Physical Pin 29. GPIO 5.
/// </summary>
Pin29 = 29,
/// <summary>
/// Header P1 Physical Pin 31. GPIO 6.
/// </summary>
Pin31 = 31,
/// <summary>
/// Header P1 Physical Pin 33. GPIO 13.
/// </summary>
Pin33 = 33,
/// <summary>
/// Header P1 Physical Pin 35. GPIO 19.
/// </summary>
Pin35 = 35,
/// <summary>
/// Header P1 Physical Pin 37. GPIO 26.
/// </summary>
Pin37 = 37,
/// <summary>
/// Header P1 Physical Pin 8. GPIO 14.
/// </summary>
Pin08 = 8,
/// <summary>
/// Header P1 Physical Pin 10. GPIO 15.
/// </summary>
Pin10 = 10,
/// <summary>
/// Header P1 Physical Pin 12. GPIO 18.
/// </summary>
Pin12 = 12,
/// <summary>
/// Header P1 Physical Pin 16. GPIO 23.
/// </summary>
Pin16 = 16,
/// <summary>
/// Header P1 Physical Pin 18. GPIO 24.
/// </summary>
Pin18 = 18,
/// <summary>
/// Header P1 Physical Pin 22. GPIO 25.
/// </summary>
Pin22 = 22,
/// <summary>
/// Header P1 Physical Pin 24. GPIO 8.
/// </summary>
Pin24 = 24,
/// <summary>
/// Header P1 Physical Pin 26. GPIO 7.
/// </summary>
Pin26 = 26,
/// <summary>
/// Header P1 Physical Pin 28. GPIO 1.
/// </summary>
Pin28 = 28,
/// <summary>
/// Header P1 Physical Pin 32. GPIO 12.
/// </summary>
Pin32 = 32,
/// <summary>
/// Header P1 Physical Pin 36. GPIO 16.
/// </summary>
Pin36 = 36,
/// <summary>
/// Header P1 Physical Pin 38. GPIO 20.
/// </summary>
Pin38 = 38,
/// <summary>
/// Header P1 Physical Pin 40. GPIO 21.
/// </summary>
Pin40 = 40,
}
/// <summary>
/// Enumerates the different pins on the P5 Header
/// as commonly referenced by Raspberry Pi documentation.
/// Enumeration values correspond to the physical pin number.
/// </summary>
public enum P5
{
/// <summary>
/// Header P5 Physical Pin 3, GPIO 28.
/// </summary>
Pin03 = 3,
/// <summary>
/// Header P5 Physical Pin 4, GPIO 29.
/// </summary>
Pin04 = 4,
/// <summary>
/// Header P5 Physical Pin 5, GPIO 30.
/// </summary>
Pin05 = 5,
/// <summary>
/// Header P5 Physical Pin 6, GPIO 31.
/// </summary>
Pin06 = 6,
}
}
@@ -0,0 +1,13 @@
namespace Unosquare.RaspberryIO.Abstractions
{
/// <summary>
/// Interface for bootstrapping an <see cref="Abstractions"/> implementation.
/// </summary>
public interface IBootstrap
{
/// <summary>
/// Bootstraps an <see cref="Abstractions"/> implementation.
/// </summary>
void Bootstrap();
}
}
@@ -0,0 +1,51 @@
namespace Unosquare.RaspberryIO.Abstractions
{
using System.Collections.Generic;
/// <summary>
/// Interface for Raspberry Pi GPIO controller.
/// </summary>
/// <seealso cref="System.Collections.Generic.IReadOnlyCollection{IGpioPin}" />
public interface IGpioController : IReadOnlyCollection<IGpioPin>
{
/// <summary>
/// Gets the <see cref="IGpioPin"/> with the specified BCM pin.
/// </summary>
/// <value>
/// The <see cref="IGpioPin"/>.
/// </value>
/// <param name="bcmPinNumber">The BCM pin number.</param>
/// <returns>A reference to the GPIO pin.</returns>
IGpioPin this[int bcmPinNumber] { get; }
/// <summary>
/// Gets the <see cref="IGpioPin"/> with the specified BCM pin.
/// </summary>
/// <value>
/// The <see cref="IGpioPin"/>.
/// </value>
/// <param name="bcmPin">The BCM pin.</param>
/// <returns>A reference to the GPIO pin.</returns>
IGpioPin this[BcmPin bcmPin] { get; }
/// <summary>
/// Gets the <see cref="IGpioPin"/> with the specified pin number.
/// </summary>
/// <value>
/// The <see cref="IGpioPin"/>.
/// </value>
/// <param name="pinNumber">The pin number in header P1.</param>
/// <returns>A reference to the GPIO pin.</returns>
IGpioPin this[P1 pinNumber] { get; }
/// <summary>
/// Gets the <see cref="IGpioPin"/> with the specified pin number.
/// </summary>
/// <value>
/// The <see cref="IGpioPin"/>.
/// </value>
/// <param name="pinNumber">The pin number in header P5.</param>
/// <returns>A reference to the GPIO pin.</returns>
IGpioPin this[P5 pinNumber] { get; }
}
}
@@ -0,0 +1,105 @@
namespace Unosquare.RaspberryIO.Abstractions
{
using System;
/// <summary>
/// Interface for GPIO Pin on a RaspberryPi board.
/// </summary>
public interface IGpioPin
{
/// <summary>
/// Gets the <see cref="Abstractions.BcmPin"/>.
/// </summary>
/// <value>
/// The pin number.
/// </value>
BcmPin BcmPin { get; }
/// <summary>
/// Gets the BCM chip (hardware) pin number.
/// </summary>
/// <value>
/// The pin number.
/// </value>
int BcmPinNumber { get; }
/// <summary>
/// Gets the physical (header) pin number.
/// </summary>
int PhysicalPinNumber { get; }
/// <summary>
/// Gets the pin's header (physical board) location.
/// </summary>
GpioHeader Header { get; }
/// <summary>
/// Gets or sets the pin operating mode.
/// </summary>
/// <value>
/// The pin mode.
/// </value>
GpioPinDriveMode PinMode { get; set; }
/// <summary>
/// This sets or gets the pull-up or pull-down resistor mode on the pin, which should be set as an input.
/// Unlike the Arduino, the BCM2835 has both pull-up an down internal resistors.
/// The parameter pud should be; PUD_OFF, (no pull up/down), PUD_DOWN (pull to ground) or PUD_UP (pull to 3.3v)
/// The internal pull up/down resistors have a value of approximately 50KΩ on the Raspberry Pi.
/// </summary>
GpioPinResistorPullMode InputPullMode { get; set; }
/// <summary>
/// Gets or sets a value indicating whether this <see cref="IGpioPin"/> is value.
/// </summary>
/// <value>
/// <c>true</c> if value; otherwise, <c>false</c>.
/// </value>
bool Value { get; set; }
/// <summary>
/// Reads the digital value on the pin as a boolean value.
/// </summary>
/// <returns>The state of the pin.</returns>
bool Read();
/// <summary>
/// Writes the specified bit value.
/// This method performs a digital write.
/// </summary>
/// <param name="value">if set to <c>true</c> [value].</param>
void Write(bool value);
/// <summary>
/// Writes the specified pin value.
/// This method performs a digital write.
/// </summary>
/// <param name="value">The value.</param>
void Write(GpioPinValue value);
/// <summary>
/// Wait for specific pin status.
/// </summary>
/// <param name="status">status to check.</param>
/// <param name="timeOutMillisecond">timeout to reach status.</param>
/// <returns>true/false.</returns>
bool WaitForValue(GpioPinValue status, int timeOutMillisecond);
/// <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 function. This function is called whenever
/// the interrupt occurs.</param>
void RegisterInterruptCallback(EdgeDetection edgeDetection, Action callback);
/// <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 function. This function is called whenever the interrupt occurs.
/// The function is passed the GPIO, the current level, and the current tick
/// (The number of microseconds since boot).</param>
void RegisterInterruptCallback(EdgeDetection edgeDetection, Action<int, int, uint> callback);
}
}
@@ -0,0 +1,39 @@
namespace Unosquare.RaspberryIO.Abstractions
{
using System.Collections.ObjectModel;
/// <summary>
/// Interfaces the I2c bus on the Raspberry Pi.
/// </summary>
public interface II2CBus
{
/// <summary>
/// Gets the registered devices as a read only collection.
/// </summary>
ReadOnlyCollection<II2CDevice> Devices { get; }
/// <summary>
/// Gets the <see cref="II2CDevice"/> with the specified device identifier.
/// </summary>
/// <value>
/// The <see cref="II2CDevice"/>.
/// </value>
/// <param name="deviceId">The device identifier.</param>
/// <returns>A reference to an I2C device.</returns>
II2CDevice this[int deviceId] { get; }
/// <summary>
/// Gets the device by identifier.
/// </summary>
/// <param name="deviceId">The device identifier.</param>
/// <returns>The device reference.</returns>
II2CDevice GetDeviceById(int deviceId);
/// <summary>
/// Adds a device to the bus by its Id. If the device is already registered it simply returns the existing device.
/// </summary>
/// <param name="deviceId">The device identifier.</param>
/// <returns>The device reference.</returns>
II2CDevice AddDevice(int deviceId);
}
}
@@ -0,0 +1,77 @@
namespace Unosquare.RaspberryIO.Abstractions
{
/// <summary>
/// Interfaces a device on the I2C Bus.
/// </summary>
public interface II2CDevice
{
/// <summary>
/// Gets the device identifier.
/// </summary>
/// <value>
/// The device identifier.
/// </value>
int DeviceId { get; }
/// <summary>
/// Gets the standard POSIX file descriptor.
/// </summary>
/// <value>
/// The file descriptor.
/// </value>
int FileDescriptor { get; }
/// <summary>
/// Reads a byte from the specified file descriptor.
/// </summary>
/// <returns>The byte from device.</returns>
byte Read();
/// <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>
byte[] Read(int length);
/// <summary>
/// Writes a byte of data the specified file descriptor.
/// </summary>
/// <param name="data">The data.</param>
void Write(byte data);
/// <summary>
/// Writes a set of bytes to the specified file descriptor.
/// </summary>
/// <param name="data">The data.</param>
void Write(byte[] data);
/// <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>
void WriteAddressByte(int address, byte data);
/// <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>
void WriteAddressWord(int address, ushort data);
/// <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>
byte ReadAddressByte(int address);
/// <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>
ushort ReadAddressWord(int address);
}
}
@@ -0,0 +1,48 @@
namespace Unosquare.RaspberryIO.Abstractions
{
/// <summary>
/// Interfaces a SPI Bus containing the 2 SPI channels.
/// </summary>
public interface ISpiBus
{
/// <summary>
/// Gets the default frequency.
/// </summary>
/// <value>
/// The default frequency.
/// </value>
int DefaultFrequency { get; }
/// <summary>
/// Gets or sets the channel 0 frequency in Hz.
/// </summary>
/// <value>
/// The channel0 frequency.
/// </value>
int Channel0Frequency { get; set; }
/// <summary>
/// Gets or sets the channel 1 frequency in Hz.
/// </summary>
/// <value>
/// The channel1 frequency.
/// </value>
int Channel1Frequency { get; set; }
/// <summary>
/// Gets the SPI bus on channel 0.
/// </summary>
/// <value>
/// The channel0.
/// </value>
ISpiChannel Channel0 { get; }
/// <summary>
/// Gets the SPI bus on channel 1.
/// </summary>
/// <value>
/// The channel0.
/// </value>
ISpiChannel Channel1 { get; }
}
}
@@ -0,0 +1,43 @@
namespace Unosquare.RaspberryIO.Abstractions
{
/// <summary>
/// Interfaces a SPI buses on the GPIO.
/// </summary>
public interface ISpiChannel
{
/// <summary>
/// Gets the standard initialization file descriptor.
/// anything negative means error.
/// </summary>
/// <value>
/// The file descriptor.
/// </value>
int FileDescriptor { get; }
/// <summary>
/// Gets the channel.
/// </summary>
int Channel { get; }
/// <summary>
/// Gets the frequency.
/// </summary>
int Frequency { get; }
/// <summary>
/// Sends data and simultaneously receives the data in the return buffer.
/// </summary>
/// <param name="buffer">The buffer.</param>
/// <returns>The read bytes from the ring-style bus.</returns>
byte[] SendReceive(byte[] buffer);
/// <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>
void Write(byte[] buffer);
}
}
@@ -0,0 +1,26 @@
namespace Unosquare.RaspberryIO.Abstractions
{
using System;
/// <summary>
/// Interface for system info.
/// </summary>
public interface ISystemInfo
{
/// <summary>
/// Gets the board revision (1 or 2).
/// </summary>
/// <value>
/// The board revision.
/// </value>
BoardRevision BoardRevision { get; }
/// <summary>
/// Gets the library version.
/// </summary>
/// <value>
/// The library version.
/// </value>
Version LibraryVersion { get; }
}
}
@@ -0,0 +1,30 @@
namespace Unosquare.RaspberryIO.Abstractions
{
using System;
/// <summary>
/// Interface to represent threading methods using interop.
/// </summary>
public interface IThreading
{
/// <summary>
/// Starts a new thread of execution which runs concurrently with your main program.
/// </summary>
/// <param name="worker">The thread routine.</param>
void StartThread(Action worker);
/// <summary>
/// Starts a new thread of execution which runs concurrently with your main program.
/// </summary>
/// <param name="worker">The thread routine.</param>
/// <param name="userData">A pointer to the user data.</param>
/// <returns>A pointer to the new thread.</returns>
UIntPtr StartThreadEx(Action<UIntPtr> worker, UIntPtr userData);
/// <summary>
/// Stops the thread pointed at by handle.
/// </summary>
/// <param name="handle">A thread pointer returned by <see cref="StartThreadEx(Action{UIntPtr}, UIntPtr)"/>.</param>
void StopThreadEx(UIntPtr handle);
}
}
@@ -0,0 +1,40 @@
namespace Unosquare.RaspberryIO.Abstractions
{
/// <summary>
/// Interface for timing methods using interop.
/// </summary>
public interface ITiming
{
/// <summary>
/// This returns a number representing the number of milliseconds since system boot.
/// </summary>
/// <returns>The milliseconds since system boot.</returns>
uint Milliseconds { get; }
/// <summary>
/// This returns a number representing the number of microseconds since system boot.
/// </summary>
/// <returns>The microseconds since system boot.</returns>
uint Microseconds { get; }
/// <summary>
/// This causes program execution to pause for at least how long milliseconds.
/// Due to the multi-tasking nature of Linux it could be longer.
/// Note that the maximum delay is an unsigned 32-bit integer or approximately 49 days.
/// </summary>
/// <param name="millis">The number of milliseconds to sleep.</param>
void SleepMilliseconds(uint millis);
/// <summary>
/// This causes program execution to pause for at least how long microseconds.
/// Due to the multi-tasking nature of Linux it could be longer.
/// Note that the maximum delay is an unsigned 32-bit integer microseconds or approximately 71 minutes.
/// Delays under 100 microseconds are timed using a hard-coded loop continually polling the system time,
/// Delays over 100 microseconds are done using the system nanosleep() function –
/// You may need to consider the implications of very short delays on the overall performance of the system,
/// especially if using threads.
/// </summary>
/// <param name="micros">The number of microseconds to sleep.</param>
void SleepMicroseconds(uint micros);
}
}
@@ -0,0 +1,71 @@
namespace Unosquare.RaspberryIO.Abstractions.Native
{
using System;
using System.Runtime.InteropServices;
/// <summary>
/// Represents a low-level exception, typically thrown when return codes from a
/// low-level operation is non-zero or in some cases when it is less than zero.
/// </summary>
/// <seealso cref="Exception" />
public class HardwareException : Exception
{
/// <summary>
/// Initializes a new instance of the <see cref="HardwareException"/> class.
/// </summary>
/// <param name="errorCode">The error code.</param>
/// <param name="component">The component.</param>
public HardwareException(int errorCode, string component)
: base($"A hardware exception occurred. Error Code: {errorCode}")
{
ExtendedMessage = null;
try
{
ExtendedMessage = Standard.Strerror(errorCode);
}
catch
{
// Ignore
}
ErrorCode = errorCode;
Component = component;
}
/// <summary>
/// Gets the error code.
/// </summary>
/// <value>
/// The error code.
/// </value>
public int ErrorCode { get; }
/// <summary>
/// Gets the component.
/// </summary>
/// <value>
/// The component.
/// </value>
public string Component { get; }
/// <summary>
/// Gets the extended message (could be null).
/// </summary>
/// <value>
/// The extended message.
/// </value>
public string? ExtendedMessage { get; }
/// <summary>
/// Throws a new instance of a hardware error by retrieving the last error number (errno).
/// </summary>
/// <param name="className">Name of the class.</param>
/// <param name="methodName">Name of the method.</param>
/// <exception cref="HardwareException">When an error thrown by an API call occurs.</exception>
public static void Throw(string className, string methodName) => throw new HardwareException(Marshal.GetLastWin32Error(), $"{className}.{methodName}");
/// <inheritdoc />
public override string ToString() => $"{nameof(HardwareException)}{(string.IsNullOrWhiteSpace(Component) ? string.Empty : $" on {Component}")}: ({ErrorCode}) - {Message}";
}
}
@@ -0,0 +1,45 @@
namespace Unosquare.RaspberryIO.Abstractions.Native
{
using System;
using System.Runtime.InteropServices;
using System.Text;
/// <summary>
/// Provides standard 'libc' calls using platform-invoke.
/// </summary>
public static class Standard
{
internal const string LibCLibrary = "libc";
#region LibC Calls
/// <summary>
/// Strerrors the specified error.
/// </summary>
/// <param name="error">The error.</param>
/// <returns>The error string.</returns>
public static string Strerror(int error)
{
if (Type.GetType("Mono.Runtime") == null) return Marshal.PtrToStringAnsi(StrError(error));
try
{
var buffer = new StringBuilder(256);
var result = Strerror(error, buffer, (ulong)buffer.Capacity);
return (result != -1) ? buffer.ToString() : null;
}
catch (Exception)
{
return null;
}
}
[DllImport(LibCLibrary, EntryPoint = "strerror", SetLastError = true)]
private static extern IntPtr StrError(int errnum);
[DllImport("MonoPosixHelper", EntryPoint = "Mono_Posix_Syscall_strerror_r", SetLastError = true)]
private static extern int Strerror(int error, [Out] StringBuilder buffer, ulong length);
#endregion
}
}
@@ -0,0 +1,21 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<Description>The Raspberry Pi's IO Functionality in an easy-to use API for Mono/.NET Core
This library enables developers to use the various Raspberry Pi's hardware modules including the Camera to capture images and video, the GPIO pins, and both, the SPI and I2C buses.</Description>
<Copyright>Unosquare (c) 2016-2019</Copyright>
<AssemblyTitle>Unosquare Raspberry Abstractions</AssemblyTitle>
<TargetFramework>netcoreapp3.0</TargetFramework>
<AssemblyName>Unosquare.Raspberry.Abstractions</AssemblyName>
<PackageId>Unosquare.Raspberry.Abstractions</PackageId>
<Version>0.4.0</Version>
<Authors>Unosquare</Authors>
<PackageIconUrl>https://github.com/unosquare/raspberryio/raw/master/logos/raspberryio-logo-32.png</PackageIconUrl>
<PackageProjectUrl>https://github.com/unosquare/raspberryio</PackageProjectUrl>
<PackageLicenseUrl>https://raw.githubusercontent.com/unosquare/raspberryio/master/LICENSE</PackageLicenseUrl>
<PackageTags>Raspberry Pi GPIO Camera SPI I2C Embedded IoT Mono C# .NET</PackageTags>
<LangVersion>8.0</LangVersion>
</PropertyGroup>
</Project>