lgpio(3)

๐Ÿ“ฆ
version 0.2.0.0 ยท 3 versions
, in ubuntu noble, ubuntu questing, ubuntu resolute, ubuntu stonking

๐Ÿ’– lgpio โ€” the C library that talks to your SBC's GPIO ๐Ÿ’–

okay bestie, welcome to lgpio(3), straight outta the lg archive โœจ this is the whole vibe: a C library that lets you control the General Purpose Input Output pins on a Linux Single Board Computer. she's long, she's iconic, and she's about to be your whole personality. let's go ๐Ÿ’…


๐ŸŒธ NAME ๐ŸŒธ

lgpio โ€” a C library to manipulate a local SBC's GPIO. yes. that's the whole job. and she ate. ๐Ÿซถ


โœจ SYNOPSIS โœจ

#include <lgpio.h>

gcc -Wall -o prog prog.c -llgpio

./prog

like, that's it. that's the ritual. ๐ŸŽ€


๐Ÿฆ‹ DESCRIPTION ๐Ÿฆ‹

lgpio is a C library for Linux Single Board Computers which allows control of the General Purpose Input Output pins. that's the mission statement, and she is so committed to it. ๐ŸŒˆ

๐Ÿ‘‘ Features

  • reading and writing GPIO singly and in groups
  • software timed PWM and waves
  • GPIO callbacks
  • pipe notification of GPIO alerts
  • I2C wrapper
  • SPI wrapper
  • serial link wrapper
  • a simple interface to start and stop new threads

look at that list. every single one. no skips, no cuts, we love a full feature set fr fr ๐Ÿ’–

๐Ÿงš Usage

Include <lgpio.h> in your source files.

Assuming your source is in a single file called prog.c use the following command to build and run the executable.

gcc -Wall -o prog prog.c -llgpio

For examples of usage see the C programs within the lg archive file. ๐Ÿ“

๐Ÿ’€ Notes

All the functions which return an int return < 0 on error.

ok so this is THE rule to internalise: if an int comes back negative, something went wrong. that's your vibe check, always. ๐Ÿ˜ญ

๐ŸŒˆ OVERVIEW ๐ŸŒˆ

โญ GPIO

  • lgGpiochipOpen โ€” Opens a gpiochip device
  • lgGpiochipClose โ€” Closes a gpiochip device
  • lgGpioGetChipInfo โ€” Gets gpiochip information
  • lgGpioGetLineInfo โ€” Gets gpiochip line information
  • lgGpioGetMode โ€” Gets the mode of a GPIO
  • lgGpioSetUser โ€” Notifies Linux of the GPIO user
  • lgGpioClaimInput โ€” Claims a GPIO for input
  • lgGpioClaimOutput โ€” Claims a GPIO for output
  • lgGpioClaimAlert โ€” Claims a GPIO for alerts
  • lgGpioFree โ€” Frees a GPIO
  • lgGroupClaimInput โ€” Claims a group of GPIO for inputs
  • lgGroupClaimOutput โ€” Claims a group of GPIO for outputs
  • lgGroupFree โ€” Frees a group of GPIO
  • lgGpioRead โ€” Reads a GPIO
  • lgGpioWrite โ€” Writes a GPIO
  • lgGroupRead โ€” Reads a group of GPIO
  • lgGroupWrite โ€” Writes a group of GPIO
  • lgTxPulse โ€” Starts pulses on a GPIO
  • lgTxPwm โ€” Starts PWM pulses on a GPIO
  • lgTxServo โ€” Starts Servo pulses on a GPIO
  • lgTxWave โ€” Starts a wave on a group of GPIO
  • lgTxBusy โ€” See if tx is active on a GPIO or group
  • lgTxRoom โ€” See if more room for tx on a GPIO or group
  • lgGpioSetDebounce โ€” Sets the debounce time for a GPIO
  • lgGpioSetWatchdog โ€” Sets the watchdog time for a GPIO
  • lgGpioSetAlertsFunc โ€” Starts a GPIO callback
  • lgGpioSetSamplesFunc โ€” Starts a GPIO callback for all GPIO

๐Ÿ”ฅ I2C

  • lgI2cOpen โ€” Opens an I2C device
  • lgI2cClose โ€” Closes an I2C device
  • lgI2cWriteQuick โ€” SMBus write quick
  • lgI2cReadByte โ€” SMBus read byte
  • lgI2cWriteByte โ€” SMBus write byte
  • lgI2cReadByteData โ€” SMBus read byte data
  • lgI2cWriteByteData โ€” SMBus write byte data
  • lgI2cReadWordData โ€” SMBus read word data
  • lgI2cWriteWordData โ€” SMBus write word data
  • lgI2cReadBlockData โ€” SMBus read block data
  • lgI2cWriteBlockData โ€” SMBus write block data
  • lgI2cReadI2CBlockData โ€” SMBus read I2C block data
  • lgI2cWriteI2CBlockData โ€” SMBus write I2C block data
  • lgI2cReadDevice โ€” Reads the raw I2C device
  • lgI2cWriteDevice โ€” Writes the raw I2C device
  • lgI2cProcessCall โ€” SMBus process call
  • lgI2cBlockProcessCall โ€” SMBus block process call
  • lgI2cSegments โ€” Performs multiple I2C transactions
  • lgI2cZip โ€” Performs multiple I2C transactions

๐Ÿ’Œ NOTIFICATIONS

  • lgNotifyOpen โ€” Request a notification
  • lgNotifyClose โ€” Close a notification
  • lgNotifyPause โ€” Pause notifications
  • lgNotifyResume โ€” Start notifications

๐ŸŽ€ SERIAL

  • lgSerialOpen โ€” Opens a serial device
  • lgSerialClose โ€” Closes a serial device
  • lgSerialReadByte โ€” Reads a byte from a serial device
  • lgSerialWriteByte โ€” Writes a byte to a serial device
  • lgSerialRead โ€” Reads bytes from a serial device
  • lgSerialWrite โ€” Writes bytes to a serial device
  • lgSerialDataAvailable โ€” Returns number of bytes ready to be read

๐Ÿซถ SPI

  • lgSpiOpen โ€” Opens a SPI device
  • lgSpiClose โ€” Closes a SPI device
  • lgSpiRead โ€” Reads bytes from a SPI device
  • lgSpiWrite โ€” Writes bytes to a SPI device
  • lgSpiXfer โ€” Transfers bytes with a SPI device

๐Ÿ’œ THREADS

  • lgThreadStart โ€” Start a new thread
  • lgThreadStop โ€” Stop a previously started thread

๐ŸŒธ UTILITIES

  • lguVersion โ€” Gets the library version
  • lguSbcName โ€” Gets the host name of the SBC
  • lguGetInternal โ€” Get an internal configuration value
  • lguSetInternal โ€” Set an internal configuration value
  • lguSleep โ€” Sleeps for a given time
  • lguTimestamp โ€” Gets the current timestamp
  • lguTime โ€” Gets the current time
  • lguErrorText โ€” Gets a text description of an error code
  • lguSetWorkDir โ€” Set the working directory
  • lguGetWorkDir โ€” Get the working directory

๐Ÿ‘‘ FUNCTIONS ๐Ÿ‘‘

int lgGpiochipOpen(int gpioDev)

This returns a handle to a gpiochip device. ๐ŸŽ‰

  • gpioDev: >= 0

If OK returns a handle (>= 0).

On failure returns a negative error code.

Example

h = lgGpiochipOpen(0); // open /dev/gpiochip0

if (h >= 0)
{
   // open ok
}
else
{
   // open error
}

int lgGpiochipClose(int handle)

This closes an opened gpiochip device. bye bestie ๐Ÿ‘‹

  • handle: >= 0 (as returned by lgGpiochipOpen)

If OK returns 0.

On failure returns a negative error code.

Example

status = lgGpiochipClose(h); // close gpiochip

if (status < 0)
{
   // close failed
}

int lgGpioGetChipInfo(int handle, lgChipInfo_p chipInfo)

This returns information about a gpiochip. ๐Ÿ•ต๏ธ

  • handle: >= 0 (as returned by lgGpiochipOpen)
  • chipInfo: A pointer to space for a lgChipInfo_t object

If OK returns 0 and updates chipInfo.

On failure returns a negative error code.

This command gets the number of GPIO on the gpiochip, its name, and its usage.

Example

lgChipInfo_t cInfo;

status = lgGpioGetChipInfo(h, &cInfo);

if (status == LG_OKAY)
{
   printf("lines=%d name=%s label=%s0,
      cInfo.lines, cInfo.name, cInfo.label))
}

int lgGpioGetLineInfo(int handle, int gpio, lgLineInfo_p lineInfo)

Returns information about a GPIO. ๐Ÿ’…

  • handle: >= 0 (as returned by lgGpiochipOpen)
  • gpio: >= 0, as legal for the gpiochip
  • lineInfo: A pointer to space for a lgLineInfo_t object

If OK returns 0 and updates lineInfo.

On failure returns a negative error code.

This command gets information for a GPIO of a gpiochip. In particular it gets the GPIO number, flags, its user, and its purpose.

The meaning of the flags bits are as given for the mode by lgGpioGetMode.

The user and purpose fields are filled in by the software which has claimed the GPIO and may be blank.

Example

lgLineInfo_t lInfo;

status = lgGpioGetLineInfo(h, gpio, &lInfo);

if (status == LG_OKAY)
{
   printf("lFlags=%d name=%s user=%s0,
      lInfo.lFlags, lInfo.name, lInfo.user))
}

int lgGpioGetMode(int handle, int gpio)

Returns the GPIO mode. ๐Ÿ”

  • handle: >= 0 (as returned by lgGpiochipOpen)
  • gpio: >= 0, as legal for the gpiochip

If OK returns the GPIO mode.

On failure returns a negative error code.

  • bit 0, value 1 โ€” Kernel: In use by the kernel
  • bit 1, value 2 โ€” Kernel: Output
  • bit 2, value 4 โ€” Kernel: Active low
  • bit 3, value 8 โ€” Kernel: Open drain
  • bit 4, value 16 โ€” Kernel: Open source
  • bit 5, value 32 โ€” Kernel: Pull up set
  • bit 6, value 64 โ€” Kernel: Pull down set
  • bit 7, value 128 โ€” Kernel: Pulls off set
  • bit 8, value 256 โ€” LG: Input
  • bit 9, value 512 โ€” LG: Output
  • bit 10, value 1024 โ€” LG: Alert
  • bit 11, value 2048 โ€” LG: Group
  • bit 12, value 4096 โ€” LG: ---
  • bit 13, value 8192 โ€” LG: ---
  • bit 14, value 16384 โ€” LG: ---
  • bit 15, value 32768 โ€” LG: ---
  • bit 16, value 65536 โ€” Kernel: Input
  • bit 17, value 1<<17 โ€” Kernel: Rising edge alert
  • bit 18, value 1<<18 โ€” Kernel: Falling edge alert
  • bit 19, value 1<<19 โ€” Kernel: Realtime clock alert
heads up bestie: the LG bits are only set if the query was made by the process that owns the GPIO. ๐Ÿ”ฅ

int lgGpioSetUser(int handle, const char *gpiouser)

This sets the user string to be associated with each claimed GPIO. like a little name tag ๐Ÿท๏ธ

  • handle: >= 0 (as returned by lgGpiochipOpen)
  • gpiouser: a string up to 32 characters long

If OK returns 0.

On failure returns a negative error code.

Example

status = lgGpioSetUser(h, "my_title");

int lgGpioClaimInput(int handle, int lFlags, int gpio)

This claims a GPIO for input. she's listening ๐Ÿ‘‚

  • handle: >= 0 (as returned by lgGpiochipOpen)
  • lFlags: line flags for the GPIO
  • gpio: the GPIO to be claimed

If OK returns 0.

On failure returns a negative error code.

The line flags may be used to set the GPIO as active low, open drain, or open source.

Example

// open GPIO 23 for input
status = lgGpioClaimInput(h, 0, 23);

int lgGpioClaimOutput(int handle, int lFlags, int gpio, int level)

This claims a GPIO for output. now she's talking ๐Ÿ—ฃ๏ธ

  • handle: >= 0 (as returned by lgGpiochipOpen)
  • lFlags: line flags for the GPIO
  • gpio: the GPIO to be claimed
  • level: the initial level to set for the GPIO

If OK returns 0.

On failure returns a negative error code.

The line flags may be used to set the GPIO as active low, open drain, or open source.

If level is zero the GPIO will be initialised low. If any other value is used the GPIO will be initialised high. โœจ

Example

// open GPIO 31 for high output
status = lgGpioClaimOutput(h, 0, 31, 1);

int lgGpioClaimAlert(int handle, int lFlags, int eFlags, int gpio, int nfyHandle)

This claims a GPIO for alerts on level changes. ๐Ÿšจ she's noticing things

  • handle: >= 0 (as returned by lgGpiochipOpen)
  • lFlags: line flags for the GPIO
  • eFlags: event flags for the GPIO
  • gpio: >= 0, as legal for the gpiochip
  • nfyHandle: >= 0 (as returned by lgNotifyOpen)

If OK returns 0.

On failure returns a negative error code.


and that's part 1 bestie โ€” more coming, don't go anywhere ๐Ÿ’–

The line flags may be used to set the GPIO as active low, open drain, or open source. โœจ

The event flags are used to specify alerts for a rising edge, falling edge, or both edges.

The alerts will be sent to a previously opened notification. If you don't want them sent to a notification set nfyHandle to -1.

The alerts will also be sent to any callback registered for the GPIO by lgGpioSetAlertsFunc.

All GPIO alerts are also sent to a callback registered by lgGpioSetSamplesFunc.

Example

status = lgGpioClaimAlert(h, 0, LG_BOTH_EDGES, 16, -1);

int lgGpioFree(int handle, int gpio)

This frees a GPIO. bye bestie ๐Ÿ‘‹๐Ÿ’–

  • handle: >= 0 (as returned by lgGpiochipOpen)
  • gpio: the GPIO to be freed

If OK returns 0.

On failure returns a negative error code.

The GPIO may now be claimed by another user or for a different purpose. it's free real estate now ๐Ÿฆ‹

Example

status = lgGpioFree(h, 16);

int lgGroupClaimInput(int handle, int lFlags, int count, const int *gpios)

This claims a group of GPIO for inputs. group project but make it GPIO ๐ŸŽ€

  • handle: >= 0 (as returned by lgGpiochipOpen)
  • lFlags: line flags for the GPIO group
  • count: the number of GPIO to claim
  • gpios: the group GPIO

If OK returns 0.

On failure returns a negative error code.

The line flags may be used to set the group as active low, open drain, or open source.

gpios is an array of one or more GPIO. The first GPIO is called the group leader and is used to reference the group as a whole. ๐Ÿ‘‘

Example

int buttons[4] = {9, 7, 2, 6};

status = lgGroupClaimInput(h, 0, 4, buttons);

if (status == LG_OKAY)
{
   // OK
}
else
{
   // Error
}

int lgGroupClaimOutput(int handle, int lFlags, int count, const int *gpios, const int *levels)

This claims a group of GPIO for outputs. ๐Ÿ’…

  • handle: >= 0 (as returned by lgGpiochipOpen)
  • lFlags: line flags for the GPIO group
  • count: the number of GPIO to claim
  • gpios: the group GPIO
  • levels: the initial level for each GPIO

If OK returns 0.

On failure returns a negative error code.

The line flags may be used to set the group as active low, open drain, or open source.

gpios is an array of one or more GPIO. The first GPIO is called the group leader and is used to reference the group as a whole.

levels is an array of initialisation values for the GPIO. If a value is zero the corresponding GPIO will be initialised low. If any other value is used the corresponding GPIO will be initialised high. no cap, zero = low, anything else = high ๐ŸŒˆ

Example

int leds[7] =   {15, 16, 17, 8, 12, 13, 14};
int levels[7] = { 1,  0,  1, 1,  1,  0,  0};

status = lgGroupClaimInput(h, 0, 7, leds, levels);

if (status == LG_OKAY)
{
   // OK
}
else
{
   // Error
}

int lgGroupFree(int handle, int gpio)

This frees all the GPIO associated with a group. the whole squad, gone ๐Ÿซถ

  • handle: >= 0 (as returned by lgGpiochipOpen)
  • gpio: the group to be freed

If OK returns 0.

On failure returns a negative error code.

The GPIO may now be claimed by another user or for a different purpose.

Example

status = lgGroupFree(9); // free buttons

int lgGpioRead(int handle, int gpio)

This returns the level of a GPIO. ๐Ÿ‘€

  • handle: >= 0 (as returned by lgGpiochipOpen)
  • gpio: the GPIO to be read

If OK returns 0 (low) or 1 (high).

On failure returns a negative error code.

This command will work for any claimed GPIO (even if a member of a group). For an output GPIO the value returned will be that last written to the GPIO.

Example

level = lgGpioRead(h, 15); // get level of GPIO 15

int lgGpioWrite(int handle, int gpio, int level)

This sets the level of an output GPIO. โœจ

  • handle: >= 0 (as returned by lgGpiochipOpen)
  • gpio: the GPIO to be written
  • level: the level to set

If OK returns 0.

On failure returns a negative error code.

This command will work for any GPIO claimed as an output (even if a member of a group).

If level is zero the GPIO will be set low (0). If any other value is used the GPIO will be set high (1).

Example

status = lgGpioWrite(h, 23, 1); // set GPIO 23 high

int lgGroupRead(int handle, int gpio, uint64_t *groupBits)

This returns the levels read from a group. ๐Ÿงš

  • handle: >= 0 (as returned by lgGpiochipOpen)
  • gpio: the group to be read
  • groupBits: a pointer to a 64-bit memory area for the returned levels

If OK returns the group size and updates groupBits.

On failure returns a negative error code.

This command will work for an output group as well as an input group. For an output group the value returned will be that last written to the group GPIO.

Note that this command will also work on an individual GPIO claimed as an input or output as that is treated as a group with one member.

After a successful read groupBits is set as follows.

  • Bit 0 is the level of the group leader.
  • Bit 1 is the level of the second GPIO in the group.
  • Bit x is the level of GPIO x+1 of the group.

Example

// assuming a read group of 4 buttons: 9, 7, 2, 6.
uint64_t bits;

size = lgGroupRead(h, 9, &bits); // 9 is buttons group leader

if (size >= 0) // size of group is returned so size will be 4
{
   level_9 = (bits >> 0) & 1;
   level_7 = (bits >> 1) & 1;
   level_2 = (bits >> 2) & 1;
   level_6 = (bits >> 3) & 1;
}
else
{
   // error
}

int lgGroupWrite(int handle, int gpio, uint64_t groupBits, uint64_t groupMask)

This sets the levels of an output group. ๐Ÿ’…

  • handle: >= 0 (as returned by lgGpiochipOpen)
  • gpio: the group to be written
  • groupBits: the level to set if the corresponding bit in groupMask is set
  • groupMask: a mask indicating the group GPIO to be updated

If OK returns 0.

On failure returns a negative error code.

The values of each GPIO of the group are set according to the bits of groupBits.

  • Bit 0 sets the level of the group leader.
  • Bit 1 sets the level of the second GPIO in the group.
  • Bit x sets the level of GPIO x+1 in the group.

However this may be modified by the groupMask. A GPIO is only updated if the corresponding bit in the mask is 1. so like, mask bit off = hands off, don't touch ๐Ÿ™ˆ

Example

// assuming an output group of 7 LEDs: 15, 16, 17, 8, 12, 13, 14.

// switch on all LEDs
status = lgGroupWrite(h, 15, 0x7f, 0x7f);

// switch off all LEDs
status = lgGroupWrite(h, 15, 0x00, 0x7f);

// switch on first 4 LEDs, leave others unaltered
status = lgGroupWrite(h, 15, 0x0f, 0x0f);

// switch on LED attached to GPIO 13, leave others unaltered
status = lgGroupWrite(h, 15, 32, 32);

int lgTxPulse(int handle, int gpio, int pulseOn, int pulseOff, int pulseOffset, int pulseCycles)

This starts software timed pulses on an output GPIO. blink blink blink ๐Ÿ”ฅ

  • handle: >= 0 (as returned by lgGpiochipOpen)
  • gpio: the GPIO to be written
  • pulseOn: pulse high time in microseconds
  • pulseOff: pulse low time in microseconds
  • pulseOffset: offset from nominal pulse start position
  • pulseCycles: the number of pulses to be sent, 0 for infinite

If OK returns the number of entries left in the PWM queue for the GPIO.

On failure returns a negative error code.

If both pulseOn and pulseOff are zero pulses will be switched off for that GPIO. The active pulse, if any, will be stopped and any queued pulses will be deleted. ๐Ÿ›‘

Each successful call to this function consumes one PWM queue entry.

pulseCycles cycles are transmitted (0 means infinite). Each cycle consists of pulseOn microseconds of GPIO high followed by pulseOff microseconds of GPIO low.

PWM is characterised by two values, its frequency (number of cycles per second) and its duty cycle (percentage of high time per cycle).

The set frequency will be 1000000 / (pulseOn + pulseOff) Hz.

The set duty cycle will be pulseOn / (pulseOn + pulseOff) * 100 %.

E.g. if pulseOn is 50 and pulseOff is 100 the frequency will be 6666.67 Hz and the duty cycle will be 33.33 %.

pulseOffset is a microsecond offset from the natural start of the PWM cycle.

For instance if the PWM frequency is 10 Hz the natural start of each cycle is at seconds 0, then 0.1, 0.2, 0.3 etc. In this case if the offset is 20000 microseconds the cycle will start at seconds 0.02, 0.12, 0.22, 0.32 etc.

Another pulse command may be issued to the GPIO before the last has finished.

If the last pulse had infinite cycles then it will be replaced by the new settings at the end of the current cycle. Otherwise it will be replaced by the new settings when all its cycles are compete. ๐Ÿ’€ (yes, "compete" โ€” that's what the page says, we don't make the rules)

Multiple pulse settings may be queued in this way. it's giving queue energy ๐Ÿ‘‘

Example

slots_left = lgTxPulse(h,  8, 100000, 100000, 0, 0); // flash LED at 5 Hz

slots_left = lgTxPulse(h, 30, 1500, 18500, 0, 0); // move servo to centre

slots_left = lgTxPulse(h, 30, 2000, 18000, 0, 0); // move servo clockwise

int lgTxPwm(int handle, int gpio, float pwmFrequency, float pwmDutyCycle, int pwmOffset, int pwmCycles)

This starts software timed PWM on an output GPIO. ๐ŸŒธ

  • handle: >= 0 (as returned by lgGpiochipOpen)
  • gpio: the GPIO to be pulsed
  • pwmFrequency: PWM frequency in Hz (0=off, 0.1-10000)
  • pwmDutyCycle: PWM duty cycle in % (0-100)
  • pwmOffset: offset from nominal pulse start position
  • pwmCycles: the number of pulses to be sent, 0 for infinite

If OK returns the number of entries left in the PWM queue for the GPIO.

On failure returns a negative error code.

Each successful call to this function consumes one PWM queue entry.

PWM is characterised by two values, its frequency (number of cycles per second) and its duty cycle (percentage of high time per cycle).

Another PWM command may be issued to the GPIO before the last has finished.

If the last pulse had infinite cycles then it will be replaced by the new settings at the end of the current cycle. Otherwise it will be replaced by the new settings when all its cycles are complete.

Multiple PWM settings may be queued in this way. ๐ŸŽ€

int lgTxServo(int handle, int gpio, int pulseWidth, int servoFrequency, int servoOffset, int servoCycles)

okay bestie, this one kicks off software timed servo pulses on an output GPIO. โœจ

๐Ÿšจ real talk: only use software timed servo pulses for testing purposes. The timing jitter is gonna make your servo fidget, and that can make it overheat and wear out prematurely. It's giving sad servo energy, we don't want that.
  • handle โ€” >= 0 (as returned by lgGpiochipOpen)
  • gpio โ€” the GPIO to be pulsed
  • pulseWidth โ€” pulse high time in microseconds (0=off, 500-2500)
  • servoFrequency โ€” the number of pulses per second (40-500).
  • servoOffset โ€” offset from nominal pulse start position
  • servoCycles โ€” the number of pulses to be sent, 0 for infinite

If it's giving success, it returns the number of entries left in the PWM queue for the GPIO.

On failure it returns a negative error code.

Every single successful call to this function consumes one PWM queue entry. One in, one out, no cap.

Another servo command may be issued to the GPIO before the last one has finished. Iconic behaviour honestly.

If the last pulse had infinite cycles, it gets replaced by the new settings at the end of the current cycle. Otherwise it gets replaced by the new settings when all its cycles are complete.

Multiple servo settings may be queued up this way. It's a whole line of vibes waiting their turn. ๐Ÿ’…


int lgTxWave(int handle, int gpio, int count, lgPulse_p pulses)

This starts a wave on an output group of GPIO. ๐ŸŒŠ

  • handle โ€” >= 0 (as returned by lgGpiochipOpen)
  • gpio โ€” the group leader
  • count โ€” the number of pulses in the wave
  • pulses โ€” the pulses

If it goes well, it returns the number of entries left in the wave queue for the group.

On failure it returns a negative error code.

Every successful call to this function consumes one queue entry.

This command starts a wave of pulses, periodt.

pulses is an array of pulses to be transmitted on the group.

Each pulse is defined by this lil triplet:

  • bits โ€” the levels to set for the selected GPIO
  • mask โ€” the GPIO to select
  • delay โ€” the delay in microseconds before the next pulse

Another wave command may be issued to the group before the last one has finished transmission. The new wave will start when the previous wave has completed. So you can stack them. Multiple waves may be queued in this way. ๐Ÿซถ

Example โœจ

#include <stdio.h>

#include <lgpio.h>

#define PULSES 2000

int main(int argc, char *argv[])
{
   int GPIO[] =   {16, 17, 18, 19, 20, 21};
   int levels[] = { 1,  1,  1,  1,  1,  1};
   int h;
   int e;
   int mask;
   int delay;
   int p;
   lgPulse_t pulses[PULSES];

   h = lgGpiochipOpen(0); // open /dev/gpiochip0

   if (h < 0) { printf("ERROR: %s (%d)0, lguErrorText(h), h); return 1; }

   e =  lgGroupClaimOutput(h, 0, 6, GPIO, levels);

   if (e < 0) { printf("ERROR: %s (%d)0, lguErrorText(e), e); return 1; }

   mask = 0;
   p = 0;

   for (p=0; p<PULSES; p++)
   {
      pulses[p].bits = (p+1)>>2;  // see what sort of pattern we get
      pulses[p].mask = mask;      // with bits and mask changing
      pulses[p].delay = (PULSES + 500) - p;

      if (++mask > 0x3f) mask = 0;
   }

   lgTxWave(h, GPIO[0], p, pulses);

   while (lgTxBusy(h, GPIO[0], LG_TX_WAVE)) lguSleep(0.1);

   lgGpiochipClose(h);
}

int lgTxBusy(int handle, int gpio, int kind)

Returns true if transmissions of the specified kind are active on the GPIO or group. Basically the "are we still going bestie" check. ๐Ÿ’ซ

  • handle โ€” >= 0 (as returned by lgGpiochipOpen)
  • gpio โ€” the gpio or group to be checked
  • kind โ€” LG_TX_PWM or LG_TX_WAVE

If OK it returns 1 for busy and 0 for not busy.

On failure it returns a negative error code.

Example

while (lgTxBusy(h, 15, LG_TX_PWM)) // wait for PWM to finish on GPIO 15
   lguSleep(0.1);

int lgTxRoom(int handle, int gpio, int kind)

This one tells you how many entries are available for queueing transmissions of the specified kind on the GPIO or group. Like checking how much room's left in the group chat. ๐ŸŽ€

  • handle โ€” >= 0 (as returned by lgGpiochipOpen)
  • gpio โ€” the gpio or group to be checked
  • kind โ€” LG_TX_PWM or LG_TX_WAVE

If OK it returns the number of free entries (0 if none).

On failure it returns a negative error code.

Example

while (lgTxRoom(h, 17, LG_TX_WAVE) > 0))
{
   // queue another wave
}

int lgGpioSetDebounce(int handle, int gpio, int debounce_us)

Sets the debounce time for a GPIO.

  • handle โ€” >= 0 (as returned by lgGpiochipOpen)
  • gpio โ€” the GPIO to be configured
  • debounce_us โ€” the debounce time in microseconds

If OK it returns 0.

On failure it returns a negative error code.

This only affects alerts, bestie. An alert will only be issued if the edge has been stable for at least debounce microseconds.

Generally this is used to debounce mechanical switches (e.g. contact bounce). We love a stable queen. โœจ

Suppose a square wave at 5 Hz is being generated on a GPIO. Each edge will last 100000 microseconds. If a debounce time of 100001 is set, no alerts will be generated. If a debounce time of 99999 is set, 10 alerts will be generated per second.

Note that level changes will be timestamped debounce microseconds after the actual level change.

Example

lgSetDebounceTime(h, 16, 1000); // set a millisecond of debounce

int lgGpioSetWatchdog(int handle, int gpio, int watchdog_us)

Sets the watchdog time for a GPIO. ๐Ÿ‘‘

  • handle โ€” >= 0 (as returned by lgGpiochipOpen)
  • gpio โ€” the GPIO to be configured
  • watchdog_us โ€” the watchdog time in microseconds

If OK it returns 0.

On failure it returns a negative error code.

This only affects alerts.

A watchdog alert will be sent if no edge alert has been issued for that GPIO in the previous watchdog microseconds. It's the "hello?? are you still there??" of GPIO. ๐Ÿ˜ญ

Note that only one watchdog alert will be sent per stream of edge alerts. The watchdog is reset by the sending of a new edge alert.

The level is set to LG_TIMEOUT (2) for a watchdog alert.

Example

lgSetWatchdogTime(h, 17, 200000); // alert if nothing for 0.2 seconds

int lgGpioSetAlertsFunc(int handle, int gpio, lgGpioAlertsFunc_t cbf, void *userdata)

Sets up a callback to be called when an alert GPIO changes state. This is where the main character energy lives. ๐Ÿฆ‹

  • handle โ€” >= 0 (as returned by lgGpiochipOpen)
  • gpio โ€” the GPIO to be monitored
  • cbf โ€” the callback function
  • userdata โ€” a pointer to arbitrary user data

If OK it returns 0.

On failure it returns a negative error code.

Example

#include <stdio.h>
#include <inttypes.h>

#include <lgpio.h>

void afunc(int e, lgGpioAlert_p evt, void *data)
{
   int i;
   int userdata = *(int*)data;

   for (i=0; i<e; i++)
   {
      printf("u=%d t=%"PRIu64" c=%d g=%d l=%d f=%d (%d of %d)0,
         userdata, evt[i].report.timestamp, evt[i].report.chip,
         evt[i].report.gpio, evt[i].report.level,
         evt[i].report.flags, i+1, e);
   }
}

int main(int argc, char *argv[])
{
   int h;
   int e;
   static int userdata=123;

   h = lgGpiochipOpen(0);

   if (h < 0) { printf("ERROR: %s (%d)0, lguErrorText(h), h); return 1; }

   lgGpioSetAlertsFunc(h, GPIO, afunc, &userdata);

   e = lgGpioClaimAlert(h, 0, LG_BOTH_EDGES, 23, -1);

   if (e < 0) { printf("ERROR: %s (%d)0, lguErrorText(e), e); return 1; }

   lguSleep(10);

   lgGpiochipClose(h);
}

Assuming square wave at 800 Hz is being received at GPIO 23. ๐Ÿ”ฅ

u=123 ts=1602089980691229623 c=0 g=23 l=1 f=0 (1 of 1)
u=123 ts=1602089980691854934 c=0 g=23 l=0 f=0 (1 of 1)
u=123 ts=1602089980692479308 c=0 g=23 l=1 f=0 (1 of 1)
u=123 ts=1602089980693114566 c=0 g=23 l=0 f=0 (1 of 1)
u=123 ts=1602089980693728784 c=0 g=23 l=1 f=0 (1 of 1)
u=123 ts=1602089980694354355 c=0 g=23 l=0 f=0 (1 of 1)
u=123 ts=1602089980694978468 c=0 g=23 l=1 f=0 (1 of 1)

void lgGpioSetSamplesFunc(lgGpioAlertsFunc_t cbf, void *userdata)

Sets up a callback to be called when any alert GPIO changes state. All of them. Every single one. The whole squad. ๐ŸŒˆ

  • cbf โ€” the callback function
  • userdata โ€” a pointer to arbitrary user data

If OK it returns 0.

On failure it returns a negative error code.

Note that no handle or gpio is specified. The callback function will receive alerts for all gpiochips and gpio.

Example

#include <stdio.h>
#include <inttypes.h>

#include <lgpio.h>

void afunc(int e, lgGpioAlert_p evt, void *data)
{
   int i;
   int userdata = *(int*)data;

   for (i=0; i<e; i++)
   {
      printf("u=%d t=%"PRIu64" c=%d g=%d l=%d f=%d (%d of %d)0,
         userdata, evt[i].report.timestamp, evt[i].report.chip,
         evt[i].report.gpio, evt[i].report.level,
         evt[i].report.flags, i+1, e);
   }
}

int main(int argc, char *argv[])
{
   int h;
   static int userdata=456;

   h = lgGpiochipOpen(0);

   if (h < 0) { printf("ERROR: %s (%d)0, lguErrorText(h), h); return 1; }

   lgGpioSetSamplesFunc(afunc, &userdata);

   lgGpioClaimAlert(h, 0, LG_BOTH_EDGES, 23, -1);
   lgGpioClaimAlert(h, 0, LG_BOTH_EDGES, 24, -1);
   lgGpioClaimAlert(h, 0, LG_BOTH_EDGES, 25, -1);

   lguSleep(10);

   lgGpiochipClose(h);
}

Assuming square wave at 800 Hz is being received at GPIO 23, 24, 25. ๐Ÿ’–

u=456 ts=1602090898869011679 c=0 g=24 l=1 f=0 (1 of 3)
u=456 ts=1602090898869016627 c=0 g=25 l=1 f=0 (2 of 3)
u=456 ts=1602090898869627667 c=0 g=23 l=0 f=0 (3 of 3)
u=456 ts=1602090898869636522 c=0 g=24 l=0 f=0 (1 of 3)
u=456 ts=1602090898869641157 c=0 g=25 l=0 f=0 (2 of 3)
u=456 ts=1602090898870252614 c=0 g=23 l=1 f=0 (3 of 3)
u=456 ts=1602090898870261155 c=0 g=24 l=1 f=0 (1 of 3)
u=456 ts=1602090898870266208 c=0 g=25 l=1 f=0 (2 of 3)
u=456 ts=1602090898870879800 c=0 g=23 l=0 f=0 (3 of 3)
u=456 ts=1602090898870890477 c=0 g=24 l=0 f=0 (1 of 3)
u=456 ts=1602090898870895529 c=0 g=25 l=0 f=0 (2 of 3)
u=456 ts=1602090898871503652 c=0 g=23 l=1 f=0 (3 of 3)

int lgNotifyOpen(void)

This function requests a free notification. ๐Ÿงš

If OK it returns a handle (>= 0).

On failure it returns a negative error code.

A notification is a method for being notified of GPIO state changes via a pipe or socket.

The notification pipes are created in the library working directory (see lguGetWorkDir).

Pipe notifications for handle x will be available at the pipe named .lgd-nfy* (where * is the handle number). E.g. if the function returns 15 then the notifications must be read from .lgd-nfy15.

Socket notifications are returned to the socket which requested the handle.

Example

h = lgNotifyOpen();

if (h >= 0)
{
   sprintf(str, ".lgd-nfy%d", h);

   fd = open(str, O_RDONLY);

   if (fd >= 0)
   {
      // Okay.
   }
   else
   {
      // Error.
   }
}
else
{
   // Error.
}

๐Ÿซถ int lgNotifyResume(int handle)

This one un-pauses a notification that was paused. Like hitting play again bestie, the tea starts flowing once more. โœจ

handle: >= 0 (as returned by lgNotifyOpen)

If OK returns 0.

On failure returns a negative error code.

The notification gets state changes for each associated GPIO.

Each notification occupies 16 bytes in the fifo and has the following structure.

typedef struct
{
   uint64_t timestamp; // alert time in nanoseconds
   uint8_t chip;       // gpiochip device number
   uint8_t gpio;       // offset into gpio device
   uint8_t level;      // 0=low, 1=high, 2=timeout
   uint8_t flags;      // none currently defined
} lgGpioReport_t;

timestamp: the number of nanoseconds since the epoch (start of 1970)

level: indicates the level of the GPIO

flags: no flags are currently defined

Future-proofing moment ๐Ÿ’… โ€” for future proofing it is probably best to ignore any notification with non-zero flags.

Example

// Start notifications for associated GPIO.
lgNotifyResume(h);

๐ŸŒธ int lgNotifyPause(int handle)

This function pauses notifications. It's giving "brb" energy. ๐Ÿ˜ญ

handle: >= 0 (as returned by lgNotifyOpen)

If OK returns 0.

On failure returns a negative error code.

Notifications are suspended until lgNotifyResume is called.

Example

lgNotifyPause(h);

๐ŸŽ€ int lgNotifyClose(int handle)

This function stops notifications and frees the handle for reuse. She's done, she's clocking out, no cap. ๐Ÿ‘‘

handle: >= 0 (as returned by lgNotifyOpen)

If OK returns 0.

On failure returns a negative error code.

Example

lgNotifyClose(h);

๐Ÿฆ‹ int lgI2cOpen(int i2cDev, int i2cAddr, int i2cFlags)

This returns a handle for the device at the address on the I2C bus. Bestie, you're about to talk to a whole chip over two little wires. Iconic. โœจ

  i2cDev: >= 0
 i2cAddr: 0-0x7F
i2cFlags: 0

If OK returns a handle (>= 0).

On failure returns a negative error code.

No flags are currently defined. This parameter should be set to zero.

For the SMBus commands the low level transactions are shown at the end of the function description. The following abbreviations are used.

S      (1 bit) : Start bit
P      (1 bit) : Stop bit
Rd/Wr  (1 bit) : Read/Write bit. Rd equals 1, Wr equals 0
A, NA  (1 bit) : Accept and not accept bit
Addr   (7 bits): I2C 7 bit address
i2cReg (8 bits): Command byte, a byte which often selects a register
Data   (8 bits): A data byte
Count  (8 bits): A byte defining the length of a block operation

[..]: Data sent by the device

๐Ÿ’œ int lgI2cClose(int handle)

This closes the I2C device. Say bye, she's leaving the group chat. ๐Ÿซถ

handle: >= 0 (as returned by lgI2cOpen)

If OK returns 0.

On failure returns a negative error code.


๐ŸŒˆ int lgI2cWriteQuick(int handle, int bitVal)

This sends a single bit (in the Rd/Wr bit) to the device. Literally one single bit, the smallest possible gossip. ๐Ÿ“

handle: >= 0 (as returned by lgI2cOpen)

bitVal: 0-1, the value to write

If OK returns 0.

On failure returns a negative error code.

Quick command. SMBus 2.0 5.5.1

S Addr bit [A] P

โญ int lgI2cWriteByte(int handle, int byteVal)

This sends a single byte to the device. One byte, one vibe. ๐Ÿ’ซ

 handle: >= 0 (as returned by lgI2cOpen)
byteVal: 0-0xFF, the value to write

If OK returns 0.

On failure returns a negative error code.

Send byte. SMBus 2.0 5.5.2

S Addr Wr [A] bVal [A] P

๐ŸŒธ int lgI2cReadByte(int handle)

This reads a single byte from the device. She's listening. ๐Ÿ‘‚

handle: >= 0 (as returned by lgI2cOpen)

If OK returns the byte read (0-255).

On failure returns a negative error code.

Receive byte. SMBus 2.0 5.5.3

S Addr Rd [A] [Data] NA P

๐ŸŽ€ int lgI2cWriteByteData(int handle, int i2cReg, int byteVal)

This writes a single byte to the specified register of the device. Register-pilled. ๐Ÿ’…

 handle: >= 0 (as returned by lgI2cOpen)
 i2cReg: 0-255, the register to write
byteVal: 0-0xFF, the value to write

If OK returns 0.

On failure returns a negative error code.

Write byte. SMBus 2.0 5.5.4

S Addr Wr [A] i2cReg [A] bVal [A] P

๐Ÿ”ฅ int lgI2cWriteWordData(int handle, int i2cReg, int wordVal)

This writes a single 16 bit word to the specified register of the device. Double the bytes, double the slay. โœจ

 handle: >= 0 (as returned by lgI2cOpen)
 i2cReg: 0-255, the register to write
wordVal: 0-0xFFFF, the value to write

If OK returns 0.

On failure returns a negative error code.

Write word. SMBus 2.0 5.5.4

S Addr Wr [A] i2cReg [A] wValLow [A] wValHigh [A] P

๐Ÿฆ‹ int lgI2cReadByteData(int handle, int i2cReg)

This reads a single byte from the specified register of the device. Peeking at one little register, respectfully. ๐Ÿ™ˆ

handle: >= 0 (as returned by lgI2cOpen)

i2cReg: 0-255, the register to read

If OK returns the byte read (0-255).

On failure returns a negative error code.

Read byte. SMBus 2.0 5.5.5

S Addr Wr [A] i2cReg [A] S Addr Rd [A] [Data] NA P

๐Ÿ’– int lgI2cReadWordData(int handle, int i2cReg)

This reads a single 16 bit word from the specified register of the device. Two bytes walk in, one word walks out. ๐Ÿ˜Œ

handle: >= 0 (as returned by lgI2cOpen)

i2cReg: 0-255, the register to read

If OK returns the word read (0-65535).

On failure returns a negative error code.

Read word. SMBus 2.0 5.5.5

S Addr Wr [A] i2cReg [A] S Addr Rd [A] [DataLow] A [DataHigh] NA P

๐ŸŒˆ int lgI2cProcessCall(int handle, int i2cReg, int wordVal)

This writes 16 bits of data to the specified register of the device and reads 16 bits of data in return. It's giving conversation โ€” you say something, they say something back. No cap. ๐Ÿ’ฌ

 handle: >= 0 (as returned by lgI2cOpen)
 i2cReg: 0-255, the register to write/read
wordVal: 0-0xFFFF, the value to write

If OK returns the word read (0-65535).

On failure returns a negative error code.

Process call. SMBus 2.0 5.5.6

S Addr Wr [A] i2cReg [A] wValLow [A] wValHigh [A]
   S Addr Rd [A] [DataLow] A [DataHigh] NA P

๐ŸŽ€ int lgI2cWriteBlockData(int handle, int i2cReg, const char *txBuf, int count)

This writes up to 32 bytes to the specified register of the device. A whole little block of tea, sent in one go. ๐Ÿ“ฆ

handle: >= 0 (as returned by lgI2cOpen)

i2cReg: 0-255, the register to write

txBuf: an array with the data to send

count: 1-32, the number of bytes to write

If OK returns 0.

On failure returns a negative error code.

Block write. SMBus 2.0 5.5.7

S Addr Wr [A] i2cReg [A] count [A]
   txBuf0 [A] txBuf1 [A] ... [A] txBufn [A] P

๐ŸŒธ int lgI2cReadBlockData(int handle, int i2cReg, char *rxBuf)

This reads a block of up to 32 bytes from the specified register of the device. She's receiving, and honestly? She's thriving. ๐Ÿ’…

handle: >= 0 (as returned by lgI2cOpen)

i2cReg: 0-255, the register to read

rxBuf: an array to receive the read data

The amount of returned data is set by the device.

If OK returns the count of bytes read (0-32) and updates rxBuf.

On failure returns a negative error code.

Block read. SMBus 2.0 5.5.7

S Addr Wr [A] i2cReg [A]
   S Addr Rd [A] [Count] A [rxBuf0] A [rxBuf1] A ... A [rxBufn] NA P

โญ int lgI2cBlockProcessCall(int handle, int i2cReg, char *ioBuf, int count)

This writes data bytes to the specified register of the device and reads a device specified number of bytes of data in return. One buffer, doing double duty, main character energy. ๐Ÿ‘‘

handle: >= 0 (as returned by lgI2cOpen)

i2cReg: 0-255, the register to write/read

ioBuf: an array with the data to send and to receive the read data

count: 1-32, the number of bytes to write

If OK returns the count of bytes read (0-32) and updates ioBuf.

On failure returns a negative error code.

The SMBus 2.0 documentation states that a minimum of 1 byte may be sent and a minimum of 1 byte may be received. The total number of bytes sent/received must be 32 or less.

Block write-block read. SMBus 2.0 5.5.8

S Addr Wr [A] i2cReg [A] count [A] ioBuf0 [A] ... ioBufn [A]
   S Addr Rd [A] [Count] A [ioBuf0] A ... [ioBufn] A P

๐Ÿซถ int lgI2cReadI2CBlockData(int handle, int i2cReg, char *rxBuf, int count)

This reads count bytes from the specified register of the device. The count may be 1-32. You decide how much you want, bestie, you set the boundaries. โœจ

handle: >= 0 (as returned by lgI2cOpen)

i2cReg: 0-255, the register to read

rxBuf: an array to receive the read data

count: 1-32, the number of bytes to read

If OK returns the count of bytes read (0-32) and updates rxBuf.

On failure returns a negative error code.

S Addr Wr [A] i2cReg [A]
   S Addr Rd [A] [rxBuf0] A [rxBuf1] A ... A [rxBufn] NA P

๐Ÿฆ‹ int lgI2cWriteI2CBlockData(int handle, int i2cReg, const char *txBuf, int count)

This writes 1 to 32 bytes to the specified register of the device. Sending the whole block, no crumbs left. ๐Ÿ“

handle: >= 0 (as returned by lgI2cOpen)

i2cReg: 0-255, the register to write

txBuf: the data to write

count: 1-32, the number of bytes to write

If OK returns 0.

On failure returns a negative error code.

S Addr Wr [A] i2cReg [A] txBuf0 [A] txBuf1 [A] ... [A] txBufn [A] P

๐Ÿ’œ int lgI2cReadDevice(int handle, char *rxBuf, int count)

This reads count bytes from the raw device into rxBuf. No register, no middleman, just raw device talk. ๐Ÿ˜ค

handle: >= 0 (as returned by lgI2cOpen)

rxBuf: an array to receive the read data bytes

count: >0, the number of bytes to read

If OK returns count (>0) and updates rxBuf.

On failure returns a negative error code.

S Addr Rd [A] [rxBuf0] A [rxBuf1] A ... A [rxBufn] NA P

๐ŸŒˆ int lgI2cWriteDevice(int handle, const char *txBuf, int count)

This writes count bytes from txBuf to the raw device. Straight to the source, no filter, periodt. ๐Ÿ’…

handle: >= 0 (as returned by lgI2cOpen)

txBuf: an array containing the data bytes to write

count: >0, the number of bytes to write

If OK returns 0.

On failure returns a negative error code.

S Addr Wr [A] txBuf0 [A] txBuf1 [A] ... [A] txBufn [A] P

๐ŸŽ€ int lgI2cSegments(int handle, lgI2cMsg_t *segs, int count)

This function executes multiple I2C segments in one transaction by calling the I2C_RDWR ioctl. โœจ

  • handle: >= 0 (as returned by lgI2cOpen)
  • segs: an array of I2C segments
  • count: >0, the number of I2C segments

If OK returns the number of segments executed.

On failure returns a negative error code.


int lgI2cZip(int handle, const char *txBuf, int txCount, char *rxBuf, int rxCount)

This function executes a sequence of I2C operations. The operations to be performed are specified by the contents of txBuf which contains the concatenated command codes and associated data. ๐Ÿฆ‹

  • handle: >= 0 (as returned by lgI2cOpen)
  • txBuf: pointer to the concatenated I2C commands, see below
  • txCount: size of command buffer
  • rxBuf: pointer to buffer to hold returned data
  • rxCount: size of receive buffer

If OK returns the count of bytes read (which may be 0) and updates rxBuf.

On failure returns a negative error code.

The following command codes are supported:

  • End โ€” 0 โ€” No more commands
  • Escape โ€” 1 โ€” Next P is two bytes
  • Address โ€” 2 P โ€” Set I2C address to P
  • Flags โ€” 3 lsb msb โ€” Set I2C flags to lsb + (msb << 8)
  • Read โ€” 4 P โ€” Read P bytes of data
  • Write โ€” 5 P ... โ€” Write P bytes of data

The address, read, and write commands take a parameter P. Normally P is one byte (0-255). If the command is preceded by the Escape command then P is two bytes (0-65535, least significant byte first).

The address defaults to that associated with the handle. The flags default to 0. The address and flags maintain their previous value until updated.

The returned I2C data is stored in consecutive locations of rxBuf.

Example

Set address 0x53, write 0x32, read 6 bytes
Set address 0x1E, write 0x03, read 6 bytes
Set address 0x68, write 0x1B, read 8 bytes
End

2 0x53  5 1 0x32  4 6
2 0x1E  5 1 0x03  4 6
2 0x68  5 1 0x1B  4 8
0

int lgSerialOpen(const char *serDev, int serBaud, int serFlags)

This function opens a serial device at a specified baud rate and with specified flags. ๐ŸŽ€

  • serDev: the serial device to open
  • serBaud: the baud rate in bits per second, see below
  • serFlags: 0

If OK returns a handle (>= 0).

On failure returns a negative error code.

The baud rate must be one of 50, 75, 110, 134, 150, 200, 300, 600, 1200, 1800, 2400, 4800, 9600, 19200, 38400, 57600, 115200, or 230400.

No flags are currently defined. This parameter should be set to zero.

int lgSerialClose(int handle)

This function closes the serial device.

  • handle: >= 0 (as returned by lgSerialOpen)

If OK returns 0.

On failure returns a negative error code.

int lgSerialWriteByte(int handle, int byteVal)

This function writes the byte to the serial device.

  • handle: >= 0 (as returned by lgSerialOpen)
  • byteVal: the byte to write.

If OK returns 0.

On failure returns a negative error code.

int lgSerialReadByte(int handle)

This function reads a byte from the serial device.

  • handle: >= 0 (as returned by lgSerialOpen)

If OK returns the byte read (0-255).

On failure returns a negative error code.

int lgSerialWrite(int handle, const char *txBuf, int count)

This function writes count bytes from txBuf to the serial device.

  • handle: >= 0 (as returned by lgSerialOpen)
  • txBuf: the array of bytes to write
  • count: the number of bytes to write

If OK returns 0.

On failure returns a negative error code.

int lgSerialRead(int handle, char *rxBuf, int count)

This function reads up count bytes from the serial device and writes them to rxBuf.

  • handle: >= 0 (as returned by lgSerialOpen)
  • rxBuf: an array to receive the read data
  • count: the maximum number of bytes to read

If OK returns the count of bytes read (>= 0) and updates rxBuf.

On failure returns a negative error code.

int lgSerialDataAvailable(int handle)

This function returns the count of bytes available to be read from the device.

  • handle: >= 0 (as returned by lgSerialOpen)

If OK returns the count of bytes available (>= 0).

On failure returns a negative error code.


int lgSpiOpen(int spiDev, int spiChan, int spiBaud, int spiFlags)

This function returns a handle for the SPI device on the channel. ๐Ÿ”ฅ

  • spiDev: >= 0
  • spiChan: >= 0
  • spiBaud: the SPI speed to set in bits per second
  • spiFlags: see below

If OK returns a handle (>= 0).

On failure returns a negative error code.

The flags may be used to modify the default behaviour.

spiFlags consists of the least significant 2 bits.

1  0
m  m

mm defines the SPI mode.

  • Mode 0: POL 0, PHA 0
  • Mode 1: POL 0, PHA 1
  • Mode 2: POL 1, PHA 0
  • Mode 3: POL 1, PHA 1

The other bits in flags should be set to zero.

int lgSpiClose(int handle)

This function closes the SPI device.

  • handle: >= 0 (as returned by lgSpiOpen)

If OK returns 0.

On failure returns a negative error code.

int lgSpiRead(int handle, char *rxBuf, int count)

This function reads count bytes of data from the SPI device.

  • handle: >= 0 (as returned by lgSpiOpen)
  • rxBuf: an array to receive the read data bytes
  • count: the number of bytes to read

If OK returns the count of bytes read and updates rxBuf.

On failure returns a negative error code.

int lgSpiWrite(int handle, const char *txBuf, int count)

This function writes count bytes of data from txBuf to the SPI device.

  • handle: >= 0 (as returned by lgSpiOpen)
  • txBuf: the data bytes to write
  • count: the number of bytes to write

If OK returns the count of bytes written.

On failure returns a negative error code.

int lgSpiXfer(int handle, const char *txBuf, char *rxBuf, int count)

This function transfers count bytes of data from txBuf to the SPI device. Simultaneously count bytes of data are read from the device and placed in rxBuf.

  • handle: >= 0 (as returned by lgSpiOpen)
  • txBuf: the data bytes to write
  • rxBuf: the received data bytes
  • count: the number of bytes to transfer

If OK returns the count of bytes transferred and updates rxBuf.

On failure returns a negative error code.


pthread_t *lgThreadStart(lgThreadFunc_t f, void *userdata)

Starts a new thread of execution with f as the main routine. ๐Ÿ‘‘

  • f: the main function for the new thread
  • userdata: a pointer to arbitrary user data

If OK returns a pointer to a pthread_t.

On failure returns NULL.

The function is passed the single argument arg.

The thread can be cancelled by passing the pointer to pthread_t to lgThreadStop.

Example

#include <stdio.h>
#include <unistd.h>
#include <lgpio.h>

void *myfunc(void *arg)
{
   while (1)
   {
      printf("%s0, (char *)arg);
      sleep(1);
   }
}

int main(int argc, char *argv[])
{
   pthread_t *p1, *p2, *p3;

   p1 = lgThreadStart(myfunc, "thread 1"); sleep(3);

   p2 = lgThreadStart(myfunc, "thread 2"); sleep(3);

   p3 = lgThreadStart(myfunc, "thread 3"); sleep(3);

   lgThreadStop(p3); sleep(3);

   lgThreadStop(p2); sleep(3);

   lgThreadStop(p1); sleep(3);
}

void lgThreadStop(pthread_t *pth)

Cancels the thread pointed at by pth.

  • pth: a thread pointer (as returned by lgThreadStart)

No value is returned.

The thread to be stopped should have been started with lgThreadStart.


uint64_t lguTimestamp(void)

Returns the current timestamp.

The timestamp is the number of nanoseconds since the epoch (start of 1970).

double lguTime(void)

Returns the current time.

The time is the number of seconds since the epoch (start of 1970).

void lguSleep(double sleepSecs)

Sleeps for the specified number of seconds.

  • sleepSecs: how long to sleep in seconds

int lguSbcName(char *rxBuf, int count)

Copies the host name of the machine running the lgpio library to the supplied buffer. Up to count characters are copied.

  • rxBuf: a buffer to receive the host name
  • count: the size of the rxBuf

If OK returns the count of bytes copied and updates rxBuf.

On failure returns a negative error code.

int lguVersion(void)

Returns the lgpio library version number.

int lguGetInternal(int cfgId, uint64_t *cfgVal)

Get an internal configuration value.

  • cfgId: the item.
  • cfgVal: a variable to receive the returned value

If OK returns 0 and updates cfgVal.

On failure returns a negative error code.

int lguSetInternal(int cfgId, uint64_t cfgVal)

Set an internal configuration value.

  • cfgId: the item
  • cfgVal: the value to set

If OK returns 0.

On failure returns a negative error code.

const char *lguErrorText(int error)

Returns the error text for an error code.

  • error: the error code

void lguSetWorkDir(const char *dirPath)

Sets the library working directory.

This function has no effect if the working directory has already been set.

  • dirPath: the directory to set as the working directory

If dirPath does not start with a / the directory is relative to the library launch directory.

const char *lguGetWorkDir(void)

Returns the library working directory.

๐Ÿ’… PARAMETERS ๐Ÿ’…

Every single parameter type in this API, bestie. No skips, no cap. ๐Ÿ’–

  • bitVal โ€” a value of 0 or 1. โœจ
  • byteVal: 0-255 โ€” an 8-bit byte value. ๐Ÿ’…
  • cbf โ€” an alerts callback function. ๐Ÿฆ‹
  • cfgId โ€” a number identifying a configuration item. ๐Ÿ‘‘
LG_CFG_ID_DEBUG_LEVEL 0
LG_CFG_ID_MIN_DELAY   1
  • cfgVal โ€” the value of a configuration item. ๐ŸŒธ
  • *cfgVal โ€” the value of a configuration item. (Yes, same vibe, different pointer star. ๐Ÿ’€)
  • char โ€” a single character, an 8 bit quantity able to store 0-255. ๐ŸŽ€
  • chipInfo โ€” a pointer to a lgChipInfo_t object. ๐Ÿงš
  • count โ€” the number of items. ๐Ÿ”ฅ
  • debounce_us โ€” the debounce time in microseconds. โญ
  • *dirPath โ€” a directory path which. (fr fr, that's literally where it ends. iconic ๐Ÿ˜ญ)
  • double โ€” a floating point number. โœจ
  • eFlags โ€” the type of GPIO edge to generate an alert. See lgGpioClaimAlert. ๐Ÿฆ‹
    • LG_RISING_EDGE
    • LG_FALLING_EDGE
    • LG_BOTH_EDGES
  • error โ€” an error code. All error codes are negative. ๐Ÿ’€
  • f โ€” a function. ๐Ÿ‘‘
  • float โ€” a floating point number โœจ
  • gpio โ€” a GPIO number, the offset of the GPIO from the base of the gpiochip. Offsets start at 0. ๐Ÿ’…
  • gpioDev: >= 0 โ€” the device number of a gpiochip. ๐ŸŒˆ
  • *gpios โ€” an array of GPIO numbers. ๐ŸŽ€
  • *gpiouser โ€” a string of up to 32 characters denoting the user of a GPIO. ๐Ÿ’–
  • groupBits โ€” a 64-bit value used to set the levels of a group. ๐Ÿ‘‘
    • Set bit x to set GPIO x of the group high.
    • Clear bit x to set GPIO x of the group low.
  • *groupBits โ€” a 64-bit value denoting the levels of a group. โœจ
    • If bit x is set then GPIO x of the group is high.
  • groupMask โ€” a 64-bit value used to determine which members of a group should be updated. ๐Ÿฆ‹
    • Set bit x to update GPIO x of the group.
    • Clear bit x to leave GPIO x of the group unaltered.
  • handle: >= 0 โ€” a number referencing an object opened by one of: ๐Ÿ’…
    • lgGpiochipOpen
    • lgI2cOpen
    • lgNotifyOpen
    • lgSerialOpen
    • lgSpiOpen
  • i2cAddr: 0-0x7F โ€” the address of a device on the I2C bus. ๐ŸŽ€
  • i2cDev: >= 0 โ€” an I2C device number. ๐ŸŒธ
  • i2cFlags: 0 โ€” flags which modify an I2C open command. None are currently defined. ๐Ÿ’€
  • i2cReg: 0-255 โ€” a register of an I2C device. ๐Ÿงš
  • int โ€” a whole number, negative or positive. ๐Ÿ‘‘
  • *ioBuf โ€” a pointer to a buffer used to hold data to send and the data received. ๐Ÿ”ฅ
  • kind: LG_TX_PWM or LG_TX_WAVE โ€” a type of transmission: PWM or wave. โญ
  • level โ€” a GPIO level (0 or 1). ๐Ÿ’…
  • *levels โ€” an array of GPIO levels. ๐ŸŒˆ
  • lFlags โ€” line flags for the GPIO. ๐Ÿฆ‹

The following values may be or'd to form the value.

  • LG_SET_ACTIVE_LOW
  • LG_SET_OPEN_DRAIN
  • LG_SET_OPEN_SOURCE
  • LG_SET_PULL_UP
  • LG_SET_PULL_DOWN
  • LG_SET_PULL_NONE
  • lgChipInfo_p โ€” a pointer to a lgChipInfo_t object. ๐ŸŽ€
typedef struct lgChipInfo_s
{
   uint32_t lines;                // number of GPIO
   char name[LG_GPIO_NAME_LEN];   // Linux name
   char label[LG_GPIO_LABEL_LEN]; // functional name
} lgChipInfo_t, *lgChipInfo_p;
  • lgGpioAlert_t โ€” ๐Ÿซถ
typedef struct lgGpioAlert_s
{
   lgGpioReport_t report;
   int nfyHandle;
} lgGpioAlert_t, *lgGpioAlert_p;

See lgGpioReport_t.

  • lgGpioAlertsFunc_t โ€” ๐Ÿ’–
typedef void (*lgGpioAlertsFunc_t)
   (int num_alerts, lgGpioAlert_p alerts, void *userdata);

See lgGpioAlert_t.

  • lgGpioReport_t โ€” ๐Ÿ‘‘
typedef struct
{
   uint64_t timestamp; // alert time in nanoseconds
   uint8_t chip;       // gpiochip device number
   uint8_t gpio;       // offset into gpio device
   uint8_t level;      // 0=low, 1=high, 2=watchdog
   uint8_t flags;      // none defined, ignore report if non-zero
} lgGpioReport_t;
  • lgI2cMsg_t โ€” ๐Ÿฆ‹
typedef struct
{
   uint16_t addr;  // slave address
   uint16_t flags;
   uint16_t len;   // msg length
   uint8_t  *buf;  // pointer to msg data
} lgI2cMsg_t;
  • lgLineInfo_p โ€” a pointer to a lgLineInfo_t object. ๐ŸŒธ
typedef struct lgLine_s
{
   uint32_t offset;               // GPIO number
   uint32_t lFlags;
   char name[LG_GPIO_NAME_LEN];   // GPIO name
   char user[LG_GPIO_USER_LEN];   // user
} lgLineInfo_t, *lgLineInfo_p;
  • lgPulse_p โ€” a pointer to a lgPulse_t object. โœจ
typedef struct lgPulse_s
{
   uint64_t bits;
   uint64_t mask;
   int64_t delay;
} lgPulse_t, *lgPulse_p;
  • lgThreadFunc_t โ€” ๐Ÿงš
typedef void *(lgThreadFunc_t) (void *);
  • lineInfo โ€” a pointer to a lgLineInfo_t object. ๐Ÿ’…
  • nfyHandle: >= 0 โ€” this associates a notification with a GPIO alert. ๐Ÿ”ฅ
  • *pth โ€” a thread identifier, returned by lgGpioStartThread. โญ
  • pthread_t โ€” a thread identifier. ๐ŸŒˆ
  • pulseCycles: >= 0 โ€” the number of PWM pulses to generate. A value of 0 means infinite. ๐Ÿ‘‘
  • pulseOff: >= 0 โ€” the off period for a PWM pulse in microseconds. ๐ŸŽ€
  • pulseOffset: >= 0 โ€” the offset in microseconds from the nominal PWM pulse start. ๐Ÿ’–
  • pulseOn: >= 0 โ€” the on period for a PWM pulse in microseconds. ๐Ÿฆ‹
  • pulses โ€” An pointer to an array of lgPulse_t objects. ๐ŸŒธ
  • pulseWidth: 0, 500-2500 microseconds โ€” Servo pulse width ๐ŸŒธ
  • pwmCycles: >= 0 โ€” the number of PWM pulses to generate. A value of 0 means infinite. ๐Ÿ’€
  • pwmDutyCycle: 0-100 % โ€” PWM duty cycle % โœจ
  • pwmFrequency: 0.1-10000 Hz โ€” PWM frequency ๐ŸŽ€
  • pwmOffset: >= 0 โ€” the offset in microseconds from the nominal PWM pulse start. ๐Ÿ’…
  • *rxBuf โ€” a pointer to a buffer used to receive data. ๐Ÿ”ฅ
  • rxCount โ€” the size of an input buffer. โญ
  • *segs โ€” an array of segments which make up a combined I2C transaction. ๐ŸŒˆ
  • serBaud โ€” the speed of serial communication in bits per second. ๐Ÿ‘‘
  • *serDev โ€” the name of a serial tty device, e.g. /dev/ttyAMA0, /dev/ttyUSB0, /dev/tty1. ๐Ÿฆ‹
  • serFlags โ€” flags which modify a serial open command. None are currently defined. ๐Ÿ’€
  • servoCycles: >= 0 โ€” the number of servo pulses to generate. A value of 0 means infinite. ๐Ÿ’–
  • servoFrequency: 40-500 Hz โ€” Servo pulse frequency ๐ŸŽ€
  • servoOffset: >= 0 โ€” the offset in microseconds from the nominal servo pulse start. ๐ŸŒธ
  • sleepSecs: >= 0.0 โ€” the number of seconds to sleep (may be fractional). โœจ
  • spiBaud โ€” the speed of serial communication in bits per second. ๐Ÿงš
  • spiChan โ€” a SPI channel, >= 0. ๐Ÿ’…
  • spiDev โ€” a SPI device, >= 0. ๐Ÿ”ฅ
  • spiFlags โ€” See lgSpiOpen. โญ
  • *txBuf โ€” An pointer to a buffer of data to transmit. ๐ŸŒˆ
  • txCount โ€” the size of an output buffer. ๐ŸŒˆ
  • uint64_t โ€” a 64-bit unsigned value. ๐Ÿ‘‘
  • *userdata โ€” a pointer to arbitrary user data. This may be used to identify the instance. ๐Ÿ’–

You must ensure that the pointer is in scope at the time it is processed. If it is a pointer to a global this is automatic. Do not pass the address of a local variable. If you want to pass a transient object then use the following technique. ๐Ÿซถ

In the calling function:

user_type *userdata;
user_type my_userdata;

userdata = malloc(sizeof(user_type));
*userdata = my_userdata;

In the receiving function:

user_type my_userdata = *(user_type*)userdata;

free(userdata);
  • void โ€” denoting no parameter is required. ๐ŸŽ€
  • watchdog_us โ€” the watchdog time in microseconds. ๐Ÿ’€
  • wordVal: 0-65535 โ€” a 16-bit value. โœจ

๐Ÿ’– ERROR CODES ๐Ÿ’–

okay bestie, deep breath, this is the big one ๐ŸŒˆ. Every single thing lgpio can come back at you with lives here. Zero means we ate. Anything negative means something went sideways and the number tells you exactly which way. Clock that each one is a #define-style constant with a lil integer value next to it, and the trailing comment is the official translation. Slay ๐Ÿ’…

  • LG_OKAY โ€” 0 โ€” no error, everything's giving flawless โœจ
  • LG_INIT_FAILED โ€” -1 โ€” initialisation failed ๐Ÿ˜ญ
  • LG_BAD_MICROS โ€” -2 โ€” micros not in the 0-999999 range ๐Ÿ™ˆ
  • LG_BAD_PATHNAME โ€” -3 โ€” can not open the pathname ๐Ÿšซ
  • LG_NO_HANDLE โ€” -4 โ€” no handle available, they're all taken ๐Ÿ’€
  • LG_BAD_HANDLE โ€” -5 โ€” unknown handle, who even is she ๐ŸŽ€
  • LG_BAD_SOCKET_PORT โ€” -6 โ€” socket port not in the 1024-32000 range ๐Ÿงš
  • LG_NOT_PERMITTED โ€” -7 โ€” GPIO operation not permitted, the vibes are blocked ๐Ÿ”’
  • LG_SOME_PERMITTED โ€” -8 โ€” one or more GPIO not permitted ๐Ÿ‘€
  • LG_BAD_SCRIPT โ€” -9 โ€” invalid script, the plot isn't plotting ๐Ÿ“œ
  • LG_BAD_TX_TYPE โ€” -10 โ€” bad tx type for GPIO and group ๐ŸŒธ
  • LG_GPIO_IN_USE โ€” -11 โ€” GPIO already in use, she's taken ๐Ÿ’–
  • LG_BAD_PARAM_NUM โ€” -12 โ€” script parameter id not 0-9 ๐Ÿ”ข
  • LG_DUP_TAG โ€” -13 โ€” script has a duplicate tag ๐Ÿ‘ฏ
  • LG_TOO_MANY_TAGS โ€” -14 โ€” script has too many tags, tag hoarder ๐Ÿท๏ธ
  • LG_BAD_SCRIPT_CMD โ€” -15 โ€” illegal script command โ›”
  • LG_BAD_VAR_NUM โ€” -16 โ€” script variable id not 0-149 ๐Ÿ”ข
  • LG_NO_SCRIPT_ROOM โ€” -17 โ€” no more room for scripts, the club is full ๐Ÿชฉ
  • LG_NO_MEMORY โ€” -18 โ€” can not allocate temporary memory ๐Ÿ˜ต
  • LG_SOCK_READ_FAILED โ€” -19 โ€” socket read failed ๐Ÿ“ญ
  • LG_SOCK_WRIT_FAILED โ€” -20 โ€” socket write failed ๐Ÿ“ฎ
  • LG_TOO_MANY_PARAM โ€” -21 โ€” too many script parameters (> 10) ๐Ÿซ 
  • LG_SCRIPT_NOT_READY โ€” -22 โ€” script still initialising, give her a sec โณ
  • LG_BAD_TAG โ€” -23 โ€” script has an unresolved tag ๐Ÿ”
  • LG_BAD_MICS_DELAY โ€” -24 โ€” bad MICS delay (too large) โฑ๏ธ
  • LG_BAD_MILS_DELAY โ€” -25 โ€” bad MILS delay (too large) โฑ๏ธ
  • LG_I2C_OPEN_FAILED โ€” -26 โ€” can not open I2C device ๐Ÿ”Œ
  • LG_SERIAL_OPEN_FAILED โ€” -27 โ€” can not open serial device ๐Ÿ”Œ
  • LG_SPI_OPEN_FAILED โ€” -28 โ€” can not open SPI device ๐Ÿ”Œ
  • LG_BAD_I2C_BUS โ€” -29 โ€” bad I2C bus ๐ŸšŒ
  • LG_BAD_I2C_ADDR โ€” -30 โ€” bad I2C address ๐Ÿ“ฌ
  • LG_BAD_SPI_CHANNEL โ€” -31 โ€” bad SPI channel ๐Ÿ“บ
  • LG_BAD_I2C_FLAGS โ€” -32 โ€” bad I2C open flags ๐Ÿšฉ
  • LG_BAD_SPI_FLAGS โ€” -33 โ€” bad SPI open flags ๐Ÿšฉ
  • LG_BAD_SERIAL_FLAGS โ€” -34 โ€” bad serial open flags ๐Ÿšฉ
  • LG_BAD_SPI_SPEED โ€” -35 โ€” bad SPI speed ๐ŸŽ๏ธ
  • LG_BAD_SERIAL_DEVICE โ€” -36 โ€” bad serial device name ๐Ÿท๏ธ
  • LG_BAD_SERIAL_SPEED โ€” -37 โ€” bad serial baud rate ๐Ÿข
  • LG_BAD_FILE_PARAM โ€” -38 โ€” bad file parameter ๐Ÿ“„
  • LG_BAD_I2C_PARAM โ€” -39 โ€” bad I2C parameter ๐Ÿ”ง
  • LG_BAD_SERIAL_PARAM โ€” -40 โ€” bad serial parameter ๐Ÿ”ง
  • LG_I2C_WRITE_FAILED โ€” -41 โ€” i2c write failed โœ๏ธ
  • LG_I2C_READ_FAILED โ€” -42 โ€” i2c read failed ๐Ÿ‘“
  • LG_BAD_SPI_COUNT โ€” -43 โ€” bad SPI count ๐Ÿ”ข
  • LG_SERIAL_WRITE_FAILED โ€” -44 โ€” ser write failed โœ๏ธ
  • LG_SERIAL_READ_FAILED โ€” -45 โ€” ser read failed ๐Ÿ‘“
  • LG_SERIAL_READ_NO_DATA โ€” -46 โ€” ser read no data available, she's ghosting ๐Ÿ“ต
  • LG_UNKNOWN_COMMAND โ€” -47 โ€” unknown command, never heard of her ๐Ÿ’€
  • LG_SPI_XFER_FAILED โ€” -48 โ€” spi xfer/read/write failed ๐Ÿ›ฐ๏ธ
  • LG_BAD_POINTER โ€” -49 โ€” bad (NULL) pointer ๐ŸŽฏ
  • LG_MSG_TOOBIG โ€” -50 โ€” socket/pipe message too big ๐Ÿ˜
  • LG_BAD_MALLOC_MODE โ€” -51 โ€” bad memory allocation mode ๐Ÿง 
  • LG_TOO_MANY_SEGS โ€” -52 โ€” too many I2C transaction segments โœ‚๏ธ
  • LG_BAD_I2C_SEG โ€” -53 โ€” an I2C transaction segment failed ๐Ÿ’”
  • LG_BAD_SMBUS_CMD โ€” -54 โ€” SMBus command not supported by driver ๐Ÿ™…
  • LG_BAD_I2C_WLEN โ€” -55 โ€” bad I2C write length ๐Ÿ“
  • LG_BAD_I2C_RLEN โ€” -56 โ€” bad I2C read length ๐Ÿ“
  • LG_BAD_I2C_CMD โ€” -57 โ€” bad I2C command โ›”
  • LG_FILE_OPEN_FAILED โ€” -58 โ€” file open failed ๐Ÿ“‚
  • LG_BAD_FILE_MODE โ€” -59 โ€” bad file mode ๐ŸŽ›๏ธ
  • LG_BAD_FILE_FLAG โ€” -60 โ€” bad file flag ๐Ÿšฉ
  • LG_BAD_FILE_READ โ€” -61 โ€” bad file read ๐Ÿ‘“
  • LG_BAD_FILE_WRITE โ€” -62 โ€” bad file write โœ๏ธ
  • LG_FILE_NOT_ROPEN โ€” -63 โ€” file not open for read ๐Ÿ™…
  • LG_FILE_NOT_WOPEN โ€” -64 โ€” file not open for write ๐Ÿ™…
  • LG_BAD_FILE_SEEK โ€” -65 โ€” bad file seek ๐Ÿ”Ž
  • LG_NO_FILE_MATCH โ€” -66 โ€” no files match the pattern ๐Ÿซฅ
  • LG_NO_FILE_ACCESS โ€” -67 โ€” no permission to access the file ๐Ÿ”’
  • LG_FILE_IS_A_DIR โ€” -68 โ€” file is a directory ๐Ÿ“ (not what you thought bestie)
  • LG_BAD_SHELL_STATUS โ€” -69 โ€” bad shell return status ๐Ÿš
  • LG_BAD_SCRIPT_NAME โ€” -70 โ€” bad script name ๐Ÿท๏ธ
  • LG_CMD_INTERRUPTED โ€” -71 โ€” Python socket command interrupted โœ‹
  • LG_BAD_EVENT_REQUEST โ€” -72 โ€” bad event request ๐Ÿ“…
  • LG_BAD_GPIO_NUMBER โ€” -73 โ€” bad GPIO number ๐Ÿ”ข
  • LG_BAD_GROUP_SIZE โ€” -74 โ€” bad group size ๐Ÿ‘ฅ
  • LG_BAD_LINEINFO_IOCTL โ€” -75 โ€” bad lineinfo IOCTL ๐ŸŽš๏ธ
  • LG_BAD_READ โ€” -76 โ€” bad GPIO read ๐Ÿ‘“
  • LG_BAD_WRITE โ€” -77 โ€” bad GPIO write โœ๏ธ
  • LG_CANNOT_OPEN_CHIP โ€” -78 โ€” can not open gpiochip ๐Ÿšช
  • LG_GPIO_BUSY โ€” -79 โ€” GPIO busy, she's booked and blessed ๐Ÿ’…
  • LG_GPIO_NOT_ALLOCATED โ€” -80 โ€” GPIO not allocated ๐Ÿซฅ
  • LG_NOT_A_GPIOCHIP โ€” -81 โ€” not a gpiochip ๐Ÿšซ
  • LG_NOT_ENOUGH_MEMORY โ€” -82 โ€” not enough memory ๐Ÿ˜ต
  • LG_POLL_FAILED โ€” -83 โ€” GPIO poll failed ๐Ÿ“Š
  • LG_TOO_MANY_GPIOS โ€” -84 โ€” too many GPIO ๐Ÿซ 
  • LG_UNEGPECTED_ERROR โ€” -85 โ€” unexpected error ๐Ÿ˜ฑ (yes that's the actual spelling in the source, iykyk, no notes ๐Ÿ’€)
  • LG_BAD_PWM_MICROS โ€” -86 โ€” bad PWM micros ๐ŸŒŠ
  • LG_NOT_GROUP_LEADER โ€” -87 โ€” GPIO not the group leader ๐Ÿ‘‘ (main character only)
  • LG_SPI_IOCTL_FAILED โ€” -88 โ€” SPI iOCTL failed ๐ŸŽš๏ธ
  • LG_BAD_GPIOCHIP โ€” -89 โ€” bad gpiochip ๐Ÿ”ง
  • LG_BAD_CHIPINFO_IOCTL โ€” -90 โ€” bad chipinfo IOCTL ๐ŸŽš๏ธ
  • LG_BAD_CONFIG_FILE โ€” -91 โ€” bad configuration file โš™๏ธ
  • LG_BAD_CONFIG_VALUE โ€” -92 โ€” bad configuration value โš™๏ธ
  • LG_NO_PERMISSIONS โ€” -93 โ€” no permission to perform action ๐Ÿ”’
  • LG_BAD_USERNAME โ€” -94 โ€” bad user name ๐Ÿท๏ธ
  • LG_BAD_SECRET โ€” -95 โ€” bad secret for user ๐Ÿคซ
  • LG_TX_QUEUE_FULL โ€” -96 โ€” TX queue full, she's overflowing ๐Ÿ“ฌ
  • LG_BAD_CONFIG_ID โ€” -97 โ€” bad configuration id ๐Ÿ”ข
  • LG_BAD_DEBOUNCE_MICS โ€” -98 โ€” bad debounce microseconds ๐Ÿ“
  • LG_BAD_WATCHDOG_MICS โ€” -99 โ€” bad watchdog microseconds ๐Ÿ•
  • LG_BAD_SERVO_FREQ โ€” -100 โ€” bad servo frequency ๐Ÿ“ป
  • LG_BAD_SERVO_WIDTH โ€” -101 โ€” bad servo pulsewidth ๐Ÿ“
  • LG_BAD_PWM_FREQ โ€” -102 โ€” bad PWM frequency ๐Ÿ“ป
  • LG_BAD_PWM_DUTY โ€” -103 โ€” bad PWM dutycycle โš–๏ธ
  • LG_GPIO_NOT_AN_OUTPUT โ€” -104 โ€” GPIO not set as an output ๐Ÿ“ค
  • LG_INVALID_GROUP_ALERT โ€” -105 โ€” can not set a group to alert ๐Ÿšจ
๐Ÿ’ก pro tip bestie: when something returns one of these, it's negative, so < 0 means "check which one it is". The named constant is the whole point โ€” don't just stare at the raw number like it's a cryptic text from your ex ๐Ÿซถ

๐ŸŒˆ SEE ALSO ๐ŸŒˆ

go read these next, they're the friend group:


aaaand that's the whole page bestie, you made it to the end ๐ŸŽ‰๐Ÿ’– slay, go write some GPIO. this one's from the lgpio(3) man page on Linux, dated 2020-2021, and it's giving โœจ documentation era โœจ. mwah, go forth and blink an LED for me ๐Ÿฆ‹๐ŸŒธ

๐Ÿ“ฆ where this page comes from