1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74
/*********************************************************************************************************************** * Copyright (c) 2019 by the authors * * Author: André Borrmann * License: Appache License 2.0 **********************************************************************************************************************/ #![doc(html_root_url = "https://docs.rs/ruspiro-gpio/0.2.1")] #![no_std] #![feature(asm)] //! # Raspberry Pi GPIO access abstraction //! //! This crate provide as simple to use and safe abstraction of the GPIO's available on the Raspberry Pi 3. The GPIO //! configuration requires access to MMIO registers with a specific memory base address. As this might differ between //! different models the right address is choosen based on the given ``ruspiro_pi3`` feature while compiling. //! //! # Usage //! //! The crate provides a singleton accessor to the GPIO peripheral and it's pin to be used in a safe manner like this: //! ``` //! use ruspiro_gpio::GPIO; //! //! fn demo() { //! GPIO.take_for(|gpio| { //! let pin = gpio.get_pin(17).unwrap(); // assuming we can always get this pin as it is not in use already //! pin.to_output().high(); // set this pin to high - this may lit a connected LED :) //! }); //! } //! ``` //! //! # Features //! //! - ``ruspiro_pi3`` is active by default and ensures the proper MMIO base memory address is used for Raspberry Pi 3 use ruspiro_singleton::Singleton; pub mod pin; pub use self::pin::*; /// Static "singleton" accessor to the GPIO peripheral pub static GPIO: Singleton<Gpio> = Singleton::<Gpio>::new(Gpio::new()); /// GPIO peripheral representation pub struct Gpio { used_pins: [bool;40], } impl Gpio { /// Get a new intance of the GPIO peripheral and do some initialization to ensure a valid state of all /// pins uppon initialization pub const fn new() -> Self { Gpio { used_pins: [false; 40], } } /// Get a new pin for further usage, the function of the pin is initially undefined/unknown /// Returns an Err(str) if the pin is already in use, otherwise an Ok(Pin) pub fn get_pin(&mut self, num: u32) -> Result<Pin<function::Unknown, pud::Unknown>, &'static str> { if self.used_pins[num as usize] { Err("requested pin already in use") } else { self.used_pins[num as usize] = true; Ok(Pin::<function::Unknown, pud::Unknown>::new(num)) } } pub fn free_pin(&mut self, num: u32) { // release the used pin // TODO: reset also pin function or other settings? if self.used_pins[num as usize] { self.used_pins[num as usize] = false; }; } }