Skip to content

Commit

Permalink
Merge pull request #23 from andrewdavidmackenzie/pigg-20
Browse files Browse the repository at this point in the history
Refactor of GPIO
  • Loading branch information
andrewdavidmackenzie authored May 15, 2024
2 parents eda2508 + 6da8626 commit 4c138b8
Show file tree
Hide file tree
Showing 10 changed files with 197 additions and 178 deletions.
15 changes: 0 additions & 15 deletions .github/workflows/build_and_test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -25,9 +25,6 @@ jobs:
profile: minimal
toolchain: stable

- name: install cross
run: cargo install cross --git https://github.com/cross-rs/cross

- name: make clippy
run: make clippy

Expand All @@ -47,24 +44,13 @@ jobs:
profile: minimal
toolchain: stable

- name: InstallLinuxDependencies
if: runner.os == 'Linux'
run: sudo apt-get update && sudo apt-get -y install lcov

- name: InstallMacDependencies
if: runner.os == 'macOS'
run: brew install lcov

- name: ConfigureCoverage
run: |
cargo install grcov
rustup component add llvm-tools-preview
echo RUSTFLAGS="-C instrument-coverage" >> "$GITHUB_ENV"
echo LLVM_PROFILE_FILE="flow-%p-%m.profraw" >> "$GITHUB_ENV"
- name: install cross
run: cargo install cross --git https://github.com/cross-rs/cross

- name: build
run: make build

Expand All @@ -74,6 +60,5 @@ jobs:
- name: UploadCoverage
run: |
grcov . --binary-path target/debug/ -s . -t lcov --branch --ignore-not-existing --ignore "/*" -o lcov.info
#lcov --remove lcov.info 'target/debug/build/**' '**/errors.rs' '*tests/*' -o lcov.info
bash <(curl -s https://codecov.io/bash) -f lcov.info
rm -f lcov.info
1 change: 1 addition & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

5 changes: 3 additions & 2 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ required-features = ["pi"]
default = []
pi = ["rppal"]
pico = [] #embassy
gui = ["iced"]
gui = ["iced", "tokio", "serde"]

[dependencies]
# for interacting with GPIO on the Raspberry Pi
Expand All @@ -35,4 +35,5 @@ rppal = { version = "0.17.1", optional = true }
iced = { version = "0.12.1", features = ["tokio", "debug"], optional = true }
iced_aw = { version = "0.9.3", default-features = false, features = ["tabs", "card", "modal",] , optional = true }
iced_native = { version = "0.10.3", optional = true }
tokio = { version = "1", features = ["sync"], optional = true }
tokio = { version = "1", features = ["sync"], optional = true }
serde = { version = "1.0.201", features = ["derive"], optional = true }
57 changes: 47 additions & 10 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -10,48 +10,85 @@
# target/aarch64-unknown-linux-gnu/release/piggui - GUI version for Pi with GPIO, can be run natively from RPi command line
# target/aarch64-unknown-linux-gnu/release/piglet - Headless version for Pi with GPIO, can be run natively from RPi command line

# Detect if on a Raspberry Pi
$(eval PI = $(shell cat /proc/cpuinfo 2>&1 | grep "Raspberry Pi"))

.PHONY: all
all: build pibuild
all: clippy piclippy build pibuild test

release: release-build pibuild

.PHONY: piclippy
piclippy:
ifneq ($(PI),)
echo "Detected as running on Raspberry Pi"
else
CROSS_CONTAINER_OPTS="--platform linux/amd64" cross clippy --release --features "pi","gui" --tests --no-deps --target=aarch64-unknown-linux-gnu
endif

.PHONY: clippy
clippy: piclippy
clippy:
ifneq ($(PI),)
echo "Detected as running on Raspberry Pi"
cargo clippy --features "pi","gui" --tests --no-deps
else
cargo clippy --features "gui" --tests --no-deps
endif

#-- --warn clippy::pedantic -D warnings

# I'm currently building using release profile for Pi, as not debugging natively on it. If we want to do that then
# we may need to add another make target
# For raspberry pi, build with the "rrpal" and "iced" features.
# That should build both the "piggui" and "piglet" binaries, with GUI and GPIO in "piggui" and GPIO in "piglet"
.PHONY: pibuild
pibuild:
ifneq ($(PI),)
echo "Detected as running on Raspberry Pi"
else
CROSS_CONTAINER_OPTS="--platform linux/amd64" cross build --release --features "pi","gui" --target=aarch64-unknown-linux-gnu
endif

# Enable the "iced" feature so we only build the "piggui" binary on the current host (macos, linux or raspberry pi)
# To build both binaries on a Pi directly, we will need to modify this
.PHONY: build
build:
ifneq ($(PI),)
echo "Detected as running on Raspberry Pi"
cargo build --features "pi","gui"
else
cargo build --features "gui"
endif

.PHONY: run
run:
ifneq ($(PI),)
echo "Detected as running on Raspberry Pi"
cargo run --features "pi","gui"
else
cargo run --features "gui"
endif

# This will build all binaries on the current host, be it macos, linux or raspberry pi - with release profile
.PHONY: release-build
release-build:
ifneq ($(PI),)
echo "Detected as running on Raspberry Pi"
cargo build --release --features "pi","gui"
else
cargo build --release --features "gui"

# I'm currently building using release profile for Pi, as not debugging natively on it. If we want to do that then
# we may need to add another make target
# For raspberry pi, build with the "rrpal" and "iced" features.
# That should build both the "piggui" and "piglet" binaries, with GUI and GPIO in "piggui" and GPIO in "piglet"
.PHONY: pibuild
pibuild:
CROSS_CONTAINER_OPTS="--platform linux/amd64" cross build --release --features "pi","gui" --target=aarch64-unknown-linux-gnu
endif

# This will only test GUI tests in piggui on the local host, whatever that is
# We'd need to think how to run tests on RPi, on piggui with GUI and GPIO functionality, and piglet with GPIO functionality
.PHONY: test
test:
ifneq ($(PI),)
echo "Detected as running on Raspberry Pi"
cargo test --features "pi","gui"
else
cargo test --features "gui"
endif

.PHONY: copy
copy: pibuild
Expand Down
17 changes: 11 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -71,22 +71,27 @@ Run `"make"` on macos or linux (or in fact RPi also) host to build these binarie

Use `"make run"` to start `piggui` on the local machine - for GUI development.

### Building for Pi
### Building for Pi from macos or linus
If you use `make` that builds for local host AND pi (using cross).

#### Helper Env vars
There are a couple of env vars that can be setup to help you interact with your pi.

Set these up in your env, or set them on the command line when invoking `make`
You can set these up in your env so you always have them, or set them on the command line when invoking `make`

* `PI_TARGET` Which Pi to copy files to and ssh into
`PI_TARGET := pizero2w0.local`

* `PI_USER` The User name of your user on the pi, to be able to copy files and ssh into it
* `PI_USER` The username of your user on the pi, to be able to copy files and ssh into it
`PI_USER := andrew`

#### Make targets
* Use `"make pibuild"` to build only for the Pi. This will build both `piggui` (with GUI and GPIO) and `piglet` binary with GPIO only
* Use `"make copy"` to copy the built binaries to your raspberry pi.
* Use `"make ssh"` to ssh into your Pi to be able to run the binaries.
* Use `make` to run `clippy`, build for the Pi using `cross`, build for the local machine using `cargo` and to run tests
* Use `make pibuild` to build only for the Pi. This will build both `piggui` (with GUI and GPIO) and `piglet` binary with GPIO only
* Use `make copy` to copy the built binaries to your raspberry pi.
* Use `make ssh` to ssh into your Pi to be able to run the binaries.

### Building for Pi on a Pi!
You should be able to use `make build` or `make run` directly, and it will build `piggui` with a GUI
### Building for Linux/macOS
Use "make build"
83 changes: 83 additions & 0 deletions src/gpio/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
mod pins;

//use serde::{Deserialize, Serialize};
use pins::*;

pub type PinLevel = bool;

#[derive(Debug)]
#[allow(dead_code)]
pub struct GPIOState {
pub pin_state: [Option<PinLevel>; 40] // TODO make private later
}

// All the possible functions a pin can be given
#[derive(Debug, PartialEq, Clone)]
#[allow(non_camel_case_types)]
#[allow(clippy::upper_case_acronyms)]
pub enum PinFunction {
Power3V3,
Power5V,
Ground,
Input,
Output,
SDA1,
I2C,
SCL1,
SPIO_MOSI,
SPIO_MISO,
SPIO_SCLK,
ID_SD,
ID,
EEPROM,
UART0_TXD,
UART0_RXD,
PCM_CLK,
SPIO_CE0_N,
SPIO_CE1_N,
ID_SC
}

// [board_pin_number] refer to the pins by the number of the pin printed on the board
// [bcm_pin_number] refer to the pins by the "Broadcom SOC channel" number,
// these are the numbers after "GPIO"
#[derive(Debug, Clone)]
#[allow(dead_code)] // TODO remove later
pub struct PinConfig {
pub board_pin_number: u8,
bcm_pin_number: Option<u8>,
pub name: &'static str,
options: &'static[PinFunction], // The set of functions the pin can have, chosen by user config
config: Option<PinFunction>, // The currently selected function for the pin, if any selected
}

// Model the 40 pin GPIO connections - including Ground, 3.3V and 5V outputs
// If no specific config is set on a pin, it will have None
// I have made array of 40, to the index is "of by one" compared to the [board_pin_number]
// is not used
#[derive(Debug, Clone)]
pub struct GPIOConfig {
pub pins: [PinConfig; 40], // TODO make private later
}

impl Default for GPIOConfig {
fn default() -> Self {
GPIOConfig {
pins: [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, PIN_16, PIN_17, PIN_18, PIN_19, PIN_20,
PIN_21, PIN_22, PIN_23, PIN_24, PIN_25, PIN_26, PIN_27, PIN_28, PIN_29, PIN_30,
PIN_31, PIN_32, PIN_33, PIN_34, PIN_35, PIN_36, PIN_37, PIN_38, PIN_39, PIN_40],
}
}
}

#[cfg(test)]
mod test {
use crate::gpio;

#[test]
fn create_a_config() {
let config = gpio::GPIOConfig::default();
assert_eq!(config.pins[1].config, None);
}
}
Loading

0 comments on commit 4c138b8

Please sign in to comment.