RaspberryIO/Unosquare.RaspberryIO/Native/WiringPi.cs

392 lines
22 KiB
C#
Raw Normal View History

2019-12-03 18:43:54 +01:00
using System;
using System.Runtime.InteropServices;
namespace Unosquare.RaspberryIO.Native {
/// <summary>
/// Provides native C WiringPi Library function call wrappers
/// All credit for the native library goes to the author of http://wiringpi.com/
/// The wrappers were written based on https://github.com/WiringPi/WiringPi/blob/master/wiringPi/wiringPi.h
/// </summary>
public partial class WiringPi {
internal const String WiringPiLibrary = "libwiringPi.so.2.46";
#region WiringPi - Core Functions (https://github.com/WiringPi/WiringPi/blob/master/wiringPi/wiringPi.h)
/// <summary>
/// This initialises wiringPi and assumes that the calling program is going to be using the wiringPi pin numbering scheme.
/// This is a simplified numbering scheme which provides a mapping from virtual pin numbers 0 through 16 to the real underlying Broadcom GPIO pin numbers.
/// See the pins page for a table which maps the wiringPi pin number to the Broadcom GPIO pin number to the physical location on the edge connector.
/// This function needs to be called with root privileges.
/// </summary>
/// <returns>The result code</returns>
[DllImport(WiringPiLibrary, EntryPoint = "wiringPiSetup", SetLastError = true)]
public static extern Int32 WiringPiSetup();
/// <summary>
/// This initialises wiringPi but uses the /sys/class/gpio interface rather than accessing the hardware directly.
/// This can be called as a non-root user provided the GPIO pins have been exported before-hand using the gpio program.
/// Pin numbering in this mode is the native Broadcom GPIO numbers the same as wiringPiSetupGpio() above,
/// so be aware of the differences between Rev 1 and Rev 2 boards.
///
/// Note: In this mode you can only use the pins which have been exported via the /sys/class/gpio interface before you run your program.
/// You can do this in a separate shell-script, or by using the system() function from inside your program to call the gpio program.
/// Also note that some functions have no effect when using this mode as theyre not currently possible to action unless called with root privileges.
/// (although you can use system() to call gpio to set/change modes if needed)
/// </summary>
/// <returns>The result code</returns>
[DllImport(WiringPiLibrary, EntryPoint = "wiringPiSetupSys", SetLastError = true)]
public static extern Int32 WiringPiSetupSys();
/// <summary>
/// This is identical to wiringPiSetup, however it allows the calling programs to use the Broadcom GPIO
/// pin numbers directly with no re-mapping.
/// As above, this function needs to be called with root privileges, and note that some pins are different
/// from revision 1 to revision 2 boards.
/// </summary>
/// <returns>The result code</returns>
[DllImport(WiringPiLibrary, EntryPoint = "wiringPiSetupGpio", SetLastError = true)]
public static extern Int32 WiringPiSetupGpio();
/// <summary>
/// Identical to wiringPiSetup, however it allows the calling programs to use the physical pin numbers on the P1 connector only.
/// This function needs to be called with root privileges.
/// </summary>
/// <returns>The result code</returns>
[DllImport(WiringPiLibrary, EntryPoint = "wiringPiSetupPhys", SetLastError = true)]
public static extern Int32 WiringPiSetupPhys();
/// <summary>
/// This function is undocumented
/// </summary>
/// <param name="pin">The pin.</param>
/// <param name="mode">The mode.</param>
[DllImport(WiringPiLibrary, EntryPoint = "pinModeAlt", SetLastError = true)]
public static extern void PinModeAlt(Int32 pin, Int32 mode);
/// <summary>
/// This sets the mode of a pin to either INPUT, OUTPUT, PWM_OUTPUT or GPIO_CLOCK.
/// Note that only wiringPi pin 1 (BCM_GPIO 18) supports PWM output and only wiringPi pin 7 (BCM_GPIO 4)
/// supports CLOCK output modes.
///
/// This function has no effect when in Sys mode. If you need to change the pin mode, then you can
/// do it with the gpio program in a script before you start your program.
/// </summary>
/// <param name="pin">The pin.</param>
/// <param name="mode">The mode.</param>
[DllImport(WiringPiLibrary, EntryPoint = "pinMode", SetLastError = true)]
public static extern void PinMode(Int32 pin, Int32 mode);
/// <summary>
/// This sets the pull-up or pull-down resistor mode on the given 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.
///
/// This function has no effect on the Raspberry Pis GPIO pins when in Sys mode.
/// If you need to activate a pull-up/pull-down, then you can do it with the gpio program in a script before you start your program.
/// </summary>
/// <param name="pin">The pin.</param>
/// <param name="pud">The pud.</param>
[DllImport(WiringPiLibrary, EntryPoint = "pullUpDnControl", SetLastError = true)]
public static extern void PullUpDnControl(Int32 pin, Int32 pud);
/// <summary>
/// This function returns the value read at the given pin. It will be HIGH or LOW (1 or 0) depending on the logic level at the pin.
/// </summary>
/// <param name="pin">The pin.</param>
/// <returns>The result code</returns>
[DllImport(WiringPiLibrary, EntryPoint = "digitalRead", SetLastError = true)]
public static extern Int32 DigitalRead(Int32 pin);
/// <summary>
/// Writes the value HIGH or LOW (1 or 0) to the given pin which must have been previously set as an output.
/// WiringPi treats any non-zero number as HIGH, however 0 is the only representation of LOW.
/// </summary>
/// <param name="pin">The pin.</param>
/// <param name="value">The value.</param>
[DllImport(WiringPiLibrary, EntryPoint = "digitalWrite", SetLastError = true)]
public static extern void DigitalWrite(Int32 pin, Int32 value);
/// <summary>
/// Writes the value to the PWM register for the given pin. The Raspberry Pi has one
/// on-board PWM pin, pin 1 (BMC_GPIO 18, Phys 12) and the range is 0-1024.
/// Other PWM devices may have other PWM ranges.
/// This function is not able to control the Pis on-board PWM when in Sys mode.
/// </summary>
/// <param name="pin">The pin.</param>
/// <param name="value">The value.</param>
[DllImport(WiringPiLibrary, EntryPoint = "pwmWrite", SetLastError = true)]
public static extern void PwmWrite(Int32 pin, Int32 value);
/// <summary>
/// This returns the value read on the supplied analog input pin. You will need to
/// register additional analog modules to enable this function for devices such as the Gertboard, quick2Wire analog board, etc.
/// </summary>
/// <param name="pin">The pin.</param>
/// <returns>The result code</returns>
[DllImport(WiringPiLibrary, EntryPoint = "analogRead", SetLastError = true)]
public static extern Int32 AnalogRead(Int32 pin);
/// <summary>
/// This writes the given value to the supplied analog pin. You will need to register additional
/// analog modules to enable this function for devices such as the Gertboard.
/// </summary>
/// <param name="pin">The pin.</param>
/// <param name="value">The value.</param>
[DllImport(WiringPiLibrary, EntryPoint = "analogWrite", SetLastError = true)]
public static extern void AnalogWrite(Int32 pin, Int32 value);
/// <summary>
/// This returns the board revision of the Raspberry Pi. It will be either 1 or 2. Some of the BCM_GPIO pins changed number and
/// function when moving from board revision 1 to 2, so if you are using BCM_GPIO pin numbers, then you need to be aware of the differences.
/// </summary>
/// <returns>The result code</returns>
[DllImport(WiringPiLibrary, EntryPoint = "piBoardRev", SetLastError = true)]
public static extern Int32 PiBoardRev();
/// <summary>
/// This function is undocumented
/// </summary>
/// <param name="model">The model.</param>
/// <param name="mem">The memory.</param>
/// <param name="maker">The maker.</param>
/// <param name="overVolted">The over volted.</param>
/// <returns>The result code</returns>
[DllImport(WiringPiLibrary, EntryPoint = "piBoardId", SetLastError = true)]
public static extern Int32 PiBoardId(ref Int32 model, ref Int32 mem, ref Int32 maker, ref Int32 overVolted);
/// <summary>
/// This returns the BCM_GPIO pin number of the supplied wiringPi pin. It takes the board revision into account.
/// </summary>
/// <param name="wPiPin">The w pi pin.</param>
/// <returns>The result code</returns>
[DllImport(WiringPiLibrary, EntryPoint = "wpiPinToGpio", SetLastError = true)]
public static extern Int32 WpiPinToGpio(Int32 wPiPin);
/// <summary>
/// This returns the BCM_GPIO pin number of the supplied physical pin on the P1 connector.
/// </summary>
/// <param name="physPin">The physical pin.</param>
/// <returns>The result code</returns>
[DllImport(WiringPiLibrary, EntryPoint = "physPinToGpio", SetLastError = true)]
public static extern Int32 PhysPinToGpio(Int32 physPin);
/// <summary>
/// This sets the “strength” of the pad drivers for a particular group of pins.
/// There are 3 groups of pins and the drive strength is from 0 to 7. Do not use this unless you know what you are doing.
/// </summary>
/// <param name="group">The group.</param>
/// <param name="value">The value.</param>
/// <returns>The result code</returns>
[DllImport(WiringPiLibrary, EntryPoint = "setPadDrive", SetLastError = true)]
public static extern Int32 SetPadDrive(Int32 group, Int32 value);
/// <summary>
/// Undocumented function
/// </summary>
/// <param name="pin">The pin.</param>
/// <returns>The result code</returns>
[DllImport(WiringPiLibrary, EntryPoint = "getAlt", SetLastError = true)]
public static extern Int32 GetAlt(Int32 pin);
/// <summary>
/// Undocumented function
/// </summary>
/// <param name="pin">The pin.</param>
/// <param name="freq">The freq.</param>
/// <returns>The result code</returns>
[DllImport(WiringPiLibrary, EntryPoint = "pwmToneWrite", SetLastError = true)]
public static extern Int32 PwmToneWrite(Int32 pin, Int32 freq);
/// <summary>
/// This writes the 8-bit byte supplied to the first 8 GPIO pins.
/// Its the fastest way to set all 8 bits at once to a particular value, although it still takes two write operations to the Pis GPIO hardware.
/// </summary>
/// <param name="value">The value.</param>
[DllImport(WiringPiLibrary, EntryPoint = "digitalWriteByte", SetLastError = true)]
public static extern void DigitalWriteByte(Int32 value);
/// <summary>
/// This writes the 8-bit byte supplied to the first 8 GPIO pins.
/// Its the fastest way to set all 8 bits at once to a particular value, although it still takes two write operations to the Pis GPIO hardware.
/// </summary>
/// <param name="value">The value.</param>
[DllImport(WiringPiLibrary, EntryPoint = "digitalWriteByte2", SetLastError = true)]
public static extern void DigitalWriteByte2(Int32 value);
/// <summary>
/// Undocumented function
/// This reads the 8-bit byte supplied to the first 8 GPIO pins.
/// Its the fastest way to get all 8 bits at once to a particular value.
/// </summary>
/// <returns>The result code</returns>
[DllImport(WiringPiLibrary, EntryPoint = "digitalReadByte", SetLastError = true)]
public static extern UInt32 DigitalReadByte();
/// <summary>
/// Undocumented function
/// This reads the 8-bit byte supplied to the first 8 GPIO pins.
/// Its the fastest way to get all 8 bits at once to a particular value.
/// </summary>
/// <returns>The result code</returns>
[DllImport(WiringPiLibrary, EntryPoint = "digitalReadByte2", SetLastError = true)]
public static extern UInt32 DigitalReadByte2();
/// <summary>
/// The PWM generator can run in 2 modes “balanced” and “mark:space”. The mark:space mode is traditional,
/// however the default mode in the Pi is “balanced”. You can switch modes by supplying the parameter: PWM_MODE_BAL or PWM_MODE_MS.
/// </summary>
/// <param name="mode">The mode.</param>
[DllImport(WiringPiLibrary, EntryPoint = "pwmSetMode", SetLastError = true)]
public static extern void PwmSetMode(Int32 mode);
/// <summary>
/// This sets the range register in the PWM generator. The default is 1024.
/// </summary>
/// <param name="range">The range.</param>
[DllImport(WiringPiLibrary, EntryPoint = "pwmSetRange", SetLastError = true)]
public static extern void PwmSetRange(UInt32 range);
/// <summary>
/// This sets the divisor for the PWM clock.
/// Note: The PWM control functions can not be used when in Sys mode.
/// To understand more about the PWM system, youll need to read the Broadcom ARM peripherals manual.
/// </summary>
/// <param name="divisor">The divisor.</param>
[DllImport(WiringPiLibrary, EntryPoint = "pwmSetClock", SetLastError = true)]
public static extern void PwmSetClock(Int32 divisor);
/// <summary>
/// Undocumented function
/// </summary>
/// <param name="pin">The pin.</param>
/// <param name="freq">The freq.</param>
[DllImport(WiringPiLibrary, EntryPoint = "gpioClockSet", SetLastError = true)]
public static extern void GpioClockSet(Int32 pin, Int32 freq);
/// <summary>
/// Note: Jan 2013: The waitForInterrupt() function is deprecated you should use the newer and easier to use wiringPiISR() function below.
/// When called, it will wait for an interrupt event to happen on that pin and your program will be stalled. The timeOut parameter is given in milliseconds,
/// or can be -1 which means to wait forever.
/// The return value is -1 if an error occurred (and errno will be set appropriately), 0 if it timed out, or 1 on a successful interrupt event.
/// Before you call waitForInterrupt, you must first initialise the GPIO pin and at present the only way to do this is to use the gpio program, either
/// in a script, or using the system() call from inside your program.
/// e.g. We want to wait for a falling-edge interrupt on GPIO pin 0, so to setup the hardware, we need to run: gpio edge 0 falling
/// before running the program.
/// </summary>
/// <param name="pin">The pin.</param>
/// <param name="timeout">The timeout.</param>
/// <returns>The result code</returns>
[Obsolete]
[DllImport(WiringPiLibrary, EntryPoint = "waitForInterrupt", SetLastError = true)]
public static extern Int32 WaitForInterrupt(Int32 pin, Int32 timeout);
/// <summary>
/// This function registers a function to received interrupts on the specified pin.
/// The edgeType parameter is either INT_EDGE_FALLING, INT_EDGE_RISING, INT_EDGE_BOTH or INT_EDGE_SETUP.
/// If it is INT_EDGE_SETUP then no initialisation of the pin will happen its assumed that you have already setup the pin elsewhere
/// (e.g. with the gpio program), but if you specify one of the other types, then the pin will be exported and initialised as specified.
/// This is accomplished via a suitable call to the gpio utility program, so it need to be available.
/// The pin number is supplied in the current mode native wiringPi, BCM_GPIO, physical or Sys modes.
/// This function will work in any mode, and does not need root privileges to work.
/// The function will be called when the interrupt triggers. When it is triggered, its cleared in the dispatcher before calling your function,
/// so if a subsequent interrupt fires before you finish your handler, then it wont be missed. (However it can only track one more interrupt,
/// if more than one interrupt fires while one is being handled then they will be ignored)
/// This function is run at a high priority (if the program is run using sudo, or as root) and executes concurrently with the main program.
/// It has full access to all the global variables, open file handles and so on.
/// </summary>
/// <param name="pin">The pin.</param>
/// <param name="mode">The mode.</param>
/// <param name="method">The method.</param>
/// <returns>The result code</returns>
[DllImport(WiringPiLibrary, EntryPoint = "wiringPiISR", SetLastError = true)]
public static extern Int32 WiringPiISR(Int32 pin, Int32 mode, InterruptServiceRoutineCallback method);
/// <summary>
/// This function creates a thread which is another function in your program previously declared using the PI_THREAD declaration.
/// This function is then run concurrently with your main program. An example may be to have this function wait for an interrupt while
/// your program carries on doing other tasks. The thread can indicate an event, or action by using global variables to
/// communicate back to the main program, or other threads.
/// </summary>
/// <param name="method">The method.</param>
/// <returns>The result code</returns>
[DllImport(WiringPiLibrary, EntryPoint = "piThreadCreate", SetLastError = true)]
public static extern Int32 PiThreadCreate(ThreadWorker method);
/// <summary>
/// These allow you to synchronise variable updates from your main program to any threads running in your program. keyNum is a number from 0 to 3 and represents a key.
/// When another process tries to lock the same key, it will be stalled until the first process has unlocked the same key.
/// You may need to use these functions to ensure that you get valid data when exchanging data between your main program and a thread
/// otherwise its possible that the thread could wake-up halfway during your data copy and change the data
/// so the data you end up copying is incomplete, or invalid. See the wfi.c program in the examples directory for an example.
/// </summary>
/// <param name="key">The key.</param>
[DllImport(WiringPiLibrary, EntryPoint = "piLock", SetLastError = true)]
public static extern void PiLock(Int32 key);
/// <summary>
/// These allow you to synchronise variable updates from your main program to any threads running in your program. keyNum is a number from 0 to 3 and represents a key.
/// When another process tries to lock the same key, it will be stalled until the first process has unlocked the same key.
/// You may need to use these functions to ensure that you get valid data when exchanging data between your main program and a thread
/// otherwise its possible that the thread could wake-up halfway during your data copy and change the data
/// so the data you end up copying is incomplete, or invalid. See the wfi.c program in the examples directory for an example.
/// </summary>
/// <param name="key">The key.</param>
[DllImport(WiringPiLibrary, EntryPoint = "piUnlock", SetLastError = true)]
public static extern void PiUnlock(Int32 key);
/// <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 wont 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)
/// The return value is 0 for success and -1 for error. If an error is returned, the program should then consult the errno global variable, as per the usual conventions.
/// Note: Only programs running as root can change their priority. If called from a non-root program then nothing happens.
/// </summary>
/// <param name="priority">The priority.</param>
/// <returns>The result code</returns>
[DllImport(WiringPiLibrary, EntryPoint = "piHiPri", SetLastError = true)]
public static extern Int32 PiHiPri(Int32 priority);
/// <summary>
/// This causes program execution to pause for at least howLong 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="howLong">The how long.</param>
[DllImport(WiringPiLibrary, EntryPoint = "delay", SetLastError = true)]
public static extern void Delay(UInt32 howLong);
/// <summary>
/// This causes program execution to pause for at least howLong 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="howLong">The how long.</param>
[DllImport(WiringPiLibrary, EntryPoint = "delayMicroseconds", SetLastError = true)]
public static extern void DelayMicroseconds(UInt32 howLong);
/// <summary>
/// This returns a number representing the number of milliseconds since your program called one of the wiringPiSetup functions.
/// It returns an unsigned 32-bit number which wraps after 49 days.
/// </summary>
/// <returns>The result code</returns>
[DllImport(WiringPiLibrary, EntryPoint = "millis", SetLastError = true)]
public static extern UInt32 Millis();
/// <summary>
/// This returns a number representing the number of microseconds since your program called one of
/// the wiringPiSetup functions. It returns an unsigned 32-bit number which wraps after approximately 71 minutes.
/// </summary>
/// <returns>The result code</returns>
[DllImport(WiringPiLibrary, EntryPoint = "micros", SetLastError = true)]
public static extern UInt32 Micros();
#endregion
}
2019-02-17 14:08:57 +01:00
}