Skip to content

Commit

Permalink
arduino-hal: Add support for Arduino Mega 1280
Browse files Browse the repository at this point in the history
  • Loading branch information
ReinoutHeeck authored and Rahix committed Nov 27, 2022
1 parent 4a70d2d commit 54cffc3
Show file tree
Hide file tree
Showing 15 changed files with 229 additions and 6 deletions.
3 changes: 3 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,9 @@ jobs:
- type: board
name: arduino-mega2560
examples: true
- type: board
name: arduino-mega1280
examples: true
- type: board
name: sparkfun-promicro
examples: true
Expand Down
1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ members = [
"examples/arduino-diecimila",
"examples/arduino-leonardo",
"examples/arduino-mega2560",
"examples/arduino-mega1280",
"examples/arduino-nano",
"examples/arduino-uno",
"examples/nano168",
Expand Down
1 change: 1 addition & 0 deletions arduino-hal/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ mcu-attiny=[]
arduino-diecimila = ["mcu-atmega", "atmega-hal/atmega168", "board-selected"]
arduino-leonardo = ["mcu-atmega", "atmega-hal/atmega32u4", "board-selected"]
arduino-mega2560 = ["mcu-atmega", "atmega-hal/atmega2560", "board-selected"]
arduino-mega1280 = ["mcu-atmega", "atmega-hal/atmega1280", "board-selected"]
arduino-nano = ["mcu-atmega", "atmega-hal/atmega328p", "atmega-hal/enable-extra-adc", "board-selected"]
arduino-uno = ["mcu-atmega", "atmega-hal/atmega328p", "board-selected"]
trinket-pro = ["mcu-atmega", "atmega-hal/atmega328p", "board-selected"]
Expand Down
1 change: 1 addition & 0 deletions arduino-hal/src/clock.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ pub(crate) mod default {
feature = "arduino-diecimila",
feature = "arduino-leonardo",
feature = "arduino-mega2560",
feature = "arduino-mega1280",
feature = "arduino-nano",
feature = "arduino-uno",
feature = "sparkfun-promicro",
Expand Down
4 changes: 4 additions & 0 deletions arduino-hal/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
#![cfg_attr(feature = "arduino-diecimila", doc = "**Arduino Diecimila**.")]
#![cfg_attr(feature = "arduino-leonardo", doc = "**Arduino Leonardo**.")]
#![cfg_attr(feature = "arduino-mega2560", doc = "**Arduino Mega 2560**.")]
#![cfg_attr(feature = "arduino-mega1280", doc = "**Arduino Mega 1280**.")]
#![cfg_attr(feature = "arduino-nano", doc = "**Arduino Nano**.")]
#![cfg_attr(feature = "arduino-uno", doc = "**Arduino Uno**.")]
#![cfg_attr(feature = "sparkfun-promicro", doc = "**SparkFun ProMicro**.")]
Expand Down Expand Up @@ -54,6 +55,7 @@ compile_error!(
* arduino-diecimila
* arduino-leonardo
* arduino-mega2560
* arduino-mega1280
* arduino-nano
* arduino-uno
* sparkfun-promicro
Expand Down Expand Up @@ -178,6 +180,7 @@ pub mod prelude {
if #[cfg(any(
feature = "arduino-diecimila",
feature = "arduino-mega2560",
feature = "arduino-mega1280",
feature = "arduino-uno"
))] {
pub use crate::hal::usart::BaudrateArduinoExt as _;
Expand Down Expand Up @@ -231,6 +234,7 @@ macro_rules! default_serial {
#[cfg(any(
feature = "arduino-diecimila",
feature = "arduino-mega2560",
feature = "arduino-mega1280",
feature = "arduino-uno"
))]
#[macro_export]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,13 @@ pub use atmega_hal::port::{mode, Pin, PinOps, PinMode};
avr_hal_generic::renamed_pins! {
type Pin = Pin;

/// Pins of the **Arduino Mega 2560**.
///
/// Pins of the **Arduino Mega 2560** and **Arduino Mega 1280**.
///
/// mega1280:
/// https://www.arduino.cc/en/uploads/Main/arduino-mega-schematic.pdf
/// mega2560:
/// https://www.arduino.cc/en/uploads/Main/arduino-mega2560-schematic.pdf
///
/// This struct is best initialized via the [`arduino_hal::pins!()`][crate::pins] macro.
pub struct Pins from atmega_hal::Pins {
/// `D0` / `RX0`
Expand Down
8 changes: 4 additions & 4 deletions arduino-hal/src/port/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,10 +23,10 @@ pub use diecimila::*;
mod leonardo;
#[cfg(feature = "arduino-leonardo")]
pub use leonardo::*;
#[cfg(feature = "arduino-mega2560")]
mod mega2560;
#[cfg(feature = "arduino-mega2560")]
pub use mega2560::*;
#[cfg(any(feature = "arduino-mega2560", feature = "arduino-mega1280"))]
mod mega;
#[cfg(any(feature = "arduino-mega2560", feature = "arduino-mega1280"))]
pub use mega::*;
#[cfg(any(feature = "arduino-nano", feature = "arduino-uno", feature = "nano168"))]
mod uno;
#[cfg(any(feature = "arduino-nano", feature = "arduino-uno", feature = "nano168"))]
Expand Down
8 changes: 8 additions & 0 deletions examples/arduino-mega1280/.cargo/config.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
[build]
target = "../../avr-specs/avr-atmega1280.json"

[target.'cfg(target_arch = "avr")']
runner = "ravedude -cb 57600 mega1280"

[unstable]
build-std = ["core"]
16 changes: 16 additions & 0 deletions examples/arduino-mega1280/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
[package]
name = "arduino-mega1280-examples"
version = "0.0.0"
authors = ["Rahix <[email protected]>"]
edition = "2018"
publish = false

[dependencies]
panic-halt = "0.2.0"
ufmt = "0.1.0"
nb = "0.1.2"
embedded-hal = "0.2.3"

[dependencies.arduino-hal]
path = "../../arduino-hal/"
features = ["arduino-mega1280"]
14 changes: 14 additions & 0 deletions examples/arduino-mega1280/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@

The `Mega1280` board cannot be auto-detected by ravedude, you need to specify the port explicitly.

This can be done in two ways:

* Add the `-P` flag to the ravedude invocation such as in the `.cargo/config.toml`, for example:
```toml
runner = "ravedude -P /dev/ttyUSB0 -cb 57600 mega1280"
```

* Set the `RAVEDUDE_PORT` environment variable, for example:
```bash
RAVEDUDE_PORT=/dev/ttyUSB0 cargo run --bin mega1280-i2cdetect
```
53 changes: 53 additions & 0 deletions examples/arduino-mega1280/src/bin/mega1280-adc.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
#![no_std]
#![no_main]

use arduino_hal::prelude::*;
use panic_halt as _;

use arduino_hal::adc;

#[arduino_hal::entry]
fn main() -> ! {
let dp = arduino_hal::Peripherals::take().unwrap();
let pins = arduino_hal::pins!(dp);
let mut serial = arduino_hal::default_serial!(dp, pins, 57600);

let mut adc = arduino_hal::Adc::new(dp.ADC, Default::default());

let (vbg, gnd) = (
adc.read_blocking(&adc::channel::Vbg),
adc.read_blocking(&adc::channel::Gnd),
);
ufmt::uwriteln!(&mut serial, "Vbandgap: {}", vbg).void_unwrap();
ufmt::uwriteln!(&mut serial, "Ground: {}", gnd).void_unwrap();

// To store multiple channels in an array, we use the `into_channel()` method.
let channels: [adc::Channel; 16] = [
pins.a0.into_analog_input(&mut adc).into_channel(),
pins.a1.into_analog_input(&mut adc).into_channel(),
pins.a2.into_analog_input(&mut adc).into_channel(),
pins.a3.into_analog_input(&mut adc).into_channel(),
pins.a4.into_analog_input(&mut adc).into_channel(),
pins.a5.into_analog_input(&mut adc).into_channel(),
pins.a6.into_analog_input(&mut adc).into_channel(),
pins.a7.into_analog_input(&mut adc).into_channel(),
pins.a8.into_analog_input(&mut adc).into_channel(),
pins.a9.into_analog_input(&mut adc).into_channel(),
pins.a10.into_analog_input(&mut adc).into_channel(),
pins.a11.into_analog_input(&mut adc).into_channel(),
pins.a12.into_analog_input(&mut adc).into_channel(),
pins.a13.into_analog_input(&mut adc).into_channel(),
pins.a14.into_analog_input(&mut adc).into_channel(),
pins.a15.into_analog_input(&mut adc).into_channel(),
];

loop {
for (i, ch) in channels.iter().enumerate() {
let v = adc.read_blocking(ch);
ufmt::uwrite!(&mut serial, "A{}: {} ", i, v).void_unwrap();
}

ufmt::uwriteln!(&mut serial, "").void_unwrap();
arduino_hal::delay_ms(1000);
}
}
17 changes: 17 additions & 0 deletions examples/arduino-mega1280/src/bin/mega1280-blink.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
#![no_std]
#![no_main]

use panic_halt as _;

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

let mut led = pins.d13.into_output().downgrade();

loop {
led.toggle();
arduino_hal::delay_ms(1000);
}
}
26 changes: 26 additions & 0 deletions examples/arduino-mega1280/src/bin/mega1280-i2cdetect.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
#![no_std]
#![no_main]

use arduino_hal::prelude::*;
use panic_halt as _;

#[arduino_hal::entry]
fn main() -> ! {
let dp = arduino_hal::Peripherals::take().unwrap();
let pins = arduino_hal::pins!(dp);
let mut serial = arduino_hal::default_serial!(dp, pins, 57600);

let mut i2c = arduino_hal::I2c::new(
dp.TWI,
pins.d20.into_pull_up_input(),
pins.d21.into_pull_up_input(),
50000,
);

ufmt::uwriteln!(&mut serial, "Write direction test:\r").void_unwrap();
i2c.i2cdetect(&mut serial, arduino_hal::i2c::Direction::Write).void_unwrap();
ufmt::uwriteln!(&mut serial, "\r\nRead direction test:\r").void_unwrap();
i2c.i2cdetect(&mut serial, arduino_hal::i2c::Direction::Read).void_unwrap();

loop {}
}
24 changes: 24 additions & 0 deletions examples/arduino-mega1280/src/bin/mega1280-usart.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
#![no_std]
#![no_main]

use arduino_hal::prelude::*;
use panic_halt as _;

use embedded_hal::serial::Read;

#[arduino_hal::entry]
fn main() -> ! {
let dp = arduino_hal::Peripherals::take().unwrap();
let pins = arduino_hal::pins!(dp);
let mut serial = arduino_hal::default_serial!(dp, pins, 57600);

ufmt::uwriteln!(&mut serial, "Hello from Arduino!\r").void_unwrap();

loop {
// Read a byte from the serial connection
let b = nb::block!(serial.read()).void_unwrap();

// Answer
ufmt::uwriteln!(&mut serial, "Got {}!\r", b).void_unwrap();
}
}
50 changes: 50 additions & 0 deletions examples/arduino-mega1280/src/bin/mega1280spi-feedback.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
//! This example demonstrates how to set up a SPI interface and communicate
//! over it. The physical hardware configuation consists of connecting a
//! jumper directly from pin `d50` (MISO/PB3) to pin `d51` (MOSI/PB2).
//!
//! Once this program is written to the board, the serial output can be
//! accessed with
//!
//! ```
//! sudo screen /dev/ttyACM0 57600
//! ```
//!
//! You should see it output the line `data: 15` repeatedly (aka 0b00001111).
//! If the output you see is `data: 255`, you may need to check your jumper.
#![no_std]
#![no_main]

use arduino_hal::prelude::*;
use arduino_hal::spi;
use embedded_hal::spi::FullDuplex;
use panic_halt as _;

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

// set up serial interface for text output
let mut serial = arduino_hal::default_serial!(dp, pins, 57600);

// Create SPI interface.
let (mut spi, _) = arduino_hal::Spi::new(
dp.SPI,
pins.d52.into_output(),
pins.d51.into_output(),
pins.d50.into_pull_up_input(),
pins.d53.into_output(),
spi::Settings::default(),
);

loop {
// Send a byte
nb::block!(spi.send(0b00001111)).void_unwrap();
// Because MISO is connected to MOSI, the read data should be the same
let data = nb::block!(spi.read()).void_unwrap();

ufmt::uwriteln!(&mut serial, "data: {}\r", data).void_unwrap();
arduino_hal::delay_ms(1000);
}
}

0 comments on commit 54cffc3

Please sign in to comment.