Skip to content

Commit

Permalink
Make the mega328p example actually a Rust example
Browse files Browse the repository at this point in the history
It was a separate crate previously, but that made its compilation
completely independent from the actual PAC crate. The user can still use
that directory as a template, they'll just need to rename
`Cargo.toml.example` into place. The changed steps for that and to test
the example are documented in `examples/atmega328p/README.md`. The
target used was updated from rustc, as well, and hoisted up as a default
for the whole crate. This allows to more easily build the
library/example for quick testing.
  • Loading branch information
LuigiPiucco committed May 14, 2024
1 parent 1b40912 commit a912026
Show file tree
Hide file tree
Showing 8 changed files with 59 additions and 29 deletions.
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
[build]
target = "avr-specs/avr-atmega328p.json"
target = "avr-unknown-gnu-atmega328p.json"

[target.'cfg(target_arch = "avr")']
runner = "ravedude uno -cb 57600"
Expand Down
22 changes: 22 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -84,3 +84,25 @@ critical-section = { version = "1.1.1", optional = true }
path = "macros/"
version = "=0.5.4"
optional = true

[dev-dependencies]
nb = "0.1.2"
embedded-hal = "0.2.3"

[[example]]
name = "atmega328p"
path = "examples/atmega328p/src/main.rs"
required-features = ["atmega328p", "rt"]

[profile.dev]
panic = "abort"
codegen-units = 1
debug = true
lto = true
opt-level = "s"

[profile.release]
panic = "abort"
codegen-units = 1
lto = true
opt-level = "s"
Original file line number Diff line number Diff line change
Expand Up @@ -2,20 +2,33 @@
"arch": "avr",
"atomic-cas": false,
"cpu": "atmega328p",
"crt-objects-fallback": "false",
"data-layout": "e-P1-p:16:8-i8:8-i16:8-i32:8-i64:8-f32:8-f64:8-n8-a:8",
"eh-frame-header": false,
"exe-suffix": ".elf",
"late-link-args": {
"gcc": [
"gnu-cc": [
"-lgcc"
],
"gnu-lld-cc": [
"-lgcc"
]
},
"linker": "avr-gcc",
"linker-flavor": "gnu-cc",
"llvm-target": "avr-unknown-unknown",
"max-atomic-width": 8,
"no-default-libraries": false,
"max-atomic-width": 16,
"metadata": {
"description": null,
"host_tools": null,
"std": null,
"tier": null
},
"pre-link-args": {
"gcc": [
"gnu-cc": [
"-mmcu=atmega328p"
],
"gnu-lld-cc": [
"-mmcu=atmega328p"
]
},
Expand Down
1 change: 0 additions & 1 deletion examples/atmega328p/.gitignore

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@ name = "mega328-test"
test = false
bench = false


[dependencies]
ufmt = "0.2.0"
nb = "0.1.2"
Expand All @@ -19,20 +18,18 @@ embedded-hal = "0.2.3"

[dependencies.avr-device]
version = "0.5.3"
# To use the local version of avr-device instead, uncomment the following line:
# NB: make sure to build this crate first by running `make` at the root of the project
# path = "../.."
features = ["atmega328p", "rt"]

# Configure the build for minimal size - AVRs have very little program memory
[profile.dev]
panic = "abort"
codegen-units = 1
debug = true
lto = true
opt-level = "s"

[profile.release]
panic = "abort"
codegen-units = 1
debug = true
lto = true
opt-level = "s"
22 changes: 11 additions & 11 deletions examples/atmega328p/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,12 @@ This example showcases a minimal Rust program that solely utilizes bare
register writes without relying on a Hardware Abstraction Layer. If you want
to use a HAL, you can use [`avr-hal`], which uses `avr-device` under the hood.

Also note that to use this directory as a template for new crates,
`Cargo.toml.example` must be renamed to `Cargo.toml`. The `.example` is there
because examples of a crate shouldn't be crates themselves. You may also need
files from the crate root, namely `.cargo/config.toml`, and a nightly toolchain
while the AVR target and the `-Zbuild-std=core` flag is unstable.

[`avr-hal`]: https://github.com/Rahix/avr-hal

## Demonstrated Features
Expand Down Expand Up @@ -52,22 +58,16 @@ a panic is raised and our custom panic handler is called.
## Trying it out
1. First of all, check the README of the [`avr-hal`][avr-hal-readme] crate for
an overview of required build dependencies.
2. Change into the example directory:
```bash
cd examples/atmega328p/
```
3. Build the program:
2. Build the program:
```bash
cargo build
cargo build --example atmega328p --features=atmega328p,rt
```
4. If you want to run the example on an Arduino Uno board, you can use
[`ravedude`] to flash the microcontroller. The project is preconfigured for
3. If you want to run the example on an Arduino Uno board, you can use
[`ravedude`] to flash the microcontroller. The project is preconfigured for
this, so all you need to do is:
```bash
cargo run
cargo run --example atmega328p --features=atmega328p,rt
```
You can configure a different ATmega328P board by editing the
`.cargo/config.toml` file.

[avr-hal-readme]: https://github.com/Rahix/avr-hal#quickstart
[`ravedude`]: https://github.com/Rahix/avr-hal/tree/main/ravedude
4 changes: 0 additions & 4 deletions examples/atmega328p/rust-toolchain.toml

This file was deleted.

9 changes: 6 additions & 3 deletions examples/atmega328p/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,10 @@

use core::cell::Cell;

use avr_device::interrupt::{self, Mutex};
use avr_device::{
atmega328p::Peripherals,
interrupt::{self, Mutex},
};

static LED_STATE: Mutex<Cell<bool>> = Mutex::new(Cell::new(true));

Expand All @@ -22,7 +25,7 @@ fn panic(_info: &core::panic::PanicInfo) -> ! {
// SAFETY: Because main() already has references to the peripherals this is an unsafe
// operation - but because no other code can run after the panic handler was called,
// we know it is okay.
let dp = unsafe { avr_device::atmega328p::Peripherals::steal() };
let dp = unsafe { atmega328p::Peripherals::steal() };

loop {
avr_device::asm::delay_cycles(1_000_000);
Expand Down Expand Up @@ -53,7 +56,7 @@ fn TIMER0_OVF() {

#[avr_device::entry]
fn main() -> ! {
let dp = avr_device::atmega328p::Peripherals::take().unwrap();
let dp = Peripherals::take().unwrap();

// As you can see, we use .write() instead of .modify(), so the register
// will be written value + the modified bits
Expand Down

0 comments on commit a912026

Please sign in to comment.