<       !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~      !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~   Basic GPIO types(c) 2016, Drew HessBSD3Drew Hess <src@drewhess.com> experimental non-portable Trustworthy05AIT!.The top level of the GPIO exception hierarchy.A pin's interrupt mode.ENote that the pin's interrupt mode is defined in terms of the pin's logicalG signal value; i.e., when the pin is configured for active-low logic, 5 refers to the physical signal's trailing edge, and . refers to the physical signal's rising edge.Interrupts are disabled,Interrupt on the pin's (logical) rising edge-Interrupt on the pin's (logical) falling edge1Interrupt on any change to the pin's signal level'A pin's signal level as a binary value. .A pin's active level (active-high/active-low). !A pin's direction (input/output).Catalog a pin's capabilities.,The set of input modes that the pin supports-The set of output modes that the pin supports.Does the pin support interrupts in input mode?cGPIO pins may support a number of different physical configurations when used as a digital output.;Pins that are capable of output will at least support the  mode.  mode is special in that, unlike the other output modes, it does not represent a unique physical configuration, but is simply a pseudonym for another (actual) output mode. Exactly which mode is used by the hardware when 4 mode is specified is platform-dependent. By using  OutputDefaut mode, you are saying that you don't care about the pin's actual configuration, other than the fact that it's being used for output.^The pin's default output mode, i.e., the mode used when a more specific mode is not specified$The output actively drives both the   and  statesThe output actively drives the  state, but  " is left floating (also known as open collector)The output actively drives the A state, and is connected to an internal pull-up resistor in the   state.The output actively drives the   state, but " is left floating (also known as  open emitter)The output actively drives the  C state, and is connected to an internal pull-down resistor in the  state.bGPIO pins may support a number of different physical configurations when used as a digital input.:Pins that are capable of input will at least support the  mode.  mode is special in that, unlike the other input modes, it does not represent a unique physical configuration, but is simply a pseudonym for another (actual) input mode. Exactly which mode is used by the hardware when 4 mode is specified is platform-dependent. By using  InputDefaut mode, you are saying that you don't care about the pin's actual configuration, other than the fact that it's being used for input.]The pin's default input mode, i.e., the mode used when a more specific mode is not specifiedA floating / high-impedance / tri-state mode which uses little power, but when disconnected, may cause the pin's value to be indeterminateThe pin is connected to an internal pull-up resistor such that, when the pin is disconnected or connected to a floating / high-impedance node, its physical value will be  The pin is connected to an internal pull-down resistor such that, when the pin is disconnected or connected to a floating / high-impedance node, its physical value will be !%A GPIO pin, identified by pin number.Note that GPIO pin numbering is platform- and runtime-dependent. See the documentation for your particular platform for an explanation of how pin numbers are assigned to physical pins.#Get the pin number as an .pinNumber (Pin 5)5$ Invert a   value.invertDirection InOutinvertDirection OutIn% Invert a .invertValue HighLowinvertValue LowHigh& Convert a # to its logical boolean equivalent.valueToBool HighTruevalueToBool LowFalse' Convert a  to its logical  equivalent.boolToValue TrueHighboolToValue FalseLow(Convert  to .)Ask whether an exception is .3  !"#$%&'()*+,-./012*  !"#$%&'()*!"    #$%&'()   !"#$%&'()*+,-./012 /Functions used by the mock MonadSysfs instance.(c) 2016, Drew HessBSD3Drew Hess <src@drewhess.com> experimental non-portableSafe:An opaque type representing the current state of the mock sysfs filesystem. Because the constructor is not exported via the public interface, you cannot create these directly, but you can manipulate them using the exposed mock sysfs! operations and then pass those  s around.-'Types for Linux sysfs GPIO(c) 2016, Drew HessBSD3Drew Hess <src@drewhess.com> experimental non-portableSafe05r!Exceptions that can be thrown by sysfs( computations (in addition to standard    exceptions, of course).The  UnexpectedX8 values are truly exceptional and mean that, while the sysfs attribute for the given pin exists, the contents of the attribute do not match any expected value for that attribute, which probably means that the package is incompatible with the sysfs* filesystem due to a kernel-level change.sThe sysfs filesystem does not existtSomething in the sysfsE filesystem does not behave as expected (could indicate a change in sysfs, behavior that the package does not expect)uThe sysfs< operation is not permitted due to insufficient permissionsvThe operation on the specified pin is not permitted, either due to insufficient permissions, or because the pin's attribute cannot be modified (e.g., trying to write to a pin that's configured for input)w`The operation is invalid for the specified pin, or in the specified pin's current configurationx!The pin has already been exportedy The specified pin does not existz.The pin has been un-exported or does not exist{1The pin does not support the specified input mode|2The pin does not support the specified output mode}The pin does not have a  direction attribute~The pin does not have an edge attribute,An unexpected value was read from the pin's  direction attribute,An unexpected value was read from the pin's value attribute,An unexpected value was read from the pin's edge attribute,An unexpected value was read from the pin's  active_low attribute4An unexpected value was read from the specified fileAn internal error has occurred in the interpreter, something which should "never happen" and should be reported to the package maintainerCLinux GPIO pins that can be configured to generate inputs have an edge attribute in the sysfs< GPIO filesystem. This type represents the values that the edge attribute can take.Note that in Linux sysfs+ GPIO, the signal edge referred to by the edge" attribute refers to the signal's logical< value; i.e., it takes into account the value of the pin's  active_low attribute.This type is isomorphic to the  type. See  and .Interrupts disabled/Interrupt on the (logical) signal's rising edge0Interrupt on the (logical) signal's falling edge+Interrupt on any change to the signal level Convert a  value to its equivalent  value.toPinInterruptMode NoneDisabledtoPinInterruptMode Rising RisingEdgetoPinInterruptMode Falling FallingEdgetoPinInterruptMode BothLevel Convert a  value to its equivalent  value.toSysfsEdge DisabledNonetoSysfsEdge RisingEdgeRisingtoSysfsEdge FallingEdgeFallingtoSysfsEdge LevelBothrstuvwxyz{|}~rvstuwxyz{|}~rstuvwxyz{|}~rstuvwxyz{|}~Useful low-level Linux sysfs functions(c) 2016, Drew HessBSD3Drew Hess <src@drewhess.com> experimental non-portableSafeThe base path to Linux's sysfs GPIO filesystem. sysfsPath"/sys/class/gpio";The name of the control file used to export GPIO pins via sysfs.exportFileName"/sys/class/gpio/export"?The name of the control file used to "unexport" GPIO pins via sysfs.unexportFileName"/sys/class/gpio/unexport"Exporting a GPIO pin via sysfs9 creates a control directory corresponding to that pin. / gives the name of that directory for a given !.pinDirName (Pin 16)"/sys/class/gpio/gpio16"AThe name of the attribute file used to read and write the pin's  active_low value.pinActiveLowFileName (Pin 16)#"/sys/class/gpio/gpio16/active_low"+Pins whose direction can be controlled via sysfs provide a  direction attribute file. * gives the name of that file for a given !z. Note that some pins' direction cannot be set. In these cases, the file named by this function does not actually exist.pinDirectionFileName (Pin 16)""/sys/class/gpio/gpio16/direction"GPins that can be configured as interrupt-generating inputs provide an edge attribute file. * gives the name of that file for a given !. Note that some pins' edge configuration cannot be set. In these cases, the file named by this function does not actually exist.pinEdgeFileName (Pin 16)"/sys/class/gpio/gpio16/edge"VThe name of the attribute file used to read and write the pin's logical signal value.pinValueFileName (Pin 16)"/sys/class/gpio/gpio16/value" Convert a   value to the corresponding  value expected by a pin's  direction attribute in the sysfs GPIO filesystem.pinDirectionToBS In"in\n"pinDirectionToBS Out"out\n" Convert a  value to the corresponding  value expected by a pin's  direction attribute in the sysfs~ GPIO, which can be used to configure the pin for output and simultaneously set the pin's (physical) signal level; see the  7https://www.kernel.org/doc/Documentation/gpio/sysfs.txtLinux kernel documentation for details.pinDirectionValueToBS Low"low\n"pinDirectionValueToBS High"high\n"When writing a pin's  direction attribute in the sysfs GPIO filesystem with a  value, in\n$ configures the pin for input, and out\ni configures the pin for output while also initializing the pin's (physical) signal level to a low value.Furthermore, you may write low\n or high\n to the  direction] attribute to configure the pin for output and simulataneously set the pin's physical value.Therefore, writing a pin's  direction attribute affects not only its direction, but also (potentially) its value. This function's return type reflects that possibility. See the  7https://www.kernel.org/doc/Documentation/gpio/sysfs.txtLinux kernel documentation for details.This function converts a  direction' attribute value, encoded as a strict , to its corresponding   and (possible)  pair; or ' if the attribute encoding is invalid.:set -XOverloadedStringsbsToPinDirection "in\n"Just (In,Nothing)bsToPinDirection "out\n"Just (Out,Just Low)bsToPinDirection "low\n"Just (Out,Just Low)bsToPinDirection "high\n"Just (Out,Just High)bsToPinDirection "foo\n"Nothing Convert a  value to the  value expected by a pin's edge attribute in the sysfs GPIO filesystem.sysfsEdgeToBS None"none\n"sysfsEdgeToBS Rising "rising\n"sysfsEdgeToBS Falling "falling\n"sysfsEdgeToBS Both"both\n" Inverse of .:set -XOverloadedStringsbsToSysfsEdge "none\n" Just NonebsToSysfsEdge "rising\n" Just RisingbsToSysfsEdge "falling\n" Just FallingbsToSysfsEdge "both\n" Just BothbsToSysfsEdge "foo\n"Nothing Convert a  to the  value expected by a pin's value attribute in the sysfs GPIO filesystem.pinValueToBS Low"0\n"pinValueToBS High"1\n" Convert a value' attribute value, encoded as a strict , to its corresponding .Note that the sysfs value attribute is quite liberal: a  value of 0\nN will set the pin's (logical) signal level to low, but any other (non-empty)  value will set it to high.:set -XOverloadedStringsbsToPinValue "0\n"Just LowbsToPinValue "1\n" Just HighbsToPinValue "high\n" Just High"bsToPinValue "low\n" -- nota bene! Just HighbsToPinValue "foo\n" Just HighbsToPinValue ""Nothing Convert a  to the  value expected by a pin's  active_low attribute in the sysfs GPIO filesystem.activeLowToBS False"0\n"activeLowToBS True"1\n" Convert an  active_low' attribute value, encoded as a strict , to its corresponding  value.Note that the sysfs  active_low attribute is quite liberal: a  value of 0\n returns  and any other (non-empty)  value returns .:set -XOverloadedStringsbsToActiveLow "0\n" Just FalsebsToActiveLow "1\n" Just TruebsToActiveLow "high\n" Just True#bsToActiveLow "low\n" -- nota bene! Just TruebsToActiveLow "foo\n" Just TruebsToActiveLow ""Nothing Convert an * to a decimal ASCII encoding in a strict . intToBS 37"37"Convert a strict decimal ASCII  encoding of an integer to an  (maybe). If there are any extraneous trailing characters after the decimal ASCII encoding, other than a single newline character, this is treated as a failure (unlike &, which returns the remaining string).:set -XOverloadedStrings bsToInt "37"Just 37bsToInt "37\n"Just 37bsToInt "37abc"NothingbsToInt "37 a"NothingA monad for GPIO computations(c) 2016, Drew HessBSD3Drew Hess <src@drewhess.com> experimental non-portableSafe9;<=?S[09A handle to a pin that's been configured for output only.Note that output pins can be both read and written. However, they only support non-blocking reads, not interrupt-driven polling reads.mA handle to a pin that's been configured both for non-blocking reads and for interrupt-driven polling reads.FA handle to a pin that's been configured for non-blocking reads only.You cannot poll an  for interrupts. See .A monad type class for GPIO computations. The type class specifies a DSL for writing portable GPIO programs, and instances of the type class provide the interpreter needed to run these programs on a particular GPIO platform.In the type signature, hx represents a (platform-dependent) abstract pin handle for operating on opened pins. It is analogous to a file handle.#Active-high versus active-low logicThe DSL supports both  active-high and  active-low logic. That is, the  active level% of a GPIO pin can be configured as   or  . If a pin's active level is  , then for that pin, a  of  7 corresponds to a "high" physical signal level, and a  of e corresponds to a "low" physical signal level. The converse is true when the pin's active level is  .Despite the potential confusion, the advantage of supporting active-low logic is that you can, if you choose, write your program in terms of "positive" logic (where   always means "on" and  always means "off"), and, with the same program, interface with either positive (active-high) or negative (active-low) logic simply by setting the pin's active level before running the program.In the documentation for this package, whenever you see a reference to a "pin value" or "signal level," unless otherwise noted, we mean the logical value or level, not the physical% value or level; that is, we mean the abstract notion of the pin being "on" or "off," independent of the voltage level seen on the physical pin. If the pin is configured as active-high, then the logical and physical values are one and the same; if not, they are the inverse of each other.oNote that the active-high/active-low setting is per-pin; each pin's active level is independent of the others.Not all platforms natively support active-low logic. On platforms without native support, the platform interpreter will invert values (both read and written) in software when a pin is configured as active-low.0Get a list of available GPIO pins on the system.This command makes a best-effort attempt to find the available pins, but some systems may not make the complete list available at runtime. Therefore, there may be more pins available than are returned by this action.Query the pin's capabilities.-Open a pin for use and return a handle to it.Note that on some platforms (notably Linux), pin handles are global resources and it is, strictly speaking, an error to attempt to open a pin which has already been opened. However, because there is generally no way to perform an atomic "only open the pin if it hasn't already been opened" operation on such platforms, this action will squash that particular error on those platforms and return the global handle anyway, without making any other state changes to the already-opened pin.)Keep in mind, however, that on these platforms where pin handles are global resources, closing one pin handle will effectively invalidate all other handles for the same pin. Be very careful to coordinate the opening and closing of pins if you are operating on the same pin in multiple threads.kClose the pin; i.e., indicate to the system that you no longer intend to use the pin via the given handle._Note that on some platforms (notably Linux), pin handles are global resources and it is, strictly speaking, an error to attempt to close a pin which has already been closed via another handle to the same pin. However, this action will squash that error on those platforms and will simply return without making any changes to the GPIO environment.[Keep in mind, however, that on these platforms where pin handles are global resources, opening multiple handles for the same pin and then closing one of those handles will render all other handles for the same pin invalid. Be very careful to coordinate the opening and closing of pins if you are operating on the same pin in multiple threads.MNote that there are also platforms (again, notably certain Linux systems) where some pins are effectively always open and cannot be closed. Invoking this action on such a pin will squash any error that occurs when attempting to close the pin, and the action will simply return without making any changes to the GPIO environment.-Get the pin's currently configured direction.Note that there is no setPinDirection_ action. You set the pin's direction indirectly by setting its input mode or output mode via  and , respectively.Rarely, a particular pin's direction may not be available in a cross-platform way. In these cases, calling this action is an error. In general, though, if the pin's capabilities indicate that it supports at least one  or !, it's safe to call this action.Get the pin's input mode.UIf the pin is not currently configured for input, it's an error to call this action.LSet the pin's input mode. This action will also set the pin's direction to .[It is an error to call this action if the given pin does not support the given input mode.Get the pin's output mode.VIf the pin is not currently configured for output, it's an error to call this action.WSet the pin's output mode and value. This action will also set the pin's direction to QIf the pin is already in output mode and you only want to change its value, use .\It is an error to call this action if the given pin does not support the given output mode.Read the pin's value.#Note that this action never blocks.Block the current thread until an event occurs on the pin which corresponds to the pin's current interrupt mode. Upon detection of the event, return the pin's value.ZIf the pin does not support interrupts, then this action's behavior is plaform-dependent.MIt is an error to call this action when the pin is not configured for input.Note: due to its interaction with the threading system, this action may behave differently across different implementations of Haskell. It has only been tested with GHC. (On GHC, you should compile any program that uses this action with the  -threaded option.)Same as y, except with a timeout, specified in microseconds. If no event occurs before the timeout expires, this action returns =; otherwise, it returns the pin's signal level wrapped in a .AIf the timeout value is negative, this action behaves just like .[If the pin does not support interrupts, then this action's behavior is platform-dependent.MIt is an error to call this action when the pin is not configured for input.Note: due to its interaction with the threading system, this action may behave differently across different implementations of Haskell. It has only been tested with GHC. (On GHC, you should compile any program that uses this action with the  -threaded option.)Set the pin's output value.NIt is an error to call this action when the pin is not configured for output.EToggle the pin's output value and return the pin's new output value.NIt is an error to call this action when the pin is not configured for output.Get the pin's interrupt mode.LIf the pin does not support interrupts, it is an error to call this action. (Note that  and H are relative to the pin's active level; i.e., they refer to the pin's logical/ signal edges, not its physical signal edges.)JSet the pin's interrupt mode (only when the pin is configured for input).6A pin's interrupt mode determines the behavior of the  and  actions. Those actions will block the current thread on an input pin until a particular event occurs on that pin's signal waveform: a low-to-high transition (), a high-to-low transition (), or any change of level ().3You can also disable interrupts on the pin so that X will block the current thread indefinitely (or until a timer expires, in the case of ). This functionality is useful when, for example, one thread is dedicated to servicing interrupts on a pin, and another thread wants to mask interrupts on that pin for some period of time.wSome pins (or even some GPIO platforms) may not support interrupts. In such cases, it is an error to call this action.AIt is an error to use this action on a pin configured for output.Get the pin's active level.Set the pin's active level.;Toggle the pin's active level. Returns the pin's new level.Exception-safe pin management. opens a pin using  and passes the handle to the given GPIO computation. Upon completion of the computation, or an exception occuring within the computation,  closes the handle using s and then propagates the result, either by returning the value of the computation or by re-raising the exception.Like  , but for /s. Sets the pin's input mode to the specified  value.)If the optional active level argument is , then the pin's active level is unchanged from its current state. Otherwise, the pin's active level is set to the specified level.It is an error to call this action if the pin cannot be configured for input, or if it does not support the specified input mode.Like .Like .Like .Like .Like .Like  , but for Gs. The pin is opened for input, is input mode is set to the specified 8 value, and its interrupt mode is set to the specified  value.)If the optional active level argument is , then the pin's active level is unchanged from its current state. Otherwise, the pin's active level is set to the specified level.DIt is an error to call this action if any of the following are true:'The pin cannot be configured for input.2The pin does not support the specified input mode.$The pin does not support interrupts.Like .Like .Like .Like .Like .Like .Like .Like .Like .Like  , but for 0s. Sets the pin's output mode to the specified  value.The  argument specifies the pin's initial output value. It is relative to the active level argument, or to the pin's current active level if the active level argument is .It is an error to call this action if the pin cannot be configured for output, or if it does not support the specified output mode.Like .Like .Like .Like .Like .Like .Like .DV  !"#()V!"#    ()+Monads for Linux sysfs GPIO operations(c) 2016, Drew HessBSD3Drew Hess <src@drewhess.com> experimental non-portable Trustworthy<=IS[An instance of I which translates actions in that monad to operations on Linux's native sysfs GPIO interface.The sysfsB pin handle type. Currently it's just a newtype wrapper around a !. The constructor is exported for convenience, but note that the implementation may change in future versions of the package.CA type class for monads which implement (or mock) low-level Linux sysfs GPIO operations.Equivalent to  .Equivalent to  .Equivalent to  .Equivalent to .Equivalent to .sysfsv control files which are global shared resources may be written simultaneously by multiple threads. This is fine -- sysfs# can handle this -- but Haskell's  cannot, as it locks the file and prevents multiple writers. We don't want this behavior, so we use low-level operations to get around it.Poll a sysfs& file for reading, as in POSIX.1-2001 poll(2).LNote that the implementation of this action is only guaranteed to work for sysfsi files, which have a peculiar way of signaling readiness for reads. Do not use it for any other purpose.Test whether the sysfs GPIO filesystem is available.)Test whether the pin is already exported.Export the given pin.Note that, if the pin is already exported, this is not an error; in this situation, the pin remains exported and its state unchanged.Export the given pin.Note that, unlike o, it's an error to call this action to export a pin that's already been exported. This is the standard Linux sysfs GPIO behavior.Unexport the given pin.Note that, if the pin is already unexported or cannot be unexported, this is not an error. In this situation, the pin remains exported and its state unchanged.Unexport the given pin.Note that, unlike h, it is an error to call this action if the pin is not currently exported. This is the standard Linux sysfs GPIO behavior.4Test whether the pin's direction can be set via the sysfs GPIO filesystem. (Some pins have a hard-wired direction, in which case their direction must be determined by some other mechanism, as the  direction) attribute does not exist for such pins.)Read the pin's direction.5It is an error to call this action if the pin has no  direction attribute.Set the pin's direction.5It is an error to call this action if the pin has no  direction attribute.Note that, in Linux sysfs& GPIO, changing a pin's direction to out will also set its physical signal level to low. NB: in Linux sysfsj, if an input pin is cofigured for edge- or level-triggered reads, it's an error to set its direction to outO. However, this action will handle that case gracefully by setting the pin's edge attribute to none( before setting the pin's direction to out.KPins whose direction can be set may be configured for output by writing a  to their  direction attribute, such that the given value will be driven on the pin as soon as it's configured for output. This enables glitch-free output configuration, assuming the pin is currently configured for input, or some kind of tri-stated or floating high-impedance mode.5It is an error to call this action if the pin has no  direction attribute.*NB: for some unfathomable reason, writing high or low to a pin's  direction attribute sets its physical8 signal level; i.e., it ignores the value of the pin's  active_lowN attribute. Contrast this behavior with the behavior of writing to the pin's value3 attribute, which respects the value of the pin's  active_low attribute and sets the pin's logical signal level.*Rather than slavishly following the Linux sysfsh GPIO spec, we choose to be consistent by taking into account the pin's active level when writing the  direction! attribute. In other words, the  argument to this action is the logicalj signal level that will be set on the pin. If you're using this action to program directly to the Linux sysfsD GPIO interface and expecting things to behave as they do with raw sysfs% GPIO operations, keep this in mind!Read the pin's signal level.<Note that this action never blocks, regardless of the pin's edge attribute setting.A blocking version of e. The current thread will block until an event occurs on the pin as specified by the pin's current edge attribute setting.If the pin has no edgea attribute, then this action's behavior is undefined. (Most likely, it will block indefinitely.)Same as , except that a timeout value, specified in microseconds, is provided. If no event occurs before the timeout expires, this action returns 6; otherwise, it returns the pin's value wrapped in a .AIf the timeout value is negative, this action behaves just like .;When specifying a timeout value, be careful not to exceed .If the pin has no edge| attribute, then this action's behavior is undefined. (Most likely, it will time out after the specified delay and return .)NB: the curent implementation of this action limits the timeout precision to 1 millisecond, rather than 1 microsecond as the timeout parameter implies. Set the pin's signal level.MIt is an error to call this action if the pin is configured as an input pin. Test whether the pin has an edgeX attribute, i.e., whether it can be configured for edge- or level-triggered interrupts. Read the pin's edge attribute.7It is an error to call this action when the pin has no edge attribute. Write the pin's edge attribute.7It is an error to call this action when the pin has no edge6 attribute, or when the pin is configured for output. Read the pin's  active_low attribute.Write the pin's  active_low attribute.3Return a list of all pins that are exposed via the sysfs GPIO filesystem. Note that the returned list may omit some pins that are available on the host but which, for various reasons, are not exposed via the sysfs GPIO filesystem.9     "     "     .     Linux sysfs GPIO operations in IO(c) 2016, Drew HessBSD3Drew Hess <src@drewhess.com> experimental non-portable Trustworthy IS[2An instance of  which runs A operations in IO. This instance must be run on an actual Linux sysfs9 GPIO filesystem and will fail in any other environment.Interactions with threadslSome parts of this implementation use the Haskell C FFI, and may block on C I/O operations. (Specifically,  will block in the C FFI until its event is triggered.) When using this implementation with GHC, you should compile your program with the  -threadedp option, so that threads performing these blocking operations do not block other Haskell threads in the system.?Note that the C FFI bits in this implementation are marked as  interruptibleC, so that, on versions of GHC later than 7.8.1, functions such as S will work properly when targeting a Haskell thread that uses this implementation.(On Haskell implementations other than GHC, the threading implications are unknown; see the implementation's notes on how its threading system interacts with the C FFI.)2345623423423456GPIO in Linux via the sysfs filesystem(c) 2016, Drew HessBSD3Drew Hess <src@drewhess.com> experimental non-portableSafeGA specialization of " which runs GPIO computations in  via sysfs.HRun GPIO computations in  via sysfs.GH@rvstuwxyz{|}~     234GHAGH234     rstuvwxyz{|}~GH Linux GPIO(c) 2016, Drew HessBSD3Drew Hess <src@drewhess.com> experimental non-portableSafe@rvstuwxyz{|}~     234GHA mock MonadSysfs instance.(c) 2016, Drew HessBSD3Drew Hess <src@drewhess.com> experimental non-portable Trustworthy0I[1I&Exceptions that can be thrown by mock sysfs filesystem operations.Note that, as much as is reasonably possible, when an error occurs, the mock filesystem implementation throws the same exception as would occur in an actual sysfs filesystem (i.e., Rs). However, in a few cases, there are exceptions that are specific to the mock sysfs$ implementation; in these cases, a I is thrown.J*The user has defined defined at least two U:s with the same pin number, which is an invalid conditionK+An internal error has occurred in the mock sysfsg interpreter, something which should "never happen" and should be reported to the package maintainer.LLike N , but wraps  so that you can mix 6 actions and GPIO actions in a mock GPIO environment.MThe simplest possible (-enabled) mock sysfs monad. Like O, but allows you to mix  operations into your sysfs computations, as well.NB: this monad cannot1 run GPIO computations; its only use is to mock sysfs) operations on an extremely limited mock sysfs simulator.8You probably do not want to use this monad; see either N or L-, which adds GPIO computations to this mock sysfs environment.NA specialization of 7 which runs (pure, fake) GPIO computations via a mock sysfs.O"The simplest possible (pure) mock sysfs monad.NB: this monad cannot1 run GPIO computations; its only use is to mock sysfs) operations on an extremely limited mock sysfs simulator.8You probably do not want to use this monad; see either N or L-, which adds GPIO computations to this mock sysfs environment.P$A monad transformer which adds mock sysfs! computations to an inner monad m.S7The global state of a mock Linux GPIO subsystem with a sysfs% interface. It consists of the mock sysfs@ GPIO filesystem state, along with the state of every mock pin.An actual Linux sysfs GPIO filesystem is not like a general-purpose filesystem. The user cannot create files or directories directly; they can only be created (or modified) via prescribed operations on special conrol files, which are themselves created by the kernel.oLikewise, the kernel and hardware platform together determine which GPIO pins are exposed to the user via the sysfs GPIO filesystem.&To preserve the illusion of an actual sysfs GPIO filesystem, the S type is opaque and can only be manipulated via the handful of actions that are implemented in this module. These actions have been designed to keep the internal state of the mock sysfsO GPIO filesystem consistent with the behavior that would be seen in an actual sysfs GPIO filesystem.EThe high/low signal level on a real GPIO pin can, of course, be manipulated by the circuit to which the pin is conected. A future version of this implementation may permit the direct manipulation of mock pin values in order to simulate simple circuits, but currently the only way to manipulate pin state is via the mock sysfs GPIO filesystem.T!A type alias for a strict map of ! to its Z.U!A mock GPIO "chip." In the Linux sysfsA GPIO filesystem, a GPIO chip is a set of one or more GPIO pins.Note that the Y0 list is used to construct the pin state for a S (see f ). For each Zz value in the list, a mock pin will be created in the mock filesystem such that, when that pin is exported, its path is /sys/class/gpio/gpioN, where N is _base + the pin's index in the Y list.W,The name given to the chip in the filesystemX&The pin number of the chip's first pinYThe pins' initial statesZ A mock pin.\The pin's direction]3Is the pin's direction visible from the filesystem?^$Is the pin configured as active-low?_ The pin's physical signal level`'The pin's interrupt mode (if supported)aLinux sysfsd GPIO natively supports active-low logic levels. A pin's "active" level is controlled by the pin's  active_low- attribute. The pin's value relative to its  active_low attribute is called its  logical value6. This function returns the mock pin's logical value. logicalValue defaultMockPinStateLow2logicalValue defaultMockPinState { _value = High }High6logicalValue defaultMockPinState { _activeLow = True }HighElogicalValue defaultMockPinState { _activeLow = True, _value = High }LowbThis function sets the Z signal level to the given logical value.1_value $ setLogicalValue High defaultMockPinStateHighG_value $ setLogicalValue High defaultMockPinState { _activeLow = True }Lowc#Default initial state of mock pins.defaultMockPinStaterMockPinState {_direction = Out, _userVisibleDirection = True, _activeLow = False, _value = Low, _edge = Just None}dGet the pin map from a S.e The initial S, representing a sysfs filesystem with no pins.f Run a mock sysfs computation in monad m) with an initial mock world and list of UHs; and return a tuple containing the computation's value and the final S5. If an exception occurs in the mock computation, a I is thrown.$Before running the computation, the S> is populated with the GPIO pins as specified by the list of U/s. If any of the chips' pin ranges overlap, a I is thrown.JTypically, you will only need this action if you're trying to mock Linux sysfsR GPIO computations using a custom monad transformer stack. For simple cases, see l or r.gLike f+, but returns only the computation's value.hLike f, but returns only the final S.iA pure version of f which returns errors in a ?, and both the computation's value and the final state of the S in a .Hlet mockChip = MockGpioChip "chip0" 0 (replicate 16 defaultMockPinState)Yfst <$> runSysfsMock (getDirectoryContents "/sys/class/gpio") initialMockWorld [mockChip]'Right ["gpiochip0","export","unexport"][runSysfsMock (getDirectoryContents "/sys/class/does_not_exist") initialMockWorld [mockChip]@Left /sys/class/does_not_exist: Mock.Internal.cd: does not existjLike i+, but returns only the computation's value.kLike i, but returns only the final S.lRun a N5 computation with an initial mock world and list of UHs, and return a tuple containing the computation's value and the final SG. Any exceptions that occur in the mock computation are returned as a  value.$Before running the computation, the S> is populated with the GPIO pins as specified by the list of U/s. If any of the chips' pin ranges overlap, a I is returned in a  value.import System.GPIO.MonadHlet mockChip = MockGpioChip "chip0" 0 (replicate 16 defaultMockPinState)9fst <$> runSysfsGpioMock pins initialMockWorld [mockChip]mRight [Pin 0,Pin 1,Pin 2,Pin 3,Pin 4,Pin 5,Pin 6,Pin 7,Pin 8,Pin 9,Pin 10,Pin 11,Pin 12,Pin 13,Pin 14,Pin 15]Gfst <$> runSysfsGpioMock (openPin (Pin 32)) initialMockWorld [mockChip]Left InvalidPin (Pin 32)mLike l,, but returns only the computation's value.nLike l, but returns only the final S.oAn  version of f&. Errors are expressed as exceptions.Hlet mockChip = MockGpioChip "chip0" 0 (replicate 16 defaultMockPinState)[fst <$> runSysfsMockIO (getDirectoryContents "/sys/class/gpio") initialMockWorld [mockChip]!["gpiochip0","export","unexport"]]runSysfsMockIO (getDirectoryContents "/sys/class/does_not_exist") initialMockWorld [mockChip]J*** Exception: /sys/class/does_not_exist: Mock.Internal.cd: does not existpLike o+, but returns only the computation's value.qLike o, but returns only the final S.rRun a L5 computation with an initial mock world and list of UHs, and return a tuple containing the computation's value and the final S.$Before running the computation, the S> is populated with the GPIO pins as specified by the list of U/s. If any of the chips' pin ranges overlap, a I is thrown.import System.GPIO.MonadHlet mockChip = MockGpioChip "chip0" 0 (replicate 16 defaultMockPinState);fst <$> runSysfsGpioMockIO pins initialMockWorld [mockChip]g[Pin 0,Pin 1,Pin 2,Pin 3,Pin 4,Pin 5,Pin 6,Pin 7,Pin 8,Pin 9,Pin 10,Pin 11,Pin 12,Pin 13,Pin 14,Pin 15]Ifst <$> runSysfsGpioMockIO (openPin (Pin 32)) initialMockWorld [mockChip]"*** Exception: InvalidPin (Pin 32)sLike r,, but returns only the computation's value.tLike r, but returns only the final S.uECheck whether the specified directory exists in the mock filesystem.v?Check whether the specified file exists in the mock filesystem.wLGet a directory listing for the specified directory in the mock filesystem.x?Read the contents of the specified file in the mock filesystem.y@Write the contents of the specified file in the mock filesystem.z7For the mock filesystem, this action is equivalent to y.{]Polling is not implemented for the mock filesystem, so this action always returns the value 1.%The initial directory structure of a sysfs GPIO filesystem. The initial sysfs filesystem zipper.JIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}3IKJLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{3SZ[\]^_`cabUVWXYTdePQRfghNlmnLrstIJKOijkMopquvwxyz{9IJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|} Safe:Run a hpio, program on a mock system with 17 GPIO pins. *  !"*!"  .Top-level re-exports for writing GPIO programs(c) 2016, Drew HessBSD3Drew Hess <src@drewhess.com> experimental non-portableSafe  !"#()rvstuwxyz{|}~     234GH !"#$%&''()*+,-./01234567789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~      !"#$%&'()*+,-./0123456789:;<=>?@@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_``abcddefghijklmnopqrstuvwxyz{|} ~                             "                    ^        #hpio-0.8.0.2-8VNjAlKBhjF3KbOZQGjX27System.GPIO.TypesSystem.GPIO.Linux.Sysfs.TypesSystem.GPIO.Linux.Sysfs.UtilSystem.GPIO.MonadSystem.GPIO.Linux.Sysfs.MonadSystem.GPIO.Linux.Sysfs.IOSystem.GPIO.Linux.SysfsSystem.GPIO.Linux.Sysfs.MockSystem.GPIO.Tutorial%System.GPIO.Linux.Sysfs.Mock.InternalSystem.IO.ErrorIOErrorSystem.DirectorydoesDirectoryExist doesFileExistgetDirectoryContentsData.ByteStringreadFile writeFileControl.ConcurentthrowToSystem.GPIO.Linux System.GPIOSomeGpioExceptionPinInterruptModeDisabled RisingEdge FallingEdgeLevelPinValueLowHighPinActiveLevel ActiveLow ActiveHigh PinDirectionInOutPinCapabilities _inputModes _outputModes _interrupts PinOutputMode OutputDefaultOutputPushPullOutputOpenDrainOutputOpenDrainPullUpOutputOpenSourceOutputOpenSourcePullDown PinInputMode InputDefault InputFloating InputPullUp InputPullDownPin pinNumberinvertDirection invertValue valueToBool boolToValuegpioExceptionToExceptiongpioExceptionFromException$fExceptionSomeGpioException$fShowSomeGpioException$fArbitraryPinInterruptMode$fArbitraryPinValue$fFiniteBitsPinValue$fBitsPinValue$fArbitraryPinActiveLevel$fArbitraryPinDirection$fArbitraryPin $fBoundedPin $fEnumPin$fEqPin $fDataPin$fOrdPin $fReadPin$fIxPin $fShowPin $fGenericPin$fBoundedPinInputMode$fEnumPinInputMode$fEqPinInputMode$fOrdPinInputMode$fDataPinInputMode$fReadPinInputMode$fShowPinInputMode$fGenericPinInputMode$fBoundedPinOutputMode$fEnumPinOutputMode$fEqPinOutputMode$fOrdPinOutputMode$fDataPinOutputMode$fReadPinOutputMode$fShowPinOutputMode$fGenericPinOutputMode$fEqPinCapabilities$fShowPinCapabilities$fGenericPinCapabilities$fBoundedPinDirection$fEnumPinDirection$fEqPinDirection$fDataPinDirection$fOrdPinDirection$fReadPinDirection$fShowPinDirection$fIxPinDirection$fGenericPinDirection$fBoundedPinActiveLevel$fEnumPinActiveLevel$fEqPinActiveLevel$fDataPinActiveLevel$fOrdPinActiveLevel$fReadPinActiveLevel$fShowPinActiveLevel$fIxPinActiveLevel$fGenericPinActiveLevel$fBoundedPinValue$fEnumPinValue $fEqPinValue$fDataPinValue $fOrdPinValue$fReadPinValue$fShowPinValue $fIxPinValue$fGenericPinValue$fBoundedPinInterruptMode$fEnumPinInterruptMode$fEqPinInterruptMode$fDataPinInterruptMode$fOrdPinInterruptMode$fReadPinInterruptMode$fShowPinInterruptMode$fGenericPinInterruptModeSysfsExceptionSysfsNotPresent SysfsErrorSysfsPermissionDeniedPermissionDeniedInvalidOperationAlreadyExported InvalidPin NotExportedUnsupportedInputModeUnsupportedOutputModeNoDirectionAttributeNoEdgeAttributeUnexpectedDirectionUnexpectedValueUnexpectedEdgeUnexpectedActiveLowUnexpectedContents InternalError SysfsEdgeNoneRisingFallingBothtoPinInterruptMode toSysfsEdge$fExceptionSysfsException$fArbitrarySysfsEdge$fBoundedSysfsEdge$fEnumSysfsEdge $fEqSysfsEdge$fDataSysfsEdge$fOrdSysfsEdge$fReadSysfsEdge$fShowSysfsEdge$fGenericSysfsEdge$fEqSysfsException$fShowSysfsException sysfsPathexportFileNameunexportFileName pinDirNamepinActiveLowFileNamepinDirectionFileNamepinEdgeFileNamepinValueFileNamepinDirectionToBSpinDirectionValueToBSbsToPinDirection sysfsEdgeToBS bsToSysfsEdge pinValueToBS bsToPinValue activeLowToBS bsToActiveLowintToBSbsToInt OutputPin InterruptPinInputPin MonadGpiopinspinCapabilitiesopenPinclosePingetPinDirectiongetPinInputModesetPinInputModegetPinOutputModesetPinOutputModereadPinpollPinpollPinTimeoutwritePin togglePingetPinInterruptModesetPinInterruptModegetPinActiveLevelsetPinActiveLeveltogglePinActiveLevelwithPin withInputPin readInputPingetInputPinInputModegetInputPinActiveLevelsetInputPinActiveLeveltoggleInputPinActiveLevelwithInterruptPinreadInterruptPinpollInterruptPinpollInterruptPinTimeoutgetInterruptPinInputModegetInterruptPinInterruptModesetInterruptPinInterruptModegetInterruptPinActiveLevelsetInterruptPinActiveLeveltoggleInterruptPinActiveLevel withOutputPinwriteOutputPintoggleOutputPin readOutputPingetOutputPinOutputModegetOutputPinActiveLevelsetOutputPinActiveLeveltoggleOutputPinActiveLevel$fMonadGpiohWriterT$fMonadGpiohWriterT0$fMonadGpiohStateT$fMonadGpiohStateT0$fMonadGpiohRWST$fMonadGpiohRWST0$fMonadGpiohReaderT$fMonadGpiohMaybeT$fMonadGpiohListT$fMonadGpiohExceptT$fMonadGpiohCatchT$fMonadGpiohContT$fMonadGpiohIdentityT $fEqInputPin$fShowInputPin$fEqInterruptPin$fShowInterruptPin $fEqOutputPin$fShowOutputPin SysfsGpioT runSysfsGpioT PinDescriptor_pin MonadSysfsunlockedWriteFilepollFilesysfsIsPresent pinIsExported exportPinexportPinChecked unexportPinunexportPinCheckedpinHasDirectionreadPinDirectionwritePinDirectionwritePinDirectionWithValue readPinValue pollPinValuepollPinValueTimeout writePinValue pinHasEdge readPinEdge writePinEdgereadPinActiveLowwritePinActiveLow availablePins"$fMonadGpioPinDescriptorSysfsGpioT$fMonadTransSysfsGpioT$fMonadSysfsWriterT$fMonadSysfsWriterT0$fMonadSysfsStateT$fMonadSysfsStateT0$fMonadSysfsRWST$fMonadSysfsRWST0$fMonadSysfsReaderT$fMonadSysfsMaybeT$fMonadSysfsListT$fMonadSysfsExceptT$fMonadSysfsCatchT$fMonadSysfsContT$fMonadSysfsIdentityT$fShowPinDescriptor$fEqPinDescriptor$fOrdPinDescriptor$fFunctorSysfsGpioT$fAlternativeSysfsGpioT$fApplicativeSysfsGpioT$fMonadSysfsGpioT$fMonadFixSysfsGpioT$fMonadPlusSysfsGpioT$fMonadThrowSysfsGpioT$fMonadCatchSysfsGpioT$fMonadMaskSysfsGpioT$fMonadContSysfsGpioT$fMonadIOSysfsGpioT$fMonadReaderSysfsGpioT$fMonadErrorSysfsGpioT$fMonadWriterSysfsGpioT$fMonadStateSysfsGpioT$fMonadRWSSysfsGpioTSysfsIOT runSysfsIOT$fMonadSysfsSysfsIOT$fMonadTransSysfsIOT$fFunctorSysfsIOT$fAlternativeSysfsIOT$fApplicativeSysfsIOT$fMonadSysfsIOT$fMonadFixSysfsIOT$fMonadPlusSysfsIOT$fMonadThrowSysfsIOT$fMonadCatchSysfsIOT$fMonadMaskSysfsIOT$fMonadContSysfsIOT$fMonadIOSysfsIOT$fMonadReaderSysfsIOT$fMonadErrorSysfsIOT$fMonadWriterSysfsIOT$fMonadStateSysfsIOT$fMonadRWSSysfsIOT SysfsGpioIOrunSysfsGpioIOMockFSExceptionGpioChipOverlapSysfsGpioMockIO SysfsMockIO SysfsGpioMock SysfsMock SysfsMockT unSysfsMockT MockWorldMockPins MockGpioChip_label_base_initialPinStates MockPinState _direction_userVisibleDirection _activeLow_value_edge logicalValuesetLogicalValuedefaultMockPinState mockWorldPinsinitialMockWorld runSysfsMockTevalSysfsMockTexecSysfsMockT runSysfsMock evalSysfsMock execSysfsMockrunSysfsGpioMockevalSysfsGpioMockexecSysfsGpioMockrunSysfsMockIOevalSysfsMockIOexecSysfsMockIOrunSysfsGpioMockIOevalSysfsGpioMockIOexecSysfsGpioMockIO$fExceptionMockFSException$fMonadSysfsSysfsMockT$fShowMockPinState$fEqMockPinState$fShowMockGpioChip$fEqMockGpioChip$fShowMockWorld $fEqMockWorld$fFunctorSysfsMockT$fAlternativeSysfsMockT$fApplicativeSysfsMockT$fMonadSysfsMockT$fMonadFixSysfsMockT$fMonadPlusSysfsMockT$fMonadThrowSysfsMockT$fMonadCatchSysfsMockT$fMonadMaskSysfsMockT$fMonadContSysfsMockT$fMonadIOSysfsMockT$fMonadReaderSysfsMockT$fMonadErrorSysfsMockT$fMonadWriterSysfsMockT$fMonadStateSysfsMockT$fMonadTransSysfsMockT$fShowMockFSException$fEqMockFSExceptionTutorialReaderGpioIO TutorialEnv runTutorialghc-prim GHC.TypesIntBoolbase GHC.Exception SomeException MockFSZipper_cwd_crumbs MockFSCrumb_node_pred_succ DirectoryDirNode _dirNodeName_filesFile _fileName _fileTypeFileTypeConstExportUnexportValue DirectionEdgeName directorydirNamefilesdirNodesubdirsuproot pathFromRoot findFile'findFilefindDir'findDir isValidNamecdmkdirmkfilermfilermdirbytestring-0.10.8.1Data.ByteString.Internal ByteStringGHC.BaseNothingFalseTrueData.ByteString.Char8readIntJust _outputHandle_interruptHandle _inputHandlemaybeSetPinActiveLevelGHC.EnummaxBoundactiveLevelToActiveLowactiveLowToActiveLevel resetEdgewriteDirectionreadIntFromFilepinRangeisInvalidArgumentErrorTypeisInvalidArgumentError pollSysfsunlockedWriteFileIO pollFileIOIOGHC.IO.Exception Data.EitherLeftRight sysfsRootsysfsRootZipper_zipper_pins getZipper putZippergetPinspinStateputPins putPinStatemakeFileSystemmakeChipaddPinsaddPinpushdfileAt _initialValue_delay _iterationschip0chip1runTutorialReaderGpioIO