dma_gpio is a library for pi's GPIO that uses DMA (Direct Memory Access) and PWM via DMA. By using DMA and interacting directly with hardware memory, it manages to be very fast (Max Raw Speed ≈ 1.6 MHz on Pi3) while having almost no CPU usage ( ~2%). This project was inspired by its predecessor projects in C, such as PiBits, pi-blaster and RPIO; however, this project bypasses L1 cache which the DMA Controller does not recognize, resulting in a slightly faster GPIO Speed.
pi module will have everything you need.
First, add the crate to the dependencies. ```no_run Cargo.toml
... [dependencies] dma_gpio = "0.1.5" ```
The easiest way to get started using this library is initializing a Board using BoardBuilder.
BoardBuilder will configure the default setting for the DMA, but manual configuration is also available (read more on this in BoardBuiler). When the Board is initialized, it recognizes which Pi-version it is running on, and interacts with the hardware memory accordingly.
Below example initializes the board using BoardBuilder with default configurations, set the PWM of gpio pins 21 and 22 to 25%, 50%, 75%, then 100% for 1 second each.
Make sure to run the binary file in sudo!!! ```norun use std::thread::sleep; use std::time::Duration; use dmagpio::pi::BoardBuilder;
fn main() { let mut board = BoardBuilder::new().buildwithpins(vec![21, 22]).unwrap(); board.print_info();
board.set_all_pwm(0.25).unwrap();
let sec = Duration::from_millis(1000);
sleep(millis);
board.set_all_pwm(0.5).unwrap();
sleep(millis);
board.set_all_pwm(0.75).unwrap();
sleep(millis);
board.set_all_pwm(1.0).unwrap();
sleep(millis);
}
```
There are two features you can enable in this crate: 'debug' and 'bindprocess'. To enable these features, write the dependency for this crate as shown below. ```norun Cargo.toml
... [dependencies] ...
[dependencies.dmagpio] version = "0.1.5" features = [debug, bindprocess] ```
By enabling this feature, the library will print out the process every step of the way. This feature will be useful when debugging. Also, after enabling this feature in Cargo.toml, you have to call enablelogger function to see the logs in the terminal. ```norun use std::thread::sleep; use std::time::Duration; use dma_gpio::pi::BoardBuilder;
fn main() { dmagpio::enablelogger(); let mut board = BoardBuilder::new().buildwithpins(vec![21, 22]).unwrap();
board.set_all_pwm(0.5).unwrap();
let sec = Duration::from_millis(2000);
sleep(millis);
}
```
This feature lets you access the picore module which only has one function bindprocesstolast. This function binds the process to the last core of the Pi. However, to use this function, you have to first install a C library called hwloc. Also, enabling debug feature will print out if you have correctly bound process to the last core. ```norun use std::thread::sleep; use std::time::Duration; use dmagpio::{pi::BoardBuilder, pi_core};
fn main() { dmagpio::enablelogger(); picore::bindprocesstolast(); let mut board = BoardBuilder::new().buildwithpins(vec![21, 22]).unwrap();
board.set_all_pwm(0.5).unwrap();
let sec = Duration::from_millis(2000);
sleep(millis);
} ```
Since compiling a rust project on a pi may take a very long time, it's often a good idea to cross-compile on your computer. Great resources for cross-compilations to Pi that I found helpful are rust-cross and this blog. For pi 2 and 3, use armv7-unknown-linux-gnueabihf, and, for pi 1 and zero, use armv6-unknown-linux-gnueabihf (if you can find one, that is).
For questions, please email to Jack.Y.L.Dev@gmail.com