avr-hal Documentation

repository·main·Indexed 23 days ago

https://github.com/rahix/avr-hal

A Hardware Abstraction Layer for AVR microcontrollers and common boards like Arduino, built on top of the avr-device crate. The workspace includes arduino-hal for board-specific abstractions, mcu/atmega-hal and mcu/attiny-hal for microcontroller families, and avr-hal-generic for core HAL implementations. It also provides ravedude, a utility for integrating avrdude and serial consoles into the cargo workflow for seamless flashing and running.

Tokens
15.3K
Snippets
40
Records
99
Agent score
82%

What's inside avr-hal

  1. Understand the avr-hal repository structure

    main

    The avr-hal workspace is organized into several specialized crates:

    • arduino-hal: The primary, batteries-included HAL for Arduino and similar boards. It abstracts away board differences and is the recommended starting point for most users.
    • mcu/atmega-hal & mcu/attiny-hal: HAL crates for specific AVR microcontroller families. Use these if you are working with custom boards rather than standard Arduino boards.
    • avr-hal-generic: A core crate containing HAL implementations as macros. If you are writing drivers intended to work across various AVR chips, target this crate.
    • examples/*: A collection of hardware examples. The arduino-uno crate currently contains the most comprehensive set.
    • ravedude: A utility for integrating avrdude and serial consoles into the cargo workflow.
  2. Porting examples to different hardware

    main
    Examples in avr-hal are often highly portable. If you cannot find a specific example for your exact board, look for examples targeting similar hardware (e.g., other ATmega-based Arduino boards) and adapt them to your specific pinout and configuration.
  3. Install ravedude

    main

    Linux Prerequisites

    On Linux systems, you must install pkg-config and libudev development files before installing ravedude.

    • Archlinux: pacman -S systemd pkgconf
    • Ubuntu/Debian: apt install libudev-dev pkg-config
    • Fedora: dnf install systemd-devel pkgconf-pkg-config

    Installation via Cargo

    Install the latest version from crates.io:

    cargo +stable install --locked ravedude

    Installation via Nix

    If using Nix + Flakes, add the following to your inputs:

    inputs.ravedude.url = "github:Rahix/avr-hal?dir=ravedude";

    Then use the package ravedude.packages."${system}".default.

  4. Run an example on a connected board

    main

    To run an example from the avr-hal repository on your hardware, navigate to the specific board's subdirectory and use cargo run specifying the binary name.

    Prerequisite: You must have ravedude installed to enable automatic flashing and running on connected boards.

    cargo install ravedude
    cd examples/arduino-uno
    
    # Build and run it on a connected board
    cargo run --bin uno-blink
  5. How to define a Custom Board in Ravedude.toml

    main

    If your board is not supported by default, you can define it manually in Ravedude.toml by providing the [board] and [board.avrdude] sections. This allows you to specify the programmer, part number, and other avrdude specific configurations.

    [general]
    # port = ...
    # open-console = true
    # serial-baudrate = 57600
    
    [board]
    name = "Custom Arduino Uno"
    
    [board.reset]
    # The board automatically resets when attempting to flash
    automatic = true
    
    [board.avrdude]
    # avrdude configuration
    programmer = "arduino"
    partno = "atmega328p"
    baudrate = -1
    do-chip-erase = true
  6. Install avr-hal dependencies

    main

    Before using avr-hal, you must install the necessary system dependencies for your operating system to support AVR compilation and flashing.

    Ubuntu

    sudo apt install avr-libc gcc-avr pkg-config avrdude libudev-dev build-essential

    MacOS

    xcode-select --install # if you haven't already done so
    brew tap osx-cross/avr
    brew install avr-gcc avrdude

    Windows

    Using winget:

    winget install AVRDudes.AVRDUDE ZakKemble.avr-gcc

    Using Scoop:

    Set-ExecutionPolicy RemoteSigned -Scope CurrentUser
    irm get.scoop.sh | iex
    scoop install avr-gcc
    scoop install avrdude
    sudo apt install avr-libc gcc-avr pkg-config avrdude libudev-dev build-essential
  7. Configure ravedude as a Cargo runner

    main

    To use ravedude with cargo run, you must configure it as the runner for the AVR architecture.

    Important: This configuration must be placed in .cargo/config.toml within your project, not in Cargo.toml.

    [target.'cfg(target_arch = "avr")']
    runner = "ravedude"
  8. Start a new avr-hal project

    main

    The recommended way to start a new project is using the avr-hal-template with cargo-generate.

    cargo install cargo-generate
    cargo generate --git https://github.com/Rahix/avr-hal-template.git
    cargo install cargo-generate
    cargo generate --git https://github.com/Rahix/avr-hal-template.git
  9. Use plain atmega-hal for ATmega2560

    main
    The atmega2560 examples directory provides code demonstrating how to use the plain atmega-hal crate directly. This is distinct from using the arduino-hal crate, which is specifically targeted at Arduino-branded boards. While these examples are written for the plain HAL, they have been tested and are compatible with the Arduino Mega2560 board.
  10. Install ravedude for seamless flashing

    main

    Install ravedude to integrate flashing your board into the standard cargo run workflow. This tool handles avrdude and serial console integration.

    cargo +stable install ravedude
    cargo +stable install ravedude
  11. How the Pin type and its modes work

    main

    In avr-hal, a Pin<MODE, PIN> represents a physical MCU pin. The MODE is a type-level parameter that enforces correct usage at compile time (e.g., you cannot call set_high() on a pin configured as an Input).

    Pin Modes

    • Output Modes (mode::Output, mode::OpenDrain): Used for driving signals. Output is standard push-pull, while OpenDrain is used for protocols like I2C.
    • Input Modes (mode::Input<IMODE>): Used for reading signals. The IMODE parameter specifies the electrical configuration:
      • mode::Floating: No internal pull-up/down.
      • mode::PullUp: Internal pull-up resistor enabled.
      • mode::AnyInput: A generic type that can represent either floating or pull-up.
    • Analog Mode (mode::Analog): Configures the pin for use with the ADC (Analog-to-Digital Converter).
  12. How clock speed management works in avr-hal

    main

    AVR microcontrollers support different core clock speeds. Peripheral drivers use this speed to calculate timing parameters. To maximize efficiency, avr-hal tracks clock speed as a compile-time constant, allowing drivers to perform timing calculations at compile time rather than runtime.

    Using arduino-hal

    If you are using arduino-hal, no manual configuration is required. The core clock speed is automatically defined as arduino_hal::DefaultClock, and all peripheral driver const-generic parameters are preset to this value.

    Using MCU HALs (atmega-hal or attiny-hal)

    If you are using a specific MCU HAL, you must manage the clock speed manually by defining a type alias for your clock and using it to alias your peripheral drivers.