<commit_before>// Copyright (c) 2017-2018 <NAME>
//
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the "Software"),
// to deal in the Software without restriction, including without limitation
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
// and/or sell copies of the Software, and to permit persons to whom the
// Software is furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE.

//! Interface for the Raspberry Pi's BCM283x GPIO peripheral.
//!
//! The GPIO peripheral interface accesses the appropriate memory registers
//! through either the `/dev/gpiomem` device, or `/dev/mem` for distributions
//! where the former isn't available.
//!
//! On a typical up-to-date Raspbian installation, any user that's part of the
//! `gpio` group can access `/dev/gpiomem`, while `/dev/mem` requires
//! superuser privileges.
//!
//! Pins are addressed by their BCM GPIO pin numbers, rather than their
//! physical location.
//!
//! By default, all pins are reset to their original state when `Gpio` goes out
//! of scope. Use `set_clear_on_drop(false)` to disable this behavior. Note that
//! drop methods aren't called when a program is abnormally terminated (for
//! instance when a SIGINT isn't caught).

#![allow(dead_code)]

use num::FromPrimitive;
use std::error;
use std::fmt;
use std::io;
use std::result;
use std::thread::sleep;
use std::time::Duration;

mod interrupt;
mod mem;
mod sysfs;

// Maximum GPIO pins on the BCM2835. The actual number of pins exposed through the Pi's GPIO header
// depends on the model.
const GPIO_MAX_PINS: u8 = 54;
// Offset in 32-bit units
const GPIO_OFFSET_GPFSEL: usize = 0;
const GPIO_OFFSET_GPSET: usize = 7;
const GPIO_OFFSET_GPCLR: usize = 10;
const GPIO_OFFSET_GPLEV: usize = 13;
const GPIO_OFFSET_GPPUD: usize = 37;
const GPIO_OFFSET_GPPUDCLK: usize = 38;

quick_error! {
    #[derive(Debug)]
/// Errors that can occur when accessing the GPIO peripheral.
    pub enum Error {
/// Invalid GPIO pin number.
///
/// The GPIO pin number is not accessible on this Raspberry Pi model.
        InvalidPin(pin: u8) { description("invalid GPIO pin number") }
/// Unknown GPIO pin mode.
///
/// The GPIO pin is set to an unknown mode.
        UnknownMode(mode: u8) { description("unknown mode") }
/// Unknown SoC.
///
/// Based on the output of `/proc/cpuinfo`, it wasn't possible to identify the Raspberry Pi's SoC.
        UnknownSoC { description("unknown SoC") }
/// Unable to find `/dev/gpiomem` in the filesystem.
///
/// Try upgrading to a more recent version of Raspbian (or
/// equivalent) that implements `/dev/gpiomem`.
        DevGpioMemNotFound { description("/dev/gpiomem not found") }
/// Permission denied when opening `/dev/gpiomem` for read/write access.
///
/// Make sure the user has read and write access to `/dev/gpiomem`.
/// Common causes are either incorrect file permissions on
/// `/dev/gpiomem`, or the user isn't part of the gpio group.
        DevGpioMemPermissionDenied { description("/dev/gpiomem insufficient permissions") }
/// `/dev/gpiomem` IO error.
        DevGpioMemIoError(err: io::Error) {
            description(err.description())
            display("/dev/gpiomem IO error ({})", error::Error::description(err))
            cause(err)
        }
/// Unable to memory-map `/dev/gpiomem`.
        DevGpioMemMapFailed { description("/dev/gpiomem map failed") }
/// Unable to find `/dev/mem` in the filesystem.
        DevMemNotFound { description("/dev/mem not found") }
/// Permission denied when opening `/dev/mem` for read/write access.
///
/// Getting read and write access to `/dev/mem` is typically
/// accomplished by executing the program as a privileged user through
/// `sudo`. A better solution that doesn't require `sudo` would be to
/// upgrade to a version of Raspbian that implements `/dev/gpiomem`.
        DevMemPermissionDenied { description("/dev/mem insufficient permissions") }
/// `/dev/mem` IO error.
        DevMemIoError(err: io::Error) {
            description(err.description())
            display("/dev/mem IO error ({})", error::Error::description(err))
            cause(err)
        }
/// Unable to memory-map `/dev/mem`.
        DevMemMapFailed { description("/dev/mem map failed") }
/// Permission denied when opening both `/dev/gpiomem` and `/dev/mem` for read/write access.
///
/// Make sure the user has read and write access to `/dev/gpiomem`.
/// Common causes are either incorrect file permissions on `/dev/gpiomem`, or
/// the user isn't part of the gpio group.
///
/// Getting read and write access to `/dev/mem` is typically
/// accomplished by executing the program as a privileged user through
/// `sudo`. A better solution that doesn't require `sudo` would be to
/// upgrade to a version of Raspbian that implements `/dev/gpiomem`.
        PermissionDenied { description("/dev/gpiomem and /dev/mem insufficient permissions") }
/// GPIO isn't initialized.
///
/// You should normally only see this error when you call a method after
/// running `cleanup()`.
        NotInitialized { description("not initialized") }
/// Interrupt error.
        Interrupt(err: interrupt::Error) { description(err.description()) from() }<commit_msg>Re-export private self::interrupt::Error<commit_after>// Copyright (c) 2017-2018 <NAME>
//
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the "Software"),
// to deal in the Software without restriction, including without limitation
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
// and/or sell copies of the Software, and to permit persons to whom the
// Software is furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE.

//! Interface for the Raspberry Pi's BCM283x GPIO peripheral.
//!
//! The GPIO peripheral interface accesses the appropriate memory registers
//! through either the `/dev/gpiomem` device, or `/dev/mem` for distributions
//! where the former isn't available.
//!
//! On a typical up-to-date Raspbian installation, any user that's part of the
//! `gpio` group can access `/dev/gpiomem`, while `/dev/mem` requires
//! superuser privileges.
//!
//! Pins are addressed by their BCM GPIO pin numbers, rather than their
//! physical location.
//!
//! By default, all pins are reset to their original state when `Gpio` goes out
//! of scope. Use `set_clear_on_drop(false)` to disable this behavior. Note that
//! drop methods aren't called when a program is abnormally terminated (for
//! instance when a SIGINT isn't caught).

#![allow(dead_code)]

use num::FromPrimitive;
use std::error;
use std::fmt;
use std::io;
use std::result;
use std::thread::sleep;
use std::time::Duration;

mod interrupt;
mod mem;
mod sysfs;

pub use self::interrupt::Error as InterruptError;

// Maximum GPIO pins on the BCM2835. The actual number of pins exposed through the Pi's GPIO header
// depends on the model.
const GPIO_MAX_PINS: u8 = 54;
// Offset in 32-bit units
const GPIO_OFFSET_GPFSEL: usize = 0;
const GPIO_OFFSET_GPSET: usize = 7;
const GPIO_OFFSET_GPCLR: usize = 10;
const GPIO_OFFSET_GPLEV: usize = 13;
const GPIO_OFFSET_GPPUD: usize = 37;
const GPIO_OFFSET_GPPUDCLK: usize = 38;

quick_error! {
    #[derive(Debug)]
/// Errors that can occur when accessing the GPIO peripheral.
    pub enum Error {
/// Invalid GPIO pin number.
///
/// The GPIO pin number is not accessible on this Raspberry Pi model.
        InvalidPin(pin: u8) { description("invalid GPIO pin number") }
/// Unknown GPIO pin mode.
///
/// The GPIO pin is set to an unknown mode.
        UnknownMode(mode: u8) { description("unknown mode") }
/// Unknown SoC.
///
/// Based on the output of `/proc/cpuinfo`, it wasn't possible to identify the Raspberry Pi's SoC.
        UnknownSoC { description("unknown SoC") }
/// Unable to find `/dev/gpiomem` in the filesystem.
///
/// Try upgrading to a more recent version of Raspbian (or
/// equivalent) that implements `/dev/gpiomem`.
        DevGpioMemNotFound { description("/dev/gpiomem not found") }
/// Permission denied when opening `/dev/gpiomem` for read/write access.
///
/// Make sure the user has read and write access to `/dev/gpiomem`.
/// Common causes are either incorrect file permissions on
/// `/dev/gpiomem`, or the user isn't part of the gpio group.
        DevGpioMemPermissionDenied { description("/dev/gpiomem insufficient permissions") }
/// `/dev/gpiomem` IO error.
        DevGpioMemIoError(err: io::Error) {
            description(err.description())
            display("/dev/gpiomem IO error ({})", error::Error::description(err))
            cause(err)
        }
/// Unable to memory-map `/dev/gpiomem`.
        DevGpioMemMapFailed { description("/dev/gpiomem map failed") }
/// Unable to find `/dev/mem` in the filesystem.
        DevMemNotFound { description("/dev/mem not found") }
/// Permission denied when opening `/dev/mem` for read/write access.
///
/// Getting read and write access to `/dev/mem` is typically
/// accomplished by executing the program as a privileged user through
/// `sudo`. A better solution that doesn't require `sudo` would be to
/// upgrade to a version of Raspbian that implements `/dev/gpiomem`.
        DevMemPermissionDenied { description("/dev/mem insufficient permissions") }
/// `/dev/mem` IO error.
        DevMemIoError(err: io::Error) {
            description(err.description())
            display("/dev/mem IO error ({})", error::Error::description(err))
            cause(err)
        }
/// Unable to memory-map `/dev/mem`.
        DevMemMapFailed { description("/dev/mem map failed") }
/// Permission denied when opening both `/dev/gpiomem` and `/dev/mem` for read/write access.
///
/// Make sure the user has read and write access to `/dev/gpiomem`.
/// Common causes are either incorrect file permissions on `/dev/gpiomem`, or
/// the user isn't part of the gpio group.
///
/// Getting read and write access to `/dev/mem` is typically
/// accomplished by executing the program as a privileged user through
/// `sudo`. A better solution that doesn't require `sudo` would be to
/// upgrade to a version of Raspbian that implements `/dev/gpiomem`.
        PermissionDenied { description("/dev/gpiomem and /dev/mem insufficient permissions") }
/// GPIO isn't initialized.
///
/// You should normally only see this error when you call a method after
/// running `cleanup()`.
        NotInitialized { description("not initialized") }
/// Interrupt error.
        Interrupt(err: InterruptError) { description(err.description()) from() }
{'fraction_non_alphanumeric': 0.1160006744225257, 'fraction_numerical': 0.00539538020569887, 'mean_word_length': 3.316957787481805, 'pattern_counts': {'":': 0, '<': 5, '<?xml version=': 0, '>': 5, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '4762541', 'n_tokens_mistral': 3441, 'n_tokens_neox': 3238, 'n_words': 1407}