Reusable components for the Arduino Uno.

Related tags

Embedded ruduino
Overview

Ruduino

This library provides a set of reusable components for the Arduino Uno.

Overview

Register and bit definitions

use ruduino::cores::current::PORTB;  // Register
use ruduino::cores::current::PORTB7; // Pin

Prelude

Disable interrupts.

without_interrupts(|| {
    unsafe { write_volatile(DDRB, 0xFF) }
})

Timers

Configure a timer.

const DESIRED_HZ_TIM1: f64 = 2.0;
const TIM1_PRESCALER: u64 = 1024;
const INTERRUPT_EVERY_1_HZ_1024_PRESCALER: u16 =
    ((ruduino::config::CPU_FREQUENCY_HZ as f64 / (DESIRED_HZ_TIM1 * TIM1_PRESCALER as f64)) as u64 - 1) as u16;

timer1::Timer::new()
    .waveform_generation_mode(timer1::WaveformGenerationMode::ClearOnTimerMatchOutputCompare)
    .clock_source(timer1::ClockSource::Prescale1024)
    .output_compare_1(Some(INTERRUPT_EVERY_1_HZ_1024_PRESCALER))
    .configure();

Set up an interrupt handler that will be called when the timer fires.

#[no_mangle]
pub unsafe extern "avr-interrupt" fn _ivr_timer1_compare_a() {
    let prev_value = read_volatile(PORTB);
    write_volatile(PORTB, prev_value ^ PINB5);
}

Hardware Serial Port

Configure the serial port.

const BAUD: u64 = 9600;
const UBRR: u16 = (ruduino::config::CPU_FREQUENCY_HZ / 16 / BAUD - 1) as u16;

serial::Serial::new(UBRR)
    .character_size(serial::CharacterSize::EightBits)
    .mode(serial::Mode::Asynchronous)
    .parity(serial::Parity::Disabled)
    .stop_bits(serial::StopBits::OneBit)
    .configure();

Transmit a sequence of bytes.

for &b in b"OK" {
    serial::transmit(b);
}

Read a byte if there's something available.

if let Some(b) = serial::try_receive() {
    serial::transmit(b);
    serial::transmit(b);
}
Comments
  • Write trait doesn't work for serial

    Write trait doesn't work for serial

    Hello,

    I have tried to implement the Write trait for the Serial struct and I haven't succeed making the write_fmt work.
    Both write_str and write_char works well and I can't seem to understand why the write_fmt doesn't work. I don't have many experience with rust so maybe you can figure out what is not working. I though since write_str is working well and as write_fmt is implemented in Write trait, it should be working.

    Here is the simple implementation I did :

    impl Write for Serial {
        fn write_str(&mut self, s: &str) -> core::fmt::Result {
            for &b in s.as_bytes() {
                transmit(b);
            }
            Ok(())
        }
    }
    

    Thanks in advance

    opened by clebi 8
  • Rust on an arduino Leonardo

    Rust on an arduino Leonardo

    I recently got a shiny new keyboard from https://shop.keyboard.io/ :)

    I am truly loving the hardware, but given that all of the configuration is done in arduino c it makes me a bit sad. I have been spending some time looking into rust and enjoying the zero cost abstractions and the convenient type systems. This all got me thinking that I would really love to be able to program for my keyboard in rust. The existing firmware for it is highly plugin based which would be a great fit for rusts crate system and is currently pretty annoying to get working in arduino c/c++.

    All of this lead me to this repo and organization. I am pretty new to arduino/avr programming however so I have a couple of questions.

    First: How likely is using something like avr-rust on an arduino leonardo to be successful? Will I need to be extra careful with progmem when compared to a c version? Does rust have a large standard library which will take up too much space or is it relatively bare bones? My guess is that this is entirely up to me as I will have to recompile core anyways, but I'm not sure.

    Second: What is the status of rust on avr. I saw a couple of threads in the main repo indicating that rust was updated to the correct version of LLVM, but I also saw that there are some outstanding bugs with LLVM which makes things difficult including i128 types not working. Are these insurmountable at the moment or is there a happy path for ignoring them?

    Third: I saw a separate issue and pull request related to adding support for different boards, I think, this would be necessary for building firmware for my keyboard as it is based on the leonardo instead of the uno. Is this still something for which progress is being made or am I left in the dark?

    I'm not sure if this is the correct place to ask these questions. Sorry if not. Clearly I am not super experienced with microcontroller programming, so any assistance in this project would be greatly appreciated!

    opened by Kethku 7
  • WIP: Support for autogenerated mcu cores

    WIP: Support for autogenerated mcu cores

    It should be possible to do something like this

    extern crate arduino;
    use arduino::{Pin, HardwareSpi};
    use arduino::cores::atmega328p;
    
    trait Netlist {
        type PushButton: Pin;
        type Led: Pin;
        type Spi: HardwareSpi;
    }
    
    struct ATmega328p;
    
    impl Netlist for ATmega328p {
        type PushButton = atmega328p::PORTB3;
        type Led = atmega328p::PORTB4;
        type Spi = atmega328p::SPI;
    }
    
    fn start<N: Netlist>() {
        N::PushButton::set_input();
        N::Led::set_output();
        N::Spi::setup_master();
    
       loop {
            // delay
            M::Led::set_high();
            // delay
            M::Led::set_low();
        }
    }
    

    This would allow users to easily mix-and-match supported microcontrollers, provided the microcontroller has enough GPIOs, etc.

    opened by dylanmckay 6
  • Fix build: Use the new rust asm! available in rustc 1.63.0-nightly

    Fix build: Use the new rust asm! available in rustc 1.63.0-nightly

    The old llvm_asm! has been removed. Therefore, it doesn't compile on new rustc anymore.

    In addition to this, an updated avr-delay dependency is needed to compile successfully: https://github.com/avr-rust/delay/pull/18

    opened by mbuesch 3
  • Docs.rs is complaining this won't compile

    Docs.rs is complaining this won't compile

    I can't seem to get documentation for any version newer than 0.1.2 because "docs.rs failed to build ruduino-0.2.0"

    This seems to be the same issue as here: https://github.com/avr-rust/blink/issues/25, I did a quick test and was able to confirm build failure and was able to get it working using the same fix I suggested there (included below for your reference).

    Cargo.toml

    [profile.dev]
    opt-level = "s"
    debug-assertions = false
    
    [profile.release]
    opt-level = "s"
    
    opened by timbell87 3
  • Always inline disabling interrupts

    Always inline disabling interrupts

    It never makes sense to call a function for these two instructions.

    Additionally, I use this at system boot time to configure the stack pointer itself. If this becomes a function call, then everything is broken!

    opened by shepmaster 3
  • How do I read/write analog values

    How do I read/write analog values

    I don't seem to find a way to read analog input using this library. I suppose that it is either not currently supported or considered too high level for this library.

    Is there an example on to achieve this (read and possibly write analog values) using Rust?

    opened by Altaflux 3
  • Make `Register::set` use `volatile_write`

    Make `Register::set` use `volatile_write`

    I was writing a small programs that uses the internal EEPROM of the ATmega328P, when I noticed that no writing was occuring. I was using

    EECR::set(EECR::EEMPE);
    EECR::set(EECR::EEPE);
    

    to start writing to the EEPROM, but the memory was unchanged.

    When I replaced the above code with the following:

    EECR::write(EECR::EEMPE);
    EECR::write(EECR::EEPE);
    

    it worked like a charme.

    I might be mistaken, but after digging through the Register code, I noticed that Register::set is not using volatile_write https://github.com/avr-rust/ruduino/blob/302095dca22f63a160d44c1fdcdc0fdf1db4072d/src/register.rs#L53-L57 while Register::unset, Register::write, etc are doing so. Is there a particular reason for this, that I may not understand yet? https://github.com/avr-rust/ruduino/blob/302095dca22f63a160d44c1fdcdc0fdf1db4072d/src/register.rs#L70-L74

    Thanks!

    opened by MalteT 2
  • Once it's compiled, how do you upload it on the arduino?

    Once it's compiled, how do you upload it on the arduino?

    Hi! I finally managed to build this project using the branch avr-use-correct-addrspace from https://github.com/dylanmckay/rust.git Now I have the .elf file, but how can I upload it to my arduino nano?

    opened by jdrouet 2
  • #![feature(unwind-attributes)] has been removed?

    #![feature(unwind-attributes)] has been removed?

    I’m trying to compile a basic program that blinks my ATmega328p, but whenever I compile my code I get the following error message:

    error[E0557]: feature has been removed
     --> /Users/ryan/.cargo/registry/src/github.com-1ecc6299db9ec823/ruduino-0.3.2/src/lib.rs:8:12
      |
    8 | #![feature(unwind_attributes)]
      |            ^^^^^^^^^^^^^^^^^ feature has been removed
      |
      = note: use the C-unwind ABI instead
    

    This problem seems to be close to the #![feature(const_fn)] has been removed problem, but that could be solved by just removing the #![feature(const_fn)] line from the imported crate. Yet, If I delete the #![feature(unwind_attributes)] line, I’ll get the following error:

    error: language item required, but not found: `eh_personality`
    
    error: `#[panic_handler]` function required, but not found
    
    error: could not compile `avr-projects` due to 2 previous errors
    
    opened by Rynibami 1
  • #[feature(const_fn)] removed on latest rust nightly

    #[feature(const_fn)] removed on latest rust nightly

    When trying to compile an example program, I get this error from the ruduino crate:

    error[E0557]: feature has been removed
     --> /home/ggsvr/.cargo/registry/src/github.com-1ecc6299db9ec823/ruduino-0.3.2/src/lib.rs:4:12
      |
    4 | #![feature(const_fn)]
      |            ^^^^^^^^ feature has been removed
      |
      = note: split into finer-grained feature gates
    
    

    I get another error from LLVM "Not supported instr", but I don't think they're related.

    opened by ggsvr 1
  • Timer configuration for interruptless mode

    Timer configuration for interruptless mode

    I'd like to configure a timer for CTC mode with polling instead of interrupts. Unfortunately, this is not possible at the moment because setting the comparator target is coupled with turning on interrupts:

        pub fn configure(self) {
            T::ControlA::write(self.a);
            T::ControlB::write(self.b);
            T::ControlC::write(self.c);
    
            // Reset counter to zero
            T::Counter::write(0u16);
    
            if let Some(v) = self.output_compare_1 {
                // Set the match
                T::CompareA::write(v);
    
                // Enable compare interrupt
                T::InterruptMask::set(T::OCIEA);
            }
        }
    

    I think these should be exposed as two orthogonal features.

    opened by gergoerdi 0
  • ATmega16u and ATmega32u support

    ATmega16u and ATmega32u support

    My Rust code is peak "I have no idea what I'm doing" territory so please feel free to improve especially the implementation of collect_register_bitfields

    opened by gergoerdi 0
  • ATmega32U4 support: collect register definitions from multiple modules

    ATmega32U4 support: collect register definitions from multiple modules

    I'd like to use Rust to develop for the ArduBoy, which uses an ATmega32U4, which I believe is the same mcu as used on the Arduino Leonardo. So there should be quite a lot of boards out there using it.

    Ruduino's core_generator chokes on the 16u4 and the 32u4 as-is because they have PDI and PDO pins in their SPI definition. I think these can be safely ignored as they are only used for in-circuit programming.

    However, if we get over this hump, we get a more severe problem: registers that are defined "piecewise" at multiple locations in the packfile. For example, on the 32u4 ADCSRB is defined in two modules, in AC and in ADC. With core_generator's naive handling of registers, these end up as duplicate definitions in atmega32u4.rs:

    #[allow(non_camel_case_types)]
    pub struct ADCSRB;
    
    impl ADCSRB {
        pub const ACME: RegisterBits<Self> = RegisterBits::new(0x40);
        pub const ACME0: RegisterBits<Self> = RegisterBits::new(1<<6);
    
    }
    
    impl Register for ADCSRB {
        type T = u8;
        const ADDRESS: *mut u8 = 0x7b as *mut u8;
    }
    
    #[allow(non_camel_case_types)]
    pub struct ADCSRB;
    
    impl ADCSRB {
        pub const ADHSM: RegisterBits<Self> = RegisterBits::new(0x80);
        pub const ADHSM0: RegisterBits<Self> = RegisterBits::new(1<<7);
    
        pub const MUX5: RegisterBits<Self> = RegisterBits::new(0x20);
        pub const MUX50: RegisterBits<Self> = RegisterBits::new(1<<5);
    
        pub const ADTS: RegisterBits<Self> = RegisterBits::new(0x17);
        pub const ADTS0: RegisterBits<Self> = RegisterBits::new(1<<0);
        pub const ADTS1: RegisterBits<Self> = RegisterBits::new(1<<1);
        pub const ADTS2: RegisterBits<Self> = RegisterBits::new(1<<2);
        pub const ADTS3: RegisterBits<Self> = RegisterBits::new(1<<4);
    
    }
    
    impl Register for ADCSRB {
        type T = u8;
        const ADDRESS: *mut u8 = 0x7b as *mut u8;
    }
    
    opened by gergoerdi 1
  • wish: publish at crates.io

    wish: publish at crates.io

    Currently this

    $ AVR_CPU_FREQUENCY_HZ=8_000_000 cargo +nightly publish --target ./avr-atmega328p.json -Z build-std=core
        Updating crates.io index
       Packaging ruduino v0.4.0 (/home/gs0604/src/rust/RustAVR/ruduino)
    error: failed to prepare local package for uploading
    
    Caused by:
      failed to select a version for the requirement `avr_delay = "^0.4.0"`
      candidate versions found which didn't match: 0.3.2, 0.3.1, 0.3.0, ...
      location searched: crates.io index
      required by package `ruduino v0.4.0 (/home/stappers/src/rust/RustAVR/ruduino)`
    

    I think the

      failed to select a version for the requirement `avr_delay = "^0.4.0"`
      candidate versions found which didn't match: 0.3.2, 0.3.1, 0.3.0, ...
    

    means that https://github.com/avr-rust/delay/issues/21 has to fixed first ...

    opened by stappersg 0
  • RFC: Add API to suspend/restore interrupts ...

    RFC: Add API to suspend/restore interrupts ...

    ... similar to the current without_interrupts() helper.

    What do you think about this?

    I renamed the existing disable/enable API to with_irqs_disabled(). The new API for suspend/restore is with_irqs_suspended(). The old without_interrupts remains as deprecated alias.

    I'm not so sure about the naming. Suggestions for better naming are welcome. :)

    This is completely untested. Just for discussion.

    opened by mbuesch 2
Owner
The AVR-Rust project
A fork of Rust with AVR microcontroller support
The AVR-Rust project
Garden monitoring system using m328p Arduino Uno boards. 100% Rust [no_std] using the avr hardware abstraction layer (avr-hal)

uno-revive-rs References Arduino Garden Controller Roadmap uno-revive-rs: roadmap Components & Controllers 1-2 Uno R3 m328p Soil moisture sensor: m328

Ethan Gallucci 1 May 4, 2022
Arduino Uno 9 axis acceleration sensor (BMX055) reader implemented in Rust.

Arduino Uno Accelaration reader in Rust Components Arduino Uno (Probably possible with other AVR microcontrollers) BMX055 (Japanese website) Datasheet

Katsu Uchiyama 3 Dec 15, 2022
Easy c̵̰͠r̵̛̠ö̴̪s̶̩̒s̵̭̀-t̶̲͝h̶̯̚r̵̺͐e̷̖̽ḁ̴̍d̶̖̔ ȓ̵͙ė̶͎ḟ̴͙e̸̖͛r̶̖͗ë̶̱́ṉ̵̒ĉ̷̥e̷͚̍ s̷̹͌h̷̲̉a̵̭͋r̷̫̊ḭ̵̊n̷̬͂g̵̦̃ f̶̻̊ơ̵̜ṟ̸̈́ R̵̞̋ù̵̺s̷̖̅ţ̸͗!̸̼͋

Rust S̵̓i̸̓n̵̉ I̴n̴f̶e̸r̵n̷a̴l mutability! Howdy, friendly Rust developer! Ever had a value get m̵̯̅ð̶͊v̴̮̾ê̴̼͘d away right under your nose just when

null 294 Dec 23, 2022
⚙️ Crate to discover embedded programming with uno r3 project

⚙️ Crate to discover embedded programming with uno r3 project

null 0 Feb 3, 2022
1️⃣ el lisp number uno - one lisp to rule them all 🏆

luno el lisp number uno luno is the one lisp to rule them all. Still experimental, do not use it in production yet. goals embeddable small size simple

Eva Pace 3 Apr 25, 2022
Reusable Reproducible Composable Software

Reusable Reproducible Composable Software Welcome What is this? Fractalide is a free and open source service programming platform using dataflow graph

Fractalide 787 Dec 29, 2022
wait-free spsc linked-list queue with individually reusable nodes

A wait-free single-producer single-consumer linked-list queue with individually reusable nodes.

glowcoil 22 Dec 26, 2022
Flexible, reusable reinforcement learning (Q learning) implementation in Rust

Rurel Rurel is a flexible, reusable reinforcement learning (Q learning) implementation in Rust. Release documentation In Cargo.toml: rurel = "0.2.0"

Milan Boers 60 Dec 29, 2022
This project attempts to allow the creation of reusable egui-themes

egui stylist Note this project is considered to be experimental and -- while used in personal projects -- may have API breaking changes without warnin

Jacobsky 22 Dec 1, 2022
An efficient method of heaplessly converting numbers into their string representations, storing the representation within a reusable byte array.

NumToA #![no_std] Compatible with Zero Heap Allocations The standard library provides a convenient method of converting numbers into strings, but thes

Michael Murphy 42 Sep 6, 2022
Fully-typed, async, reusable state management and synchronization for Dioxus 🧬

dioxus-query ?? ⚡ Fully-typed, async, reusable state management and synchronization for Dioxus ??. Inspired by TanStack Query. ⚠️ Work in progress ⚠️

Marc Espín 9 Aug 7, 2023
Arduino Nano frequency counter with atomic clock accuracy

Arduino Nano frequency counter with atomic clock accuracy Project description and test setup With this project you can measure a frequency from less t

Frank Buss 24 Apr 3, 2022
Board Support Crate for Arduino Leonardo in Rust

Deprecation Note: This crate will soon be deprecated in favor of avr-hal. avr-hal is a new approach to writing the HAL crate, that was designed with s

Rahix 5 May 6, 2021
🖥 Simple Arduino Serial Monitor

Born out of the desire to connect to an Arduino without having to run the whole Arduino suite.

Robin Schroer 2 Mar 19, 2022
An open-source emulator for small OLED displays that are often used for Arduino/IOT projects.

SSD1306 OLED Emulator An open-source emulator for small OLED displays that are often used for Arduino/IOT projects. This project is still in an alpha

Sam Peach 21 Oct 23, 2022
How to use an Arduino library in a Rust project?

Example of an Arduino library usage in a Rust project The project tested with Arduino UNO on Fedora 35. It demonstrates the usage of LiquidCrystal_I2C

Konstantin 6 Dec 27, 2022
An implementation of webauthn components for Rustlang servers

Webauthn-rs Webauthn is a modern approach to hardware based authentication, consisting of a user with an authenticator device, a browser or client tha

Kanidm 232 Jan 8, 2023
Rewind is a snapshot-based coverage-guided fuzzer targeting Windows kernel components.

Rewind is a snapshot-based coverage-guided fuzzer targeting Windows kernel components.

Quarkslab 259 Dec 26, 2022
NPM package distributing biscuit in WebAssembly for web components

Biscuit playground This is an example application for Biscuit tokens, where you can manipulate tokens and their verification in your browser. build wi

null 0 Dec 30, 2021
An implementation of webauthn components for Rustlang servers

Webauthn-rs Webauthn is a modern approach to hardware based authentication, consisting of a user with an authenticator device, a browser or client tha

Kanidm 226 Dec 28, 2022