RaspberryIO/Unosquare.RaspberryIO/Native/WiringPi.cs
2019-12-03 18:43:54 +01:00

392 lines
22 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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
}
}