diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 8c54132245..7a21f463da 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -3,24 +3,54 @@ name: Continuous Integration on: push: branches: - - master + - main + - next - wip pull_request: jobs: - board-ci: - name: "Board: ${{ matrix.board }}" + ci: + name: "${{ matrix.m.type }}: ${{ matrix.m.name }}" strategy: fail-fast: true matrix: - board: - - arduino-uno - - arduino-leonardo - - - arduino-mega2560 - - bigavr6 - - trinket - - sparkfun-pro-micro + m: + - type: board + name: arduino-uno + - type: board + name: arduino-diecimila + - type: board + name: arduino-leonardo + - type: board + name: arduino-mega2560 + - type: board + name: sparkfun-promicro + - type: board + name: trinket-pro + - type: mcu + name: atmega1280 + spec: atmega1280 + crate: atmega-hal + - type: mcu + name: atmega168 + spec: atmega168 + crate: atmega-hal + - type: mcu + name: atmega328pb + spec: atmega328p + crate: atmega-hal + - type: mcu + name: atmega48p + spec: atmega48p + crate: atmega-hal + - type: mcu + name: attiny85 + spec: attiny85 + crate: attiny-hal + - type: mcu + name: attiny88 + spec: attiny88 + crate: attiny-hal runs-on: ubuntu-latest steps: - name: Checkout code @@ -35,4 +65,28 @@ jobs: - name: Install avr-gcc, binutils, and libc run: sudo apt-get install -y avr-libc binutils-avr gcc-avr - name: Compile board crate and examples - run: cd "boards/${{ matrix.board }}" && cargo build --examples + if: "${{ matrix.m.type == 'board' }}" + run: cd "examples/${{ matrix.m.name }}" && cargo build --bins + - name: Test-compile HAL crate for an MCU + if: "${{ matrix.m.type == 'mcu' }}" + run: cd "mcu/${{ matrix.m.crate }}" && cargo build --features "${{ matrix.m.name }}" -Z build-std=core --target "../../avr-specs/avr-${{ matrix.m.spec }}.json" + + ravedude: + name: "ravedude" + runs-on: ubuntu-latest + steps: + - name: Checkout code + uses: actions/checkout@v2 + - name: Install Rust + uses: actions-rs/toolchain@v1 + with: + profile: minimal + toolchain: stable + override: true + - name: Install libudev + run: sudo apt-get update && sudo apt-get install -y libudev-dev + - name: Check ravedude + uses: actions-rs/cargo@v1 + with: + command: check + args: --manifest-path ravedude/Cargo.toml diff --git a/.github/workflows/docs.yml b/.github/workflows/docs.yml index 1681f75deb..019c18473f 100644 --- a/.github/workflows/docs.yml +++ b/.github/workflows/docs.yml @@ -3,7 +3,7 @@ name: Documentation on: push: branches: - - master + - main jobs: docs: @@ -19,8 +19,12 @@ jobs: toolchain: nightly-2021-01-07 override: true components: rust-src - - name: Build documentation - run: cargo doc --all + - name: Build documentation (arduino-hal) + run: cd arduino-hal/ && cargo doc --features arduino-uno + - name: Build documentation (atmega-hal) + run: cd mcu/atmega-hal/ && cargo doc --features atmega328p + - name: Build documentation (attiny-hal) + run: cd mcu/attiny-hal/ && cargo doc --features attiny85 - name: Deploy to GH-Pages uses: peaceiris/actions-gh-pages@v3 with: diff --git a/Cargo.toml b/Cargo.toml index a1d4b0bec9..dffef3af17 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -15,24 +15,25 @@ members = [ # The generic hal definitions "avr-hal-generic", - # The chip definitions - "chips/atmega1280-hal", - "chips/atmega168-hal", - "chips/atmega2560-hal", - "chips/atmega328p-hal", - "chips/atmega32u4-hal", - "chips/atmega48p-hal", - "chips/attiny85-hal", - "chips/attiny88-hal", + # MCU HAL crates + "mcu/atmega-hal", + "mcu/attiny-hal", - # The board crates - "boards/arduino-diecimila", - "boards/arduino-leonardo", - "boards/arduino-uno", - "boards/arduino-mega2560", - "boards/bigavr6", - "boards/sparkfun-pro-micro", - "boards/trinket", + # Higher level crates + "arduino-hal", + + # Examples + "examples/arduino-diecimila", + "examples/arduino-leonardo", + "examples/arduino-mega2560", + "examples/arduino-nano", + "examples/arduino-uno", + "examples/sparkfun-promicro", + "examples/trinket-pro", +] +exclude = [ + # The RAVEDUDE! Yeah! + "ravedude", ] [patch.crates-io] diff --git a/README.md b/README.md index 2294c52e0b..412ea0380c 100644 --- a/README.md +++ b/README.md @@ -1,193 +1,56 @@ -avr-hal ![Continuous Integration](https://github.com/Rahix/avr-hal/workflows/Continuous%20Integration/badge.svg) +avr-hal ![Continuous Integration](https://github.com/Rahix/avr-hal/workflows/Continuous%20Integration/badge.svg) [![arduino-hal docs](https://img.shields.io/badge/docs-arduino--hal-4d76ae)][arduino-hal docs] [![atmega-hal docs](https://img.shields.io/badge/docs-atmega--hal-4d76ae)][atmega-hal docs] [![attiny-hal docs](https://img.shields.io/badge/docs-attiny--hal-4d76ae)][attiny-hal docs] ======= -`embedded-hal` implementations for AVR microcontrollers. Based on the register definitions from [`avr-device`](https://github.com/Rahix/avr-device). +Hardware Abstraction Layer for AVR microcontrollers and common boards (for example Arduino). Based on the [`avr-device`](https://github.com/Rahix/avr-device) crate. -- [Quickstart](#quickstart) -- [Starting your own project](#starting-your-own-project) -- [Repository Structure](#repository-structure) - - [Supported MCUs](#supported-mcus) - - [Supported Boards](#supported-boards) +**This is a new version of `avr-hal`! Older versions can be found in the `old` branch but will no longer get support.** ## Quickstart -You need a nightly Rust compiler for compiling Rust code for AVR. **Note**: Due to a regression, versions after `nightly-2021-01-07` are currently broken (see [#124](https://github.com/Rahix/avr-hal/issues/124)). Please use that version of the compiler for now. You can install it using +You need a nightly Rust compiler for compiling Rust code for AVR. **Note**: Due to a regression, versions after `nightly-2021-01-07` are currently broken (see [#124](https://github.com/Rahix/avr-hal/issues/124)). Please use that version of the compiler for now. The correct version will be installed automatically. + +Next, install ["ravedude"](./ravedude), a tool which seamlessly integrates flashing your board into the usual cargo workflow: ```bash -rustup toolchain install nightly-2021-01-07 +cargo +stable install ravedude ``` -Go into `./boards/arduino-uno` (or the directory for whatever board you want), and run the following commands: +Go into `./examples/arduino-uno` (or the directory for whatever board you want), and run the following commands: ```bash -cd boards/arduino-uno - -# Now you are ready to build your first avr blink example! -cargo +nightly-2021-01-07 build --example uno-blink +cd examples/arduino-uno -# For some boards, you can even run it directly (this will attempt to flash it -# onto a connected board): -cargo +nightly-2021-01-07 run --example uno-blink - -# For others, you can find the binary file in -ls ../../target/avr-atmega328p/debug/examples/uno-blink.elf -# and e.g. create an ihex file using -avr-objcopy -S -j .text -j .data -O ihex uno-blink.elf uno-blink.hex +# Build and run it on a connected board +cargo run --bin uno-blink ``` ## Starting your own project -This is a step-by-step guide for creating a new project targeting Arduino Uno (`ATmega328P`). You can of course apply the same steps for any other microcontroller. - -1. Start by creating a new project: - ```bash - cargo new --bin avr-example - cd avr-example - ``` -2. If you're using rustup, you probably want to set an override for this directory, to use the nightly toolchain (as mentioned above, use `nightly-2021-01-07` for the time being): - ```bash - rustup override set nightly-2021-01-07 - ``` -3. Copy the target description for your MCU from [`avr-specs/`](./avr-specs) (e.g. [`avr-atmega328p.json`](avr-specs/avr-atmega328p.json)) into your project. -4. Create a file `.cargo/config.toml` with the following content: - ```toml - [build] - target = "avr-atmega328p.json" - - [unstable] - build-std = ["core"] - ``` -5. Fill `Cargo.toml` with these additional directives: - ```toml - [dependencies] - # A panic handler is needed. This is a crate with the most basic one. - # The `leonardo-panic` example shows a more elaborate version. - panic-halt = "0.2.0" - - [dependencies.arduino-uno] - git = "https://github.com/rahix/avr-hal" - rev = "" - # ^- Pin the dependency to a specific version. You should use the latest - # commit hash from the avr-hal master branch. You can find it here: - # - # https://github.com/rahix/avr-hal/commits/master - - # Configure the build for minimal size - [profile.dev] - panic = "abort" - lto = true - opt-level = "s" - - [profile.release] - panic = "abort" - codegen-units = 1 - debug = true - lto = true - opt-level = "s" - ``` - **Note**: If you at some point want to update to a newer version of `avr-hal`, you just need to put a later commit hash into the `rev =` field. For any breaking changes which might require you to fix something in your code, read the [CHANGELOG](https://github.com/Rahix/avr-hal/blob/master/CHANGELOG.md). -6. Start your project with this basic template: - ```rust - #![no_std] - #![no_main] - - // Pull in the panic handler from panic-halt - extern crate panic_halt; - - use arduino_uno::prelude::*; - - #[arduino_uno::entry] - fn main() -> ! { - let dp = arduino_uno::Peripherals::take().unwrap(); - - unimplemented!() - } - ``` -7. Build with these commands (make sure you're using _nightly_ rust!): - ```bash - cargo build - # or - cargo build --release - ``` - and find your binary in `target/avr-atmega328p/debug/` (or `target/avr-atmega328p/release`). - -8. (**Optional**): To make development as smooth as possible, you can configure a cargo runner for your board. This repository contains a few example scripts (e.g. [`uno-runner.sh`][uno-runner], [`leonardo-runner.sh`][leonardo-runner]) which you can copy into your project. You'll then need to add the following section to your `.cargo/config.toml`: - ```toml - [target.'cfg(target_arch = "avr")'] - runner = "./uno-runner.sh" - ``` - And that's it, now you can build an run your project in a single command! - ```bash - cargo run - # or - cargo run --release - ``` - -[leonardo-runner]: ./boards/arduino-leonardo/leonardo-runner.sh -[uno-runner]: ./boards/arduino-uno/uno-runner.sh +The best way to start your own project is via the [`avr-hal-template`](https://github.com/Rahix/avr-hal-template) which you can easily use with [`cargo-generate`](https://github.com/cargo-generate/cargo-generate): + +```bash +cargo generate --git https://github.com/Rahix/avr-hal-template.git +``` ## Repository Structure -This repository contains the following components: -* A generic crate containing implementations that can be used chip-independently and macros to create chip-dependent instances of peripheral abstractions. This crate is named [`avr-hal-generic`](./avr-hal-generic). -* HAL crates for each MCU in `chips/`. These make use of `avr-hal-generic` to create chip-specific definitions. -* Board Support Crates for popular hardware in `boards/`. They, for the most part, just re-export functionality from the chip-HAL, with the names that are printed on the PCB. - -### Supported MCUs -The following HAL crates currently exist. Take a look at the docs for more details on what's supported. - -* [`atmega168-hal`](./chips/atmega168-hal) - [Crate Documentation](https://rahix.github.io/avr-hal/atmega168_hal) - - [x] ADC - - [x] Digital IO - - [x] I2C using `TWI` - - [x] PWM - - [x] SPI - - [x] Spinning Delay - - [x] USART Serial -* [`atmega2560-hal`](./chips/atmega2560-hal) - [Crate Documentation](https://rahix.github.io/avr-hal/atmega2560_hal) - - [x] ADC (no differential channels yet) - - [x] Digital IO - - [x] I2C using `TWI` - - [x] SPI - - [x] Spinning Delay - - [x] USART Serial -* [`atmega328p-hal`](./chips/atmega328p-hal) - [Crate Documentation](https://rahix.github.io/avr-hal/atmega328p_hal) - - [x] ADC - - [x] Digital IO - - [x] I2C using `TWI` - - [x] SPI - - [x] Spinning Delay - - [x] USART Serial -* [`atmega32u4-hal`](./chips/atmega32u4-hal) - [Crate Documentation](https://rahix.github.io/avr-hal/atmega32u4_hal) - - [x] ADC (no differential channels yet) - - [x] Digital IO - - [x] I2C using `TWI` - - [x] SPI - - [x] Spinning Delay - - [x] USART Serial -* [`attiny85-hal`](./chips/attiny85-hal) - [Crate Documentation](https://rahix.github.io/avr-hal/attiny85_hal) - - [x] Digital IO - - [x] Spinning Delay -* [`attiny88-hal`](./chips/attiny88-hal) - [Crate Documentation](https://rahix.github.io/avr-hal/attiny88_hal) - - [x] Digital IO - - [x] I2C using `TWI` - - [x] SPI - - [x] Spinning Delay - -### Supported Boards -In `boards/` there are crates for the following hardware. Please note that this project is in no way affiliated with any of the vendors. - -Each board crate comes with a few examples showing how to use them. For more details, follow the links to the documentation. - -* [Arduino diecimila](./boards/arduino-diecimila) - [Crate Documentation](https://rahix.github.io/avr-hal/arduino_diecimila) - - [Website](https://www.arduino.cc/en/Main/Arduino_BoardDiecimila) -* [Arduino Leonardo](./boards/arduino-leonardo) - [Crate Documentation](https://rahix.github.io/avr-hal/arduino_leonardo) - - [Website](https://www.arduino.cc/en/Main/Arduino_BoardLeonardo) -* [Arduino Uno](./boards/arduino-uno) - [Crate Documentation](https://rahix.github.io/avr-hal/arduino_uno) - - [Website](https://store.arduino.cc/usa/arduino-uno-rev3) -* [Arduino Nano](./boards/arduino-uno) (via `arduino-uno` crate) - [Crate Documentation](https://rahix.github.io/avr-hal/arduino_uno) - - [Website](https://store.arduino.cc/arduino-nano) -* [Arduino Mega 2560](./boards/arduino-mega2560) - [Crate Documentation](https://rahix.github.io/avr-hal/arduino_mega2560) - - [Website](http://arduino.cc/en/Main/ArduinoBoardMega2560) -* [Adafruit Trinket (3V3 or 5V)](./boards/trinket) (**not** PRO!) - [Crate Documentation](https://rahix.github.io/avr-hal/trinket) - - [Website](https://learn.adafruit.com/introducing-trinket) -* [BigAVR 6](./boards/bigavr6) - [Crate Documentation](https://rahix.github.io/avr-hal/bigavr6) +The `avr-hal` repository is a workspace containing all components making up the HAL. Here is an overview: + +### `arduino-hal` [![arduino-hal docs](https://img.shields.io/badge/docs-git-4d76ae)][arduino-hal docs] +`arduino-hal` is the batteries-included HAL for all Arduino & similar boards. This is what you probably want to use for your projects. It is intentionally built to abstract away the differences between boards as much as possible. + +### `examples/*` +The [examples directory](./examples) contains lots of examples for common hardware. Do note that not all examples were ported to all boards, but there is a good chance that you can still use the code. Currently, the [Arduino Uno](./examples/arduino-uno/) crate contains the most examples. + +### `mcu/atmega-hal` [![atmega-hal docs](https://img.shields.io/badge/docs-git-4d76ae)][atmega-hal docs] , `mcu/attiny-hal` [![attiny-hal docs](https://img.shields.io/badge/docs-git-4d76ae)][attiny-hal docs] +HAL crates for AVR microcontroller families. If you have a custom board, you'll want to work with these crates. Please check their documentation for a list of supported MCUs. + +### `avr-hal-generic` [![avr-hal-generic docs](https://img.shields.io/badge/docs-git-4d76ae)][avr-hal-generic docs] +This is a generic crate containing most of the HAL implementaions in the form of macros which are instanciated in each HAL crate for the specific MCUs. If you intend to write drivers that work with any AVR chip, targeting `avr-hal-generic` is probably the best route. + +### `avr-specs/` +The `avr-specs/` directory contains rustc target definitions for all supported microcontrollers. You will need these for compiling rust code for AVR. The [`avr-hal-template`](https://github.com/Rahix/avr-hal-template) already includes them for convenience. + +[avr-hal-generic docs]: https://rahix.github.io/avr-hal/avr_hal_generic/index.html +[arduino-hal docs]: https://rahix.github.io/avr-hal/arduino_hal/index.html +[atmega-hal docs]: https://rahix.github.io/avr-hal/atmega_hal/index.html +[attiny-hal docs]: https://rahix.github.io/avr-hal/attiny_hal/index.html ## Disclaimer This project is not affiliated with either Microchip (former Atmel) nor any of the Vendors that created the boards supported in this repository. @@ -199,3 +62,6 @@ This project is not affiliated with either Microchip (former Atmel) nor any of t * MIT license ([LICENSE-MIT](LICENSE-MIT) or http://opensource.org/licenses/MIT) at your option. + +## Contribution +Unless you explicitly state otherwise, any contribution intentionally submitted for inclusion in the work by you, as defined in the Apache-2.0 license, shall be dual licensed as above, without any additional terms or conditions. diff --git a/arduino-hal/Cargo.toml b/arduino-hal/Cargo.toml new file mode 100644 index 0000000000..cea92d7ddc --- /dev/null +++ b/arduino-hal/Cargo.toml @@ -0,0 +1,52 @@ +[package] +name = "arduino-hal" +version = "0.1.0" +authors = ["Rahix "] +edition = "2018" + +[features] +default = ["rt"] +rt = ["avr-device/rt"] + +board-selected = [] +mcu-atmega=[] +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-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"] +sparkfun-promicro = ["mcu-atmega", "atmega-hal/atmega32u4", "board-selected"] + +[dependencies] +cfg-if = "1" +embedded-hal = "0.2.3" +ufmt = "0.1.0" + +[dependencies.void] +version = "1.0.2" +default-features = false + +[dependencies.avr-hal-generic] +path = "../avr-hal-generic/" + +[dependencies.atmega-hal] +path = "../mcu/atmega-hal/" +optional = true + +# Because this crate has its own check that at least one device is selected, we +# can safely "circumvent" the check in `atmega-hal`. Due to compile order, +# this allows us to show our error instead of the one from `atmega-hal` (which +# is much less helpful in this situation). +features = ["disable-device-selection-error"] + +[dependencies.avr-device] +version = "0.3" + +# Because this crate has its own check that at least one device is selected, we +# can safely "circumvent" the check in `avr-device`. +# +# Why would we want that? Otherwise, as `avr-device` is compiled first, its +# error will be shown and ours won't which leads to a degraded user experience +# as the displayed error message does not really tell what needs to be done... +features = ["device-selected"] diff --git a/arduino-hal/src/clock.rs b/arduino-hal/src/clock.rs new file mode 100644 index 0000000000..3fccb45d39 --- /dev/null +++ b/arduino-hal/src/clock.rs @@ -0,0 +1,27 @@ +//! MCU core clock support. +//! +//! This module contains common definitions to abtract over the MCU core clock speed. `avr-hal` +//! does not support changing the clock-speed at runtime. +//! +//! Most items in this module are re-exported from [`avr_hal_generic::clock`]. +pub use avr_hal_generic::clock::*; + +pub(crate) mod default { + /// Default clock speed for this board. + /// + /// `arduino-hal` contains a lot of type aliases for assuming this clock speed. As such it is + /// easiest to keep the processor at the selected default speed. + /// + /// However, you can of course still use other clock speeds but you'll then need to correctly + /// name the types from the HAL crate using your own clock definition. + #[cfg(any( + feature = "arduino-diecimila", + feature = "arduino-leonardo", + feature = "arduino-mega2560", + feature = "arduino-nano", + feature = "arduino-uno", + feature = "sparkfun-promicro", + feature = "trinket-pro", + ))] + pub type DefaultClock = avr_hal_generic::clock::MHz16; +} diff --git a/arduino-hal/src/delay.rs b/arduino-hal/src/delay.rs new file mode 100644 index 0000000000..8a05ca01ac --- /dev/null +++ b/arduino-hal/src/delay.rs @@ -0,0 +1,23 @@ +use embedded_hal::blocking::delay::{DelayMs, DelayUs}; + +/// Delay type for `embedded-hal` compatibility. +/// +/// This type can be used to pass a generic delay utility to `embedded-hal` drivers. For direct +/// use in `arduino-hal` code, usage of [`delay_ms`] or [`delay_us`] is preferred. +pub type Delay = avr_hal_generic::delay::Delay; + +/// Delay execution for a number of milliseconds. +/// +/// Busy-loop for the given time. This function assumes the default clock speed defined by +/// [`arduino_hal::DefaultClock`][crate::DefaultClock]. +pub fn delay_ms(ms: u16) { + Delay::new().delay_ms(ms) +} + +/// Delay execution for a number of microseconds. +/// +/// Busy-loop for the given time. This function assumes the default clock speed defined by +/// [`arduino_hal::DefaultClock`][crate::DefaultClock]. +pub fn delay_us(us: u32) { + Delay::new().delay_us(us) +} diff --git a/arduino-hal/src/lib.rs b/arduino-hal/src/lib.rs new file mode 100644 index 0000000000..f2841815ca --- /dev/null +++ b/arduino-hal/src/lib.rs @@ -0,0 +1,245 @@ +#![no_std] +#![feature(doc_cfg)] + +//! `arduino-hal` +//! ============= +//! Common HAL (hardware abstraction layer) for Arduino boards. +//! +//! **Note**: This version of the documentation was built for +#![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-nano", doc = "**Arduino Nano**.")] +#![cfg_attr(feature = "arduino-uno", doc = "**Arduino Uno**.")] +#![cfg_attr(feature = "sparkfun-promicro", doc = "**SparkFun ProMicro**.")] +#![cfg_attr(feature = "trinket-pro", doc = "**Trinket Pro**.")] +//! This means that only items which are available for this board are visible. If you are using a +//! different board, try building the documentation locally with +//! +//! ```text +//! cargo doc --open +//! ``` +//! +//! in your project (where `arduino-hal` is included with the feature-flag for your board). +//! +//! ## Usage +//! For setting up a new project, the [`avr-hal-template`](https://github.com/Rahix/avr-hal-template) +//! is the recommended baseline. Applications should be built ontop of the following skeleton: +//! +//! ```no_run +//! #![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); +//! +//! loop { } +//! } +//! ``` +//! +//! For examples, please check the `avr-hal` examples: + +#[cfg(not(feature = "board-selected"))] +compile_error!( + "This crate requires you to specify your target Arduino board as a feature. + + Please select one of the following + + * arduino-diecimila + * arduino-leonardo + * arduino-mega2560 + * arduino-nano + * arduino-uno + * sparkfun-promicro + * trinket-pro + " +); + +/// Attribute to declare the entry point of the program +/// +/// Exactly one entry point must be declared in the entire dependency tree. +/// +/// ``` +/// #[arduino_hal::entry] +/// fn main() -> ! { +/// // ... +/// } +/// ``` +/// +/// The entry function must have a signature of `[unsafe] fn() -> !`. +/// +/// This macro is a reexport of [`avr_device::entry`]. It is only available when the `rt` +/// (runtime) feature is selected (it is by default). +#[cfg(any(feature = "rt", doc))] +#[doc(cfg(feature = "rt"))] +pub use avr_device::entry; + +#[doc(no_inline)] +#[cfg(feature = "mcu-atmega")] +pub use atmega_hal as hal; +#[doc(no_inline)] +#[cfg(feature = "mcu-atmega")] +pub use atmega_hal::pac; + +#[doc(no_inline)] +#[cfg(feature = "board-selected")] +pub use hal::Peripherals; + +#[cfg(feature = "board-selected")] +pub mod clock; +#[cfg(feature = "board-selected")] +pub use clock::default::DefaultClock; + +#[cfg(feature = "board-selected")] +mod delay; +#[cfg(feature = "board-selected")] +pub use delay::{delay_ms, delay_us, Delay}; + +#[cfg(feature = "board-selected")] +pub mod port; +#[doc(no_inline)] +#[cfg(feature = "board-selected")] +pub use port::Pins; + +/// Analog to Digital converter. +#[cfg(feature = "board-selected")] +pub mod adc { + pub use crate::hal::adc::{ + channel, AdcChannel, AdcOps, AdcSettings, Channel, ClockDivider, ReferenceVoltage, + }; + + /// Check the [`avr_hal_generic::adc::Adc`] documentation. + pub type Adc = crate::hal::Adc; +} +#[doc(no_inline)] +#[cfg(feature = "board-selected")] +pub use adc::Adc; + +/// I2C bus controller. +#[cfg(feature = "board-selected")] +pub mod i2c { + pub use crate::hal::i2c::*; + + pub type I2c = crate::hal::i2c::I2c; +} +#[doc(no_inline)] +#[cfg(feature = "board-selected")] +pub use i2c::I2c; + +/// SPI controller. +#[cfg(feature = "board-selected")] +pub mod spi { + pub use crate::hal::spi::*; + + pub type Spi = crate::hal::spi::Spi; +} +#[doc(no_inline)] +#[cfg(feature = "board-selected")] +pub use spi::Spi; + +#[cfg(feature = "board-selected")] +pub mod usart { + pub use crate::hal::usart::{Baudrate, UsartOps}; + + pub type Usart = crate::hal::usart::Usart; + pub type UsartWriter = + crate::hal::usart::UsartWriter; + pub type UsartReader = + crate::hal::usart::UsartReader; +} +#[doc(no_inline)] +#[cfg(feature = "board-selected")] +pub use usart::Usart; + +#[cfg(feature = "board-selected")] +pub mod prelude { + cfg_if::cfg_if! { + if #[cfg(any( + feature = "arduino-diecimila", + feature = "arduino-mega2560", + feature = "arduino-uno" + ))] { + pub use crate::hal::usart::BaudrateArduinoExt as _; + } else { + pub use crate::hal::usart::BaudrateExt as _; + } + } + + pub use ufmt::uWrite as _; + pub use void::ResultVoidErrExt as _; + pub use void::ResultVoidExt as _; +} + +/// Convenience macro to instanciate the [`Pins`] struct for this board. +/// +/// # Example +/// ```no_run +/// let dp = arduino_hal::Peripherals::take().unwrap(); +/// let pins = arduino_hal::pins!(dp); +/// ``` +#[cfg(feature = "board-selected")] +#[macro_export] +macro_rules! pins { + ($p:expr) => { + $crate::Pins::with_mcu_pins($crate::hal::pins!($p)) + }; +} + +#[cfg(any(feature = "arduino-leonardo"))] +#[macro_export] +macro_rules! default_serial { + ($p:expr, $pins:expr, $baud:expr) => { + $crate::Usart::new( + $p.USART1, + $pins.d0, + $pins.d1.into_output(), + $crate::hal::usart::BaudrateExt::into_baudrate($baud), + ) + }; +} +#[cfg(any(feature = "sparkfun-promicro"))] +#[macro_export] +macro_rules! default_serial { + ($p:expr, $pins:expr, $baud:expr) => { + $crate::Usart::new( + $p.USART1, + $pins.rx, + $pins.tx.into_output(), + $crate::hal::usart::BaudrateExt::into_baudrate($baud), + ) + }; +} +// See comment in avr-hal-generic/src/usart.rs for why these boards use +// the BaudrateArduinoExt trait instead of BaudrateExt +#[cfg(any( + feature = "arduino-diecimila", + feature = "arduino-mega2560", + feature = "arduino-uno" +))] +#[macro_export] +macro_rules! default_serial { + ($p:expr, $pins:expr, $baud:expr) => { + $crate::Usart::new( + $p.USART0, + $pins.d0, + $pins.d1.into_output(), + $crate::hal::usart::BaudrateArduinoExt::into_baudrate($baud), + ) + }; +} +#[cfg(feature = "arduino-nano")] +#[macro_export] +macro_rules! default_serial { + ($p:expr, $pins:expr, $baud:expr) => { + $crate::Usart::new( + $p.USART0, + $pins.d0, + $pins.d1.into_output(), + $crate::hal::usart::BaudrateExt::into_baudrate($baud), + ) + }; +} diff --git a/boards/arduino-diecimila/src/pins.rs b/arduino-hal/src/port/diecimila.rs similarity index 74% rename from boards/arduino-diecimila/src/pins.rs rename to arduino-hal/src/port/diecimila.rs index d55ce0a39d..45e4ac3b36 100644 --- a/boards/arduino-diecimila/src/pins.rs +++ b/arduino-hal/src/port/diecimila.rs @@ -1,134 +1,129 @@ -use crate::hal::port::PortExt; +pub use atmega_hal::port::mode; +pub use atmega_hal::port::Pin; -avr_hal_generic::impl_board_pins! { - #[port_defs] - use crate::hal::port; +avr_hal_generic::renamed_pins! { + type Pin = Pin; - /// Generic DDR that works for all ports - pub struct DDR { - portb: crate::pac::PORTB, - portc: crate::pac::PORTC, - portd: crate::pac::PORTD, - } - - /// Reexport of the Diecimila's pins, with the names they have on the board - pub struct Pins { + /// Pins of the **Arduino Diecimila**. + /// + /// This struct is best initialized via the [`arduino_hal::pins!()`][pins] macro. + pub struct Pins from atmega_hal::Pins { /// `A0` /// /// * ADC0 (ADC input channel 0) /// * PCINT8 (pin change interrupt 8) - pub a0: portc::pc0::PC0, + pub a0: atmega_hal::port::PC0 = pc0, /// `A1` /// /// * ADC1 (ADC input channel 1) /// * PCINT9 (pin change interrupt 9) - pub a1: portc::pc1::PC1, + pub a1: atmega_hal::port::PC1 = pc1, /// `A2` /// /// * ADC2 (ADC input channel 2) /// * PCINT10 (pin change interrupt 10) - pub a2: portc::pc2::PC2, + pub a2: atmega_hal::port::PC2 = pc2, /// `A3` /// /// * ADC3 (ADC input channel 3) /// * PCINT11 (pin change interrupt 11) - pub a3: portc::pc3::PC3, + pub a3: atmega_hal::port::PC3 = pc3, /// `A4` /// /// * ADC4 (ADC input channel 4) /// * SDA (2-wire serial bus data input/output line) /// * PCINT12 (pin change interrupt 12) - pub a4: portc::pc4::PC4, + pub a4: atmega_hal::port::PC4 = pc4, /// `A5` /// /// ADC5 (ADC input channel 5) /// SCL (2-wire serial bus clock line) /// PCINT13 (pin change interrupt 13) - pub a5: portc::pc5::PC5, + pub a5: atmega_hal::port::PC5 = pc5, /// `D0` / `RX` /// /// * RXD (USART input pin) /// * PCINT16 (pin change interrupt 16) - pub d0: portd::pd0::PD0, + pub d0: atmega_hal::port::PD0 = pd0, /// `D1` / `TX` /// /// * TXD (USART output pin) /// * PCINT17 (pin change interrupt 17) - pub d1: portd::pd1::PD1, + pub d1: atmega_hal::port::PD1 = pd1, /// `D2` /// /// * INT0 (external interrupt 0 input) /// * PCINT18 (pin change interrupt 18) - pub d2: portd::pd2::PD2, + pub d2: atmega_hal::port::PD2 = pd2, /// `D3` /// /// * **PWM**: [atmega168_hal::timer::Timer3Pwm] /// * INT1 (external interrupt 1 input) /// * OC2B (Timer/Counter2 output compare match B output) /// * PCINT19 (pin change interrupt 19) - pub d3: portd::pd3::PD3, + pub d3: atmega_hal::port::PD3 = pd3, /// `D4` /// /// * XCK (USART external clock input/output) /// * T0 (Timer/Counter 0 external counter input) /// * PCINT20 (pin change interrupt 20) - pub d4: portd::pd4::PD4, + pub d4: atmega_hal::port::PD4 = pd4, /// `D5` /// /// * **PWM**: [atmega168_hal::timer::Timer3Pwm] /// * T1 (Timer/Counter 1 external counter input) /// * OC0B (Timer/Counter0 output compare match B output) /// * PCINT21 (pin change interrupt 21) - pub d5: portd::pd5::PD5, + pub d5: atmega_hal::port::PD5 = pd5, /// `D6` /// /// * **PWM**: [atmega168_hal::timer::Timer3Pwm] /// * AIN0 (analog comparator positive input) /// * OC0A (Timer/Counter0 output compare match A output) /// * PCINT22 (pin change interrupt 22) - pub d6: portd::pd6::PD6, + pub d6: atmega_hal::port::PD6 = pd6, /// `D7` /// /// * AIN1 (analog comparator negative input) /// * PCINT23 (pin change interrupt 23) - pub d7: portd::pd7::PD7, + pub d7: atmega_hal::port::PD7 = pd7, /// `D8` /// /// * ICP1 (Timer/Counter1 input capture input) /// * CLKO (divided system clock output) /// * PCINT0 (pin change interrupt 0) - pub d8: portb::pb0::PB0, + pub d8: atmega_hal::port::PB0 = pb0, /// `D9` /// /// * **PWM**: [atmega168_hal::timer::Timer3Pwm] /// * OC1A (Timer/Counter1 output compare match A output) /// * PCINT1 (pin change interrupt 1) - pub d9: portb::pb1::PB1, + pub d9: atmega_hal::port::PB1 = pb1, /// `D10` /// /// * **PWM**: [atmega168_hal::timer::Timer3Pwm] /// * SS (SPI bus master slave select) /// * OC1B (Timer/Counter1 output compare match B output) /// * PCINT2 (pin change interrupt 2) - pub d10: portb::pb2::PB2, + pub d10: atmega_hal::port::PB2 = pb2, /// `D11` /// /// * **PWM**: [atmega168_hal::timer::Timer3Pwm] /// * MOSI (SPI bus master/slave input) /// * OC2A (Timer/Counter2 output compare match A output) /// * PCINT3 (pin change interrupt 3) - pub d11: portb::pb3::PB3, + pub d11: atmega_hal::port::PB3 = pb3, /// `D12` /// /// * MISO (SPI bus master input/slave output) /// * PCINT4 (pin change interrupt 4) - pub d12: portb::pb4::PB4, + pub d12: atmega_hal::port::PB4 = pb4, /// `D13` /// /// * SCK (SPI bus master clock input) /// * PCINT5 (pin change interrupt 5) /// * L LED on Arduino Uno - pub d13: portb::pb5::PB5, + pub d13: atmega_hal::port::PB5 = pb5, } } diff --git a/boards/arduino-leonardo/src/pins.rs b/arduino-hal/src/port/leonardo.rs similarity index 66% rename from boards/arduino-leonardo/src/pins.rs rename to arduino-hal/src/port/leonardo.rs index 06c9ebc7c1..cc734412b1 100644 --- a/boards/arduino-leonardo/src/pins.rs +++ b/arduino-hal/src/port/leonardo.rs @@ -1,132 +1,125 @@ -use crate::hal::port::PortExt; +pub use atmega_hal::port::mode; +pub use atmega_hal::port::Pin; -avr_hal_generic::impl_board_pins! { - #[port_defs] - use crate::hal::port; +avr_hal_generic::renamed_pins! { + type Pin = Pin; - /// Generic DDR that works for all ports - pub struct DDR { - portb: crate::pac::PORTB, - portc: crate::pac::PORTC, - portd: crate::pac::PORTD, - porte: crate::pac::PORTE, - portf: crate::pac::PORTF, - } - - /// Reexport of the Leonardo's pins, with the names they have on the board - pub struct Pins { + /// Pins of the **Arduino Leonardo**. + /// + /// This struct is best initialized via the [`arduino_hal::pins!()`][pins] macro. + pub struct Pins from atmega_hal::Pins { /// `D0` / `RX` /// /// * `RX` (UART) /// * `INT2`: External Interrupt - pub d0: portd::pd2::PD2, + pub d0: atmega_hal::port::PD2 = pd2, /// `D1` / `TX` /// /// * `TX` (UART) /// * `INT3`: External Interrupt - pub d1: portd::pd3::PD3, + pub d1: atmega_hal::port::PD3 = pd3, /// `D2` / `SDA` /// /// * `SDA`: i2c/twi data /// * `INT1`: External Interrupt - pub d2: portd::pd1::PD1, + pub d2: atmega_hal::port::PD1 = pd1, /// `D3` / `SCL` /// /// * **PWM**: [atmega32u4_hal::timer::Timer0Pwm] /// * `SCL`: i2c/twi clock /// * `INT0`: External Interrupt /// * `OC0B`: Output Compare Channel `B` for Timer/Counter0 - pub d3: portd::pd0::PD0, + pub d3: atmega_hal::port::PD0 = pd0, /// `D4` - pub d4: portd::pd4::PD4, + pub d4: atmega_hal::port::PD4 = pd4, /// `D5` /// /// * **PWM**: [atmega32u4_hal::timer::Timer3Pwm] /// * `OC3A`: Output Compare Channel `A` for Timer/Counter3 /// * `#OC4A`: Inverted Output Compare Channel `A` for Timer/Counter4 (Not implemented) - pub d5: portc::pc6::PC6, + pub d5: atmega_hal::port::PC6 = pc6, /// `D6` /// /// * **PWM**: [atmega32u4_hal::timer::Timer4Pwm] /// * `OC4D`: Output Compare Channel `D` for Timer/Counter4 - pub d6: portd::pd7::PD7, + pub d6: atmega_hal::port::PD7 = pd7, /// `D7` /// /// * `INT6`: External Interrupt - pub d7: porte::pe6::PE6, + pub d7: atmega_hal::port::PE6 = pe6, /// `D8` - pub d8: portb::pb4::PB4, + pub d8: atmega_hal::port::PB4 = pb4, /// `D9` /// /// * **PWM**: [atmega32u4_hal::timer::Timer1Pwm] /// * `OC1A`: Output Compare Channel `A` for Timer/Counter1 /// * `#OC4B`: Inverted Output Compare Channel `B` for Timer/Counter4 (Not implemented) - pub d9: portb::pb5::PB5, + pub d9: atmega_hal::port::PB5 = pb5, /// `D10` /// /// * **PWM**: [atmega32u4_hal::timer::Timer1Pwm] /// * `OC1B`: Output Compare Channel `B` for Timer/Counter1 /// * `OC4B`: Output Compare Channel `B` for Timer/Counter4 (Not implemented) - pub d10: portb::pb6::PB6, + pub d10: atmega_hal::port::PB6 = pb6, /// `D11` /// /// * **PWM**: [atmega32u4_hal::timer::Timer0Pwm] /// * `OC0A`: Output Compare Channel `B` for Timer/Counter0 /// * `OC1C`: Output Compare Channel `C` for Timer/Counter1 - pub d11: portb::pb7::PB7, + pub d11: atmega_hal::port::PB7 = pb7, /// `D12` /// /// * `#OC4D`: Inverted Output Compare Channel `D` for Timer/Counter4 (Not implemented) - pub d12: portd::pd6::PD6, + pub d12: atmega_hal::port::PD6 = pd6, /// `D13` / `LED_BUILTIN` /// /// * Onboard LED /// * **PWM**: [atmega32u4_hal::timer::Timer4Pwm] /// * `OC4A`: Output Compare Channel `A` for Timer/Counter4 - pub d13: portc::pc7::PC7, + pub d13: atmega_hal::port::PC7 = pc7, /// `RX` /// /// Led for indicating inbound data. Also the CS pin. - pub led_rx: portb::pb0::PB0, + pub led_rx: atmega_hal::port::PB0 = pb0, /// `TX` /// /// Led for indicating outbound data - pub led_tx: portd::pd5::PD5, + pub led_tx: atmega_hal::port::PD5 = pd5, /// `SCLK` /// /// ICSP SCLK pin - pub sck: portb::pb1::PB1, + pub sck: atmega_hal::port::PB1 = pb1, /// `MOSI` /// /// ICSP MOSI pin - pub mosi: portb::pb2::PB2, + pub mosi: atmega_hal::port::PB2 = pb2, /// `MISO` /// /// ICSP MISO pin - pub miso: portb::pb3::PB3, + pub miso: atmega_hal::port::PB3 = pb3, /// `A0` /// /// * `ADC7` channel - pub a0: portf::pf7::PF7, + pub a0: atmega_hal::port::PF7 = pf7, /// `A1` /// /// * `ADC6` channel - pub a1: portf::pf6::PF6, + pub a1: atmega_hal::port::PF6 = pf6, /// `A2` /// /// * `ADC5` channel - pub a2: portf::pf5::PF5, + pub a2: atmega_hal::port::PF5 = pf5, /// `A3` /// /// * `ADC4` channel - pub a3: portf::pf4::PF4, + pub a3: atmega_hal::port::PF4 = pf4, /// `A4` /// /// * `ADC1` channel - pub a4: portf::pf1::PF1, + pub a4: atmega_hal::port::PF1 = pf1, /// `A5` /// /// * `ADC0` channel - pub a5: portf::pf0::PF0, + pub a5: atmega_hal::port::PF0 = pf0, } } diff --git a/boards/arduino-mega2560/src/pins.rs b/arduino-hal/src/port/mega2560.rs similarity index 69% rename from boards/arduino-mega2560/src/pins.rs rename to arduino-hal/src/port/mega2560.rs index ad856411a7..1e79bc7e5d 100644 --- a/boards/arduino-mega2560/src/pins.rs +++ b/arduino-hal/src/port/mega2560.rs @@ -1,96 +1,83 @@ -use crate::hal::port::PortExt; +pub use atmega_hal::port::mode; +pub use atmega_hal::port::Pin; -avr_hal_generic::impl_board_pins! { - #[port_defs] - use crate::hal::port; +avr_hal_generic::renamed_pins! { + type Pin = Pin; - /// Generic DDR that works for all ports - pub struct DDR { - porta: crate::pac::PORTA, - portb: crate::pac::PORTB, - portc: crate::pac::PORTC, - portd: crate::pac::PORTD, - porte: crate::pac::PORTE, - portf: crate::pac::PORTF, - portg: crate::pac::PORTG, - porth: crate::pac::PORTH, - portj: crate::pac::PORTJ, - portk: crate::pac::PORTK, - portl: crate::pac::PORTL, - } - - /// Reexport of the Mega 2560's pins, with the names they have on the board - pub struct Pins { + /// Pins of the **Arduino Mega 2560**. + /// + /// This struct is best initialized via the [`arduino_hal::pins!()`][pins] macro. + pub struct Pins from atmega_hal::Pins { /// `D0` / `RX0` /// /// * `RXD0` (USART0) /// * `PCINT8`: External Interrupt (Pin Change) - pub d0: porte::pe0::PE0, + pub d0: atmega_hal::port::PE0 = pe0, /// `D1` / `TX0` /// /// * `TXD0` (USART0) - pub d1: porte::pe1::PE1, + pub d1: atmega_hal::port::PE1 = pe1, /// `D2` /// /// * **PWM**: [atmega2560_hal::timer::Timer3Pwm] /// * `OC3B`: Output Compare Channel `B` for Timer/Counter3 /// * `INT4`: External Interrupt - pub d2: porte::pe4::PE4, + pub d2: atmega_hal::port::PE4 = pe4, /// `D3` /// /// * **PWM**: [atmega2560_hal::timer::Timer3Pwm] /// * `OC3C`: Output Compare Channel `C` for Timer/Counter3 /// * `INT5`: External Interrupt - pub d3: porte::pe5::PE5, + pub d3: atmega_hal::port::PE5 = pe5, /// `D4` /// /// * **PWM**: [atmega2560_hal::timer::Timer0Pwm] /// * `OC0B`: Output Compare Channel `B` for Timer/Counter0 - pub d4: portg::pg5::PG5, + pub d4: atmega_hal::port::PG5 = pg5, /// `D5` /// /// * **PWM**: [atmega2560_hal::timer::Timer3Pwm] /// * `OC3A`: Output Compare Channel `A` for Timer/Counter3 /// * `AIN1`: Analog Comparator Negative Input (Not Implemented) - pub d5: porte::pe3::PE3, + pub d5: atmega_hal::port::PE3 = pe3, /// `D6` /// /// * **PWM**: [atmega2560_hal::timer::Timer4Pwm] /// * `OC4A`: Output Compare Channel `A` for Timer/Counter4 - pub d6: porth::ph3::PH3, + pub d6: atmega_hal::port::PH3 = ph3, /// `D7` /// /// * **PWM**: [atmega2560_hal::timer::Timer4Pwm] /// * `OC4B`: Output Compare Channel `B` for Timer/Counter4 - pub d7: porth::ph4::PH4, + pub d7: atmega_hal::port::PH4 = ph4, /// `D8` /// /// * **PWM**: [atmega2560_hal::timer::Timer4Pwm] /// * `OC4C`: Output Compare Channel `C` for Timer/Counter4 - pub d8: porth::ph5::PH5, + pub d8: atmega_hal::port::PH5 = ph5, /// `D9` /// /// * **PWM**: [atmega2560_hal::timer::Timer2Pwm] /// * `OC2B`: Output Compare Channel `B` for Timer/Counter2 - pub d9: porth::ph6::PH6, + pub d9: atmega_hal::port::PH6 = ph6, /// `D10` /// /// * **PWM**: [atmega2560_hal::timer::Timer2Pwm] /// * `OC2B`: Output Compare Channel `B` for Timer/Counter2 /// * `PCINT4`: External Interrupt (Pin Change) - pub d10: portb::pb4::PB4, + pub d10: atmega_hal::port::PB4 = pb4, /// `D11` /// /// * **PWM**: [atmega2560_hal::timer::Timer1Pwm] /// * `OC1A`: Output Compare Channel `A` for Timer/Counter1 /// * `PCINT5`: External Interrupt (Pin Change) - pub d11: portb::pb5::PB5, + pub d11: atmega_hal::port::PB5 = pb5, /// `D12` /// /// * **PWM**: [atmega2560_hal::timer::Timer1Pwm] /// * `OC1B`: Output Compare Channel `B` for Timer/Counter1 /// * `PCINT6`: External Interrupt (Pin Change) - pub d12: portb::pb6::PB6, + pub d12: atmega_hal::port::PB6 = pb6, /// `D13` /// /// * Onboard LED @@ -99,251 +86,251 @@ avr_hal_generic::impl_board_pins! { /// * `OC0A`: Output Compare Channel `A` for Timer/Counter0 /// * `OC1C`: Output Compare Channel `C` for Timer/Counter1 /// * `PCINT7`: External Interrupt (Pin Change) - pub d13: portb::pb7::PB7, + pub d13: atmega_hal::port::PB7 = pb7, /// `D14` / `TX3` /// /// * `TXD3` (USART3) /// * `PCINT10`: External Interrupt (Pin Change) - pub d14: portj::pj1::PJ1, + pub d14: atmega_hal::port::PJ1 = pj1, /// `D15` / `RX3` /// /// * `RXD3` (USART3) /// * `PCINT9`: External Interrupt (Pin Change) - pub d15: portj::pj0::PJ0, + pub d15: atmega_hal::port::PJ0 = pj0, /// `D16` / `TX2` /// /// * `TXD2` (USART2) - pub d16: porth::ph1::PH1, + pub d16: atmega_hal::port::PH1 = ph1, /// `D17` / `RX2` /// /// * `RXD2` (USART2) - pub d17: porth::ph0::PH0, + pub d17: atmega_hal::port::PH0 = ph0, /// `D18` / `TX1` /// /// * `TXD1` (USART1) /// * `INT3`: External Interrupt - pub d18: portd::pd3::PD3, + pub d18: atmega_hal::port::PD3 = pd3, /// `D19` / `RX1` /// /// * `RXD1` (USART1) /// * `INT2`: External Interrupt - pub d19: portd::pd2::PD2, + pub d19: atmega_hal::port::PD2 = pd2, /// `D20` / `SDA` /// /// * `SDA`: i2c/twi data /// * `INT1`: External Interrupt - pub d20: portd::pd1::PD1, + pub d20: atmega_hal::port::PD1 = pd1, /// `D21` / `SCL` /// /// * `SCL`: i2c/twi clock /// * `INT0`: External Interrupt - pub d21: portd::pd0::PD0, + pub d21: atmega_hal::port::PD0= pd0, /// `D22` /// /// * `AD0`: External memory interface - pub d22: porta::pa0::PA0, + pub d22: atmega_hal::port::PA0 = pa0, /// `D23` /// /// * `AD1`: External memory interface - pub d23: porta::pa1::PA1, + pub d23: atmega_hal::port::PA1 = pa1, /// `D24` /// /// * `AD2`: External memory interface - pub d24: porta::pa2::PA2, + pub d24: atmega_hal::port::PA2 = pa2, /// `D25` /// /// * `AD3`: External memory interface - pub d25: porta::pa3::PA3, + pub d25: atmega_hal::port::PA3 = pa3, /// `D26` /// /// * `AD4`: External memory interface - pub d26: porta::pa4::PA4, + pub d26: atmega_hal::port::PA4 = pa4, /// `D27` /// /// * `AD5`: External memory interface - pub d27: porta::pa5::PA5, + pub d27: atmega_hal::port::PA5 = pa5, /// `D28` /// /// * `AD6`: External memory interface - pub d28: porta::pa6::PA6, + pub d28: atmega_hal::port::PA6 = pa6, /// `D29` /// /// * `AD7`: External memory interface - pub d29: porta::pa7::PA7, + pub d29: atmega_hal::port::PA7 = pa7, /// `D30` /// /// * `AD15`: External memory interface - pub d30: portc::pc7::PC7, + pub d30: atmega_hal::port::PC7 = pc7, /// `D31` /// /// * `AD14`: External memory interface - pub d31: portc::pc6::PC6, + pub d31: atmega_hal::port::PC6 = pc6, /// `D32` /// /// * `AD13`: External memory interface - pub d32: portc::pc5::PC5, + pub d32: atmega_hal::port::PC5 = pc5, /// `D33` /// /// * `AD12`: External memory interface - pub d33: portc::pc4::PC4, + pub d33: atmega_hal::port::PC4 = pc4, /// `D34` /// /// * `AD11`: External memory interface - pub d34: portc::pc3::PC3, + pub d34: atmega_hal::port::PC3 = pc3, /// `D35` /// /// * `AD10`: External memory interface - pub d35: portc::pc2::PC2, + pub d35: atmega_hal::port::PC2 = pc2, /// `D36` /// /// * `AD9`: External memory interface - pub d36: portc::pc1::PC1, + pub d36: atmega_hal::port::PC1 = pc1, /// `D37` /// /// * `AD8`: External memory interface - pub d37: portc::pc0::PC0, + pub d37: atmega_hal::port::PC0 = pc0, /// `D38` /// /// * `T0`: Clock Input for Timer/Counter0 - pub d38: portd::pd7::PD7, + pub d38: atmega_hal::port::PD7 = pd7, /// `D39` /// /// * `ALE`: External memory Address Latch Enable - pub d39: portg::pg2::PG2, + pub d39: atmega_hal::port::PG2 = pg2, /// `D40` /// /// `RD`: External memory Read Strobe - pub d40: portg::pg1::PG1, + pub d40: atmega_hal::port::PG1 = pg1, /// `D41` /// /// `WR`: External memory Write Strobe - pub d41: portg::pg0::PG0, + pub d41: atmega_hal::port::PG0 = pg0, /// `D42` - pub d42: portl::pl7::PL7, + pub d42: atmega_hal::port::PL7 = pl7, /// `D43` - pub d43: portl::pl6::PL6, + pub d43: atmega_hal::port::PL6 = pl6, /// `D44` /// /// * **PWM**: [atmega2560_hal::timer::Timer5Pwm] /// * `OC5C`: Output Compare Channel `C` for Timer/Counter5 - pub d44: portl::pl5::PL5, + pub d44: atmega_hal::port::PL5 = pl5, /// `D45` /// /// * **PWM**: [atmega2560_hal::timer::Timer5Pwm] /// * `OC5B`: Output Compare Channel `B` for Timer/Counter5 - pub d45: portl::pl4::PL4, + pub d45: atmega_hal::port::PL4 = pl4, /// `D46` /// /// * **PWM**: [atmega2560_hal::timer::Timer5Pwm] /// * `OC5A`: Output Compare Channel `A` for Timer/Counter5 - pub d46: portl::pl3::PL3, + pub d46: atmega_hal::port::PL3 = pl3, /// `D47` /// /// * `T5`: Clock Input for Timer/Counter5 - pub d47: portl::pl2::PL2, + pub d47: atmega_hal::port::PL2 = pl2, /// `D48` /// /// * `ICP5`: Input Capture Trigger for Timer/Counter5 - pub d48: portl::pl1::PL1, + pub d48: atmega_hal::port::PL1 = pl1, /// `D49` /// /// * `ICP4`: Input Capture Trigger for Timer/Counter4 - pub d49: portl::pl0::PL0, + pub d49: atmega_hal::port::PL0 = pl0, /// `D50` /// /// * `MISO`: SPI bus Master In/Slave Out /// * `PCINT3`: External Interrupt (Pin Change) - pub d50: portb::pb3::PB3, + pub d50: atmega_hal::port::PB3 = pb3, /// `D51` /// /// * `MOSI`: SPI bus Master Out/Slave In /// * `PCINT2`: External Interrupt (Pin Change) - pub d51: portb::pb2::PB2, + pub d51: atmega_hal::port::PB2 = pb2, /// `D52` /// /// * `SCK`: SPI bus Serial Clock /// * `PCINT1`: External Interrupt (Pin Change) - pub d52: portb::pb1::PB1, + pub d52: atmega_hal::port::PB1 = pb1, /// `D53` /// /// * `SS`: SPI bus Slave Select /// * `PCINT0`: External Interrupt (Pin Change) - pub d53: portb::pb0::PB0, + pub d53: atmega_hal::port::PB0 = pb0, /// `A0` /// /// * `ADC0`: A/D converter input 0 - pub a0: portf::pf0::PF0, + pub a0: atmega_hal::port::PF0 = pf0, /// `A1` /// /// * `ADC1`: A/D converter input 1 - pub a1: portf::pf1::PF1, + pub a1: atmega_hal::port::PF1 = pf1, /// `A2` /// /// * `ADC2`: A/D converter input 2 - pub a2: portf::pf2::PF2, + pub a2: atmega_hal::port::PF2 = pf2, /// `A3` /// /// * `ADC3`: A/D converter input 3 - pub a3: portf::pf3::PF3, + pub a3: atmega_hal::port::PF3 = pf3, /// `A4` /// /// * `ADC4`: A/D converter input 4 /// * `TCK`: JTAG test clock - pub a4: portf::pf4::PF4, + pub a4: atmega_hal::port::PF4 = pf4, /// `A5` /// /// * `ADC5`: A/D converter input 5 /// * `TMS`: JTAG test mode select - pub a5: portf::pf5::PF5, + pub a5: atmega_hal::port::PF5 = pf5, /// `A6` /// /// * `ADC6`: A/D converter input 6 /// * `TDO`: JTAG test data output - pub a6: portf::pf6::PF6, + pub a6: atmega_hal::port::PF6 = pf6, /// `A7` /// /// * `ADC7`: A/D converter input 7 /// * `TDI`: JTAG test data input - pub a7: portf::pf7::PF7, + pub a7: atmega_hal::port::PF7 = pf7, /// `A8` /// /// * `ADC8`: A/D converter input 8 /// * `PCINT16`: External Interrupt (Pin Change) - pub a8: portk::pk0::PK0, + pub a8: atmega_hal::port::PK0 = pk0, /// `A9` /// /// * `ADC9`: A/D converter input 9 /// * `PCINT17`: External Interrupt (Pin Change) - pub a9: portk::pk1::PK1, + pub a9: atmega_hal::port::PK1 = pk1, /// `A10` /// /// * `ADC10`: A/D converter input 10 /// * `PCINT18`: External Interrupt (Pin Change) - pub a10: portk::pk2::PK2, + pub a10: atmega_hal::port::PK2 = pk2, /// `A11` /// /// * `ADC11`: A/D converter input 11 /// * `PCINT19`: External Interrupt (Pin Change) - pub a11: portk::pk3::PK3, + pub a11: atmega_hal::port::PK3 = pk3, /// `A12` /// /// * `ADC12`: A/D converter input 12 /// * `PCINT20`: External Interrupt (Pin Change) - pub a12: portk::pk4::PK4, + pub a12: atmega_hal::port::PK4 = pk4, /// `A13` /// /// * `ADC13`: A/D converter input 13 /// * `PCINT21`: External Interrupt (Pin Change) - pub a13: portk::pk5::PK5, + pub a13: atmega_hal::port::PK5 = pk5, /// `A14` /// /// * `ADC14`: A/D converter input 14 /// * `PCINT22`: External Interrupt (Pin Change) - pub a14: portk::pk6::PK6, + pub a14: atmega_hal::port::PK6 = pk6, /// `A15` /// /// * `ADC15`: A/D converter input 15 /// * `PCINT23`: External Interrupt (Pin Change) - pub a15: portk::pk7::PK7, + pub a15: atmega_hal::port::PK7 = pk7, } } diff --git a/arduino-hal/src/port/mod.rs b/arduino-hal/src/port/mod.rs new file mode 100644 index 0000000000..b2480d8304 --- /dev/null +++ b/arduino-hal/src/port/mod.rs @@ -0,0 +1,41 @@ +//! GPIO & Pin control. +//! +//! This module contains a [`Pins`] struct which represents all pins of the board. The [`Pins`] +//! struct is most easily constructed using the [`arduino_hal::pins!()`][pins] macro: +//! +//! ```no_run +//! let dp = arduino_hal::Peripherals::take().unwrap(); +//! let pins = arduino_hal::pins!(dp); +//! ``` +//! +//! Additionally, the [`mode`] submodule contains all valid types for the `MODE` generic parameter +//! of a pin. The [`Pin`] type-alias represents a pin which can represent _any_ of the pins +//! dynamically (while usually each pin has its own type). +//! +//! Check the documentation for [`avr_hal_generic::port::Pin`] for a detailed explanation of GPIO +//! pins in `avr-hal`. + +#[cfg(feature = "arduino-diecimila")] +mod diecimila; +#[cfg(feature = "arduino-diecimila")] +pub use diecimila::*; +#[cfg(feature = "arduino-leonardo")] +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-nano", feature = "arduino-uno"))] +mod uno; +#[cfg(any(feature = "arduino-nano", feature = "arduino-uno"))] +pub use uno::*; +#[cfg(feature = "sparkfun-promicro")] +mod promicro; +#[cfg(feature = "sparkfun-promicro")] +pub use promicro::*; +#[cfg(feature = "trinket-pro")] +mod trinket_pro; +#[cfg(feature = "trinket-pro")] +pub use trinket_pro::*; diff --git a/arduino-hal/src/port/promicro.rs b/arduino-hal/src/port/promicro.rs new file mode 100644 index 0000000000..d76c97c28d --- /dev/null +++ b/arduino-hal/src/port/promicro.rs @@ -0,0 +1,78 @@ +pub use atmega_hal::port::mode; +pub use atmega_hal::port::Pin; + +avr_hal_generic::renamed_pins! { + type Pin = Pin; + + /// Pins of the **SparkFun ProMicro**. + /// + /// This struct is best initialized via the [`arduino_hal::pins!()`][pins] macro. + pub struct Pins from atmega_hal::Pins { + /// `RX` + /// + /// `RX` (UART) + pub rx: atmega_hal::port::PD2 = pd2, + /// `TX` + /// + /// `TX` (UART) + pub tx: atmega_hal::port::PD3 = pd3, + /// `D2` / `SDA` + /// + /// `SDA`: i2c/twi data + pub d2: atmega_hal::port::PD1 = pd1, + /// `D3` / `SCL` + /// + /// `SCL`: i2c/twi clock + pub d3: atmega_hal::port::PD0 = pd0, + /// `D4` + pub d4: atmega_hal::port::PD4 = pd4, + /// `D5` + pub d5: atmega_hal::port::PC6 = pc6, + /// `D6` + pub d6: atmega_hal::port::PD7 = pd7, + /// `D7` + pub d7: atmega_hal::port::PE6 = pe6, + /// `D8` + pub d8: atmega_hal::port::PB4 = pb4, + /// `D9` + pub d9: atmega_hal::port::PB5 = pb5, + /// `D10` + pub d10: atmega_hal::port::PB6 = pb6, + /// `LED_RX` + /// + /// Led for indicating inbound data (yellow). Also the CS pin for SPI. + pub led_rx: atmega_hal::port::PB0 = pb0, + /// `LED_TX` + /// + /// Led for indicating outbound data (green). + pub led_tx: atmega_hal::port::PD5 = pd5, + /// `D15`, `SCK` + /// + /// ICSP SCLK pin + pub d15: atmega_hal::port::PB1 = pb1, + /// `D14`, `MISO` + /// + /// ICSP MISO pin + pub d16: atmega_hal::port::PB3 = pb3, + /// `D16`, `MOSI` + /// + /// ICSP MOSI pin + pub d14: atmega_hal::port::PB2 = pb2, + /// `A0` + /// + /// `ADC7` channel + pub a0: atmega_hal::port::PF7 = pf7, + /// `A1` + /// + /// `ADC6` channel + pub a1: atmega_hal::port::PF6 = pf6, + /// `A2` + /// + /// `ADC5` channel + pub a2: atmega_hal::port::PF5 = pf5, + /// `A3` + /// + /// `ADC4` channel + pub a3: atmega_hal::port::PF4 = pf4, + } +} diff --git a/arduino-hal/src/port/trinket_pro.rs b/arduino-hal/src/port/trinket_pro.rs new file mode 100644 index 0000000000..adadbd11bd --- /dev/null +++ b/arduino-hal/src/port/trinket_pro.rs @@ -0,0 +1,119 @@ +pub use atmega_hal::port::mode; +pub use atmega_hal::port::Pin; + +avr_hal_generic::renamed_pins! { + type Pin = Pin; + + /// Pins of the **Trinket Pro**. + /// + /// This struct is best initialized via the [`arduino_hal::pins!()`][pins] macro. + pub struct Pins from atmega_hal::Pins { + /// `A0` + /// + /// * ADC0 (ADC input channel 0) + /// * PCINT8 (pin change interrupt 8) + pub a0: atmega_hal::port::PC0 = pc0, + /// `A1` + /// + /// * ADC1 (ADC input channel 1) + /// * PCINT9 (pin change interrupt 9) + pub a1: atmega_hal::port::PC1 = pc1, + /// `A2` + /// + /// * ADC2 (ADC input channel 2) + /// * PCINT10 (pin change interrupt 10) + pub a2: atmega_hal::port::PC2 = pc2, + /// `A3` + /// + /// * ADC3 (ADC input channel 3) + /// * PCINT11 (pin change interrupt 11) + pub a3: atmega_hal::port::PC3 = pc3, + /// `A4` + /// + /// * ADC4 (ADC input channel 4) + /// * SDA (2-wire serial bus data input/output line) + /// * PCINT12 (pin change interrupt 12) + pub a4: atmega_hal::port::PC4 = pc4, + /// `A5` + /// + /// ADC5 (ADC input channel 5) + /// SCL (2-wire serial bus clock line) + /// PCINT13 (pin change interrupt 13) + pub a5: atmega_hal::port::PC5 = pc5, + + /// `D0` / `RX` + /// + /// * RXD (USART input pin) + /// * PCINT16 (pin change interrupt 16) + pub d0: atmega_hal::port::PD0 = pd0, + /// `D1` / `TX` + /// + /// * TXD (USART output pin) + /// * PCINT17 (pin change interrupt 17) + pub d1: atmega_hal::port::PD1 = pd1, + /// `D3` + /// + /// * **PWM**: [atmega328p_hal::timer::Timer3Pwm] + /// * INT1 (external interrupt 1 input) + /// * OC2B (Timer/Counter2 output compare match B output) + /// * PCINT19 (pin change interrupt 19) + pub d3: atmega_hal::port::PD3 = pd3, + /// `D4` + /// + /// * XCK (USART external clock input/output) + /// * T0 (Timer/Counter 0 external counter input) + /// * PCINT20 (pin change interrupt 20) + pub d4: atmega_hal::port::PD4 = pd4, + /// `D5` + /// + /// * **PWM**: [atmega328p_hal::timer::Timer3Pwm] + /// * T1 (Timer/Counter 1 external counter input) + /// * OC0B (Timer/Counter0 output compare match B output) + /// * PCINT21 (pin change interrupt 21) + pub d5: atmega_hal::port::PD5 = pd5, + /// `D6` + /// + /// * **PWM**: [atmega328p_hal::timer::Timer3Pwm] + /// * AIN0 (analog comparator positive input) + /// * OC0A (Timer/Counter0 output compare match A output) + /// * PCINT22 (pin change interrupt 22) + pub d6: atmega_hal::port::PD6 = pd6, + /// `D8` + /// + /// * ICP1 (Timer/Counter1 input capture input) + /// * CLKO (divided system clock output) + /// * PCINT0 (pin change interrupt 0) + pub d8: atmega_hal::port::PB0 = pb0, + /// `D9` + /// + /// * **PWM**: [atmega328p_hal::timer::Timer3Pwm] + /// * OC1A (Timer/Counter1 output compare match A output) + /// * PCINT1 (pin change interrupt 1) + pub d9: atmega_hal::port::PB1 = pb1, + /// `D10` + /// + /// * **PWM**: [atmega328p_hal::timer::Timer3Pwm] + /// * SS (SPI bus master slave select) + /// * OC1B (Timer/Counter1 output compare match B output) + /// * PCINT2 (pin change interrupt 2) + pub d10: atmega_hal::port::PB2 = pb2, + /// `D11` + /// + /// * **PWM**: [atmega328p_hal::timer::Timer3Pwm] + /// * MOSI (SPI bus master/slave input) + /// * OC2A (Timer/Counter2 output compare match A output) + /// * PCINT3 (pin change interrupt 3) + pub d11: atmega_hal::port::PB3 = pb3, + /// `D12` + /// + /// * MISO (SPI bus master input/slave output) + /// * PCINT4 (pin change interrupt 4) + pub d12: atmega_hal::port::PB4 = pb4, + /// `D13` + /// + /// * SCK (SPI bus master clock input) + /// * PCINT5 (pin change interrupt 5) + /// * L LED on Trinket Pro + pub d13: atmega_hal::port::PB5 = pb5, + } +} diff --git a/boards/arduino-uno/src/pins.rs b/arduino-hal/src/port/uno.rs similarity index 74% rename from boards/arduino-uno/src/pins.rs rename to arduino-hal/src/port/uno.rs index ae5a0b7742..5f0c39a4d3 100644 --- a/boards/arduino-uno/src/pins.rs +++ b/arduino-hal/src/port/uno.rs @@ -1,134 +1,129 @@ -use crate::hal::port::PortExt; +pub use atmega_hal::port::mode; +pub use atmega_hal::port::Pin; -avr_hal_generic::impl_board_pins! { - #[port_defs] - use crate::hal::port; +avr_hal_generic::renamed_pins! { + type Pin = Pin; - /// Generic DDR that works for all ports - pub struct DDR { - portb: crate::pac::PORTB, - portc: crate::pac::PORTC, - portd: crate::pac::PORTD, - } - - /// Reexport of the Uno's pins, with the names they have on the board - pub struct Pins { + /// Pins of the **Arduino Uno**. + /// + /// This struct is best initialized via the [`arduino_hal::pins!()`][pins] macro. + pub struct Pins from atmega_hal::Pins { /// `A0` /// /// * ADC0 (ADC input channel 0) /// * PCINT8 (pin change interrupt 8) - pub a0: portc::pc0::PC0, + pub a0: atmega_hal::port::PC0 = pc0, /// `A1` /// /// * ADC1 (ADC input channel 1) /// * PCINT9 (pin change interrupt 9) - pub a1: portc::pc1::PC1, + pub a1: atmega_hal::port::PC1 = pc1, /// `A2` /// /// * ADC2 (ADC input channel 2) /// * PCINT10 (pin change interrupt 10) - pub a2: portc::pc2::PC2, + pub a2: atmega_hal::port::PC2 = pc2, /// `A3` /// /// * ADC3 (ADC input channel 3) /// * PCINT11 (pin change interrupt 11) - pub a3: portc::pc3::PC3, + pub a3: atmega_hal::port::PC3 = pc3, /// `A4` /// /// * ADC4 (ADC input channel 4) /// * SDA (2-wire serial bus data input/output line) /// * PCINT12 (pin change interrupt 12) - pub a4: portc::pc4::PC4, + pub a4: atmega_hal::port::PC4 = pc4, /// `A5` /// /// ADC5 (ADC input channel 5) /// SCL (2-wire serial bus clock line) /// PCINT13 (pin change interrupt 13) - pub a5: portc::pc5::PC5, + pub a5: atmega_hal::port::PC5 = pc5, /// `D0` / `RX` /// /// * RXD (USART input pin) /// * PCINT16 (pin change interrupt 16) - pub d0: portd::pd0::PD0, + pub d0: atmega_hal::port::PD0 = pd0, /// `D1` / `TX` /// /// * TXD (USART output pin) /// * PCINT17 (pin change interrupt 17) - pub d1: portd::pd1::PD1, + pub d1: atmega_hal::port::PD1 = pd1, /// `D2` /// /// * INT0 (external interrupt 0 input) /// * PCINT18 (pin change interrupt 18) - pub d2: portd::pd2::PD2, + pub d2: atmega_hal::port::PD2 = pd2, /// `D3` /// /// * **PWM**: [atmega328p_hal::timer::Timer3Pwm] /// * INT1 (external interrupt 1 input) /// * OC2B (Timer/Counter2 output compare match B output) /// * PCINT19 (pin change interrupt 19) - pub d3: portd::pd3::PD3, + pub d3: atmega_hal::port::PD3 = pd3, /// `D4` /// /// * XCK (USART external clock input/output) /// * T0 (Timer/Counter 0 external counter input) /// * PCINT20 (pin change interrupt 20) - pub d4: portd::pd4::PD4, + pub d4: atmega_hal::port::PD4 = pd4, /// `D5` /// /// * **PWM**: [atmega328p_hal::timer::Timer3Pwm] /// * T1 (Timer/Counter 1 external counter input) /// * OC0B (Timer/Counter0 output compare match B output) /// * PCINT21 (pin change interrupt 21) - pub d5: portd::pd5::PD5, + pub d5: atmega_hal::port::PD5 = pd5, /// `D6` /// /// * **PWM**: [atmega328p_hal::timer::Timer3Pwm] /// * AIN0 (analog comparator positive input) /// * OC0A (Timer/Counter0 output compare match A output) /// * PCINT22 (pin change interrupt 22) - pub d6: portd::pd6::PD6, + pub d6: atmega_hal::port::PD6 = pd6, /// `D7` /// /// * AIN1 (analog comparator negative input) /// * PCINT23 (pin change interrupt 23) - pub d7: portd::pd7::PD7, + pub d7: atmega_hal::port::PD7 = pd7, /// `D8` /// /// * ICP1 (Timer/Counter1 input capture input) /// * CLKO (divided system clock output) /// * PCINT0 (pin change interrupt 0) - pub d8: portb::pb0::PB0, + pub d8: atmega_hal::port::PB0 = pb0, /// `D9` /// /// * **PWM**: [atmega328p_hal::timer::Timer3Pwm] /// * OC1A (Timer/Counter1 output compare match A output) /// * PCINT1 (pin change interrupt 1) - pub d9: portb::pb1::PB1, + pub d9: atmega_hal::port::PB1 = pb1, /// `D10` /// /// * **PWM**: [atmega328p_hal::timer::Timer3Pwm] /// * SS (SPI bus master slave select) /// * OC1B (Timer/Counter1 output compare match B output) /// * PCINT2 (pin change interrupt 2) - pub d10: portb::pb2::PB2, + pub d10: atmega_hal::port::PB2 = pb2, /// `D11` /// /// * **PWM**: [atmega328p_hal::timer::Timer3Pwm] /// * MOSI (SPI bus master/slave input) /// * OC2A (Timer/Counter2 output compare match A output) /// * PCINT3 (pin change interrupt 3) - pub d11: portb::pb3::PB3, + pub d11: atmega_hal::port::PB3 = pb3, /// `D12` /// /// * MISO (SPI bus master input/slave output) /// * PCINT4 (pin change interrupt 4) - pub d12: portb::pb4::PB4, + pub d12: atmega_hal::port::PB4 = pb4, /// `D13` /// /// * SCK (SPI bus master clock input) /// * PCINT5 (pin change interrupt 5) /// * L LED on Arduino Uno - pub d13: portb::pb5::PB5, + pub d13: atmega_hal::port::PB5 = pb5, } } diff --git a/avr-hal-generic/src/adc.rs b/avr-hal-generic/src/adc.rs index ae26597465..41dcadd4e0 100644 --- a/avr-hal-generic/src/adc.rs +++ b/avr-hal-generic/src/adc.rs @@ -1,18 +1,24 @@ +/// Analog-to-Digial converter +use core::marker::PhantomData; + /// The division factor between the system clock frequency and the input clock to the AD converter. /// -/// To get 10bit precision, clock from 50kHz to 200kHz must be supplied. If you need less precision, you can supply higher clock. +/// To get 10-bit precision, clock from 50kHz to 200kHz must be supplied. If you need less +/// precision, you can supply a higher clock. #[derive(Debug, Clone, Copy, PartialEq, Eq)] -pub enum ClockRateDivision { +#[repr(u8)] +pub enum ClockDivider { Factor2, Factor4, Factor8, Factor16, Factor32, Factor64, + /// (default) Factor128, } -impl Default for ClockRateDivision { +impl Default for ClockDivider { fn default() -> Self { Self::Factor128 } @@ -20,14 +26,16 @@ impl Default for ClockRateDivision { /// Select the voltage reference for the ADC peripheral /// -/// The internal voltage reference options may not be used if an external reference voltage is being applied to the AREF pin. +/// The internal voltage reference options may not be used if an external reference voltage is +/// being applied to the AREF pin. #[derive(Debug, Clone, Copy, PartialEq, Eq)] +#[repr(u8)] pub enum ReferenceVoltage { /// Voltage applied to AREF pin. Aref, - /// Default reference voltage. + /// Default reference voltage (default). AVcc, - /// Internal reference voltage + /// Internal reference voltage. Internal, } @@ -37,125 +45,297 @@ impl Default for ReferenceVoltage { } } +/// Configuration for the ADC peripheral. #[derive(Default, Debug, Clone, Copy, PartialEq, Eq)] pub struct AdcSettings { - pub clock_divider: ClockRateDivision, + pub clock_divider: ClockDivider, pub ref_voltage: ReferenceVoltage, } -#[macro_export] -macro_rules! impl_adc { - ( - pub struct $Adc:ident { - type ChannelID = $ID:ty; - peripheral: $ADC:ty, - set_mux: |$periph_var:ident, $id_var:ident| $set_mux:block, - pins: { - $($pxi:ident: ($PXi:ident, $ChannelID:expr, $didr:ident::$didr_method:ident),)+ - } - } - ) => { +/// Internal trait for the low-level ADC peripheral. +/// +/// **Prefer using the [`Adc`] API instead of this trait.** +pub trait AdcOps { + /// Channel ID type for this ADC. + type Channel: PartialEq + Copy; + + /// Initialize the ADC peripheral with the specified settings. + /// + /// **Warning**: This is a low-level method and should not be called directly from user code. + fn raw_init(&mut self, settings: AdcSettings); - use $crate::void::Void; - use $crate::hal::adc::{Channel, OneShot}; - use $crate::nb; - use $crate::port::mode::Analog; - pub use $crate::adc::*; + /// Read out the ADC data register. + /// + /// This method must only be called after a conversion completed. + /// + /// **Warning**: This is a low-level method and should not be called directly from user code. + fn raw_read_adc(&self) -> u16; - pub struct $Adc { - peripheral: $ADC, - reading_channel: Option<$ID>, + /// Check whether the ADC is currently converting a signal. + /// + /// **Warning**: This is a low-level method and should not be called directly from user code. + fn raw_is_converting(&self) -> bool; + + /// Start a conversion on the currently selected channel. + /// + /// **Warning**: This is a low-level method and should not be called directly from user code. + fn raw_start_conversion(&mut self); + + /// Set the multiplexer to a certain channel. + /// + /// **Warning**: This is a low-level method and should not be called directly from user code. + fn raw_set_channel(&mut self, channel: Self::Channel); + + /// Set the DIDR (Digital Input Disable) for a certain channel. + /// + /// This disabled digital logic on the corresponding pin and allows measuring analog signals. + /// + /// **Warning**: This is a low-level method and should not be called directly from user code. + fn raw_enable_channel(&mut self, channel: Self::Channel); +} + +/// Trait marking a type as an ADC channel for a certain ADC. +pub trait AdcChannel> { + fn channel(&self) -> ADC::Channel; +} + +/// Representation of any ADC Channel. +/// +/// Typically, distinct types are used per channel, like for example `Pin`. In +/// some situations, however, a type is needed which can represent _any_ channel. This is required +/// to, for example, store multiple channels in an array. +/// +/// `Channel` is such a type. It can be created by calling the [`into_channel()`][into-channel] +/// method of a distinct type: +/// +/// ``` +/// let a0 = pins.a0.into_analog_input(&mut adc); +/// let a1 = pins.a1.into_analog_input(&mut adc); +/// +/// let channels: [atmega_hal::adc::Channel; 2] = [ +/// a0.into_channel(), +/// a1.into_channel(), +/// ]; +/// +/// for ch in channels.iter() { +/// adc.read_blocking(ch); +/// } +/// ``` +/// +/// [into-channel]: crate::port::Pin::into_channel +pub struct Channel> { + ch: ADC::Channel, + _h: PhantomData, +} + +impl> Channel { + pub fn new>(ch: CH) -> Self { + Self { + ch: ch.channel(), + _h: PhantomData, } + } +} - impl $Adc { - pub fn new(peripheral: $ADC, settings: AdcSettings) -> $Adc { - let s = Self { peripheral, reading_channel: None } ; - s.enable(settings); - s +impl> AdcChannel for Channel { + #[inline] + fn channel(&self) -> ADC::Channel { + self.ch + } +} + +/// Analog-to-Digital Converter +/// ``` +/// let dp = atmega_hal::Peripherals::take().unwrap(); +/// let pins = atmega_hal::pins!(dp); +/// let mut adc = atmega_hal::Adc::new(dp.ADC, Default::default()); +/// +/// let a0 = dp.pc0.into_analog_input(&mut adc); +/// +/// // the following two calls are equivalent +/// let voltage = a0.analog_read(&mut adc); +/// let voltage = adc.read_blocking(&a0); +/// +/// // alternatively, a non-blocking interface exists +/// let voltage = nb::block!(adc.read_nonblocking(&a0)).void_unwrap(); +/// ``` +pub struct Adc, CLOCK> { + p: ADC, + reading_channel: Option, + _clock: PhantomData, + _h: PhantomData, +} + +impl Adc +where + ADC: AdcOps, + CLOCK: crate::clock::Clock, +{ + pub fn new(p: ADC, settings: AdcSettings) -> Self { + let mut adc = Self { + p, + reading_channel: None, + _clock: PhantomData, + _h: PhantomData, + }; + adc.initialize(settings); + adc + } + + pub fn initialize(&mut self, settings: AdcSettings) { + self.p.raw_init(settings); + } + + #[inline] + pub(crate) fn enable_pin>(&mut self, pin: &PIN) { + self.p.raw_enable_channel(pin.channel()); + } + + pub fn read_blocking>(&mut self, pin: &PIN) -> u16 { + // assert!(self.reading_channel.is_none()); + self.p.raw_set_channel(pin.channel()); + self.p.raw_start_conversion(); + while self.p.raw_is_converting() {} + self.p.raw_read_adc() + } + + pub fn read_nonblocking>( + &mut self, + pin: &PIN, + ) -> nb::Result { + match (&self.reading_channel, self.p.raw_is_converting()) { + // Measurement on current pin is ongoing + (Some(channel), true) if *channel == pin.channel() => Err(nb::Error::WouldBlock), + // Measurement on current pin completed + (Some(channel), false) if *channel == pin.channel() => { + self.reading_channel = None; + Ok(self.p.raw_read_adc().into()) + } + // Measurement on other pin is ongoing + (Some(_), _) => { + self.reading_channel = None; + Err(nb::Error::WouldBlock) + } + // Start measurement + (None, _) => { + self.reading_channel = Some(pin.channel()); + self.p.raw_set_channel(pin.channel()); + self.p.raw_start_conversion(); + Err(nb::Error::WouldBlock) } + } + } +} + +#[macro_export] +macro_rules! impl_adc { + ( + hal: $HAL:ty, + peripheral: $ADC:ty, + channel_id: $Channel:ty, + set_channel: |$periph_var:ident, $chan_var:ident| $set_channel:block, + pins: { + $( + $(#[$pin_attr:meta])* + $pin:ty: ($pin_channel:expr, $didr:ident::$didr_method:ident), + )+ + }, + $(channels: { + $( + $(#[$channel_attr:meta])* + $channel_ty:ty: $channel:expr, + )* + },)? + ) => { + impl $crate::adc::AdcOps<$HAL> for $ADC { + type Channel = $Channel; - fn enable(&self, settings: AdcSettings) { - self.peripheral.adcsra.write(|w| { + #[inline] + fn raw_init(&mut self, settings: $crate::adc::AdcSettings) { + self.adcsra.write(|w| { w.aden().set_bit(); match settings.clock_divider { - ClockRateDivision::Factor2 => w.adps().prescaler_2(), - ClockRateDivision::Factor4 => w.adps().prescaler_4(), - ClockRateDivision::Factor8 => w.adps().prescaler_8(), - ClockRateDivision::Factor16 => w.adps().prescaler_16(), - ClockRateDivision::Factor32 => w.adps().prescaler_32(), - ClockRateDivision::Factor64 => w.adps().prescaler_64(), - ClockRateDivision::Factor128 => w.adps().prescaler_128(), - }}); - self.peripheral.admux.write(|w| match settings.ref_voltage { + ClockDivider::Factor2 => w.adps().prescaler_2(), + ClockDivider::Factor4 => w.adps().prescaler_4(), + ClockDivider::Factor8 => w.adps().prescaler_8(), + ClockDivider::Factor16 => w.adps().prescaler_16(), + ClockDivider::Factor32 => w.adps().prescaler_32(), + ClockDivider::Factor64 => w.adps().prescaler_64(), + ClockDivider::Factor128 => w.adps().prescaler_128(), + } + }); + self.admux.write(|w| match settings.ref_voltage { ReferenceVoltage::Aref => w.refs().aref(), ReferenceVoltage::AVcc => w.refs().avcc(), ReferenceVoltage::Internal => w.refs().internal(), }); + } + #[inline] + fn raw_read_adc(&self) -> u16 { + self.adc.read().bits() } - fn disable(&self) { - self.peripheral.adcsra.reset(); + #[inline] + fn raw_is_converting(&self) -> bool { + self.adcsra.read().adsc().bit_is_set() } - pub fn release(self) -> $ADC { - self.disable(); - self.peripheral + #[inline] + fn raw_start_conversion(&mut self) { + self.adcsra.modify(|_, w| w.adsc().set_bit()); } - } - impl OneShot<$Adc, WORD, PIN> for $Adc - where - WORD: From, - PIN: Channel<$Adc, ID=$ID>, - { - type Error = Void; - - fn read(&mut self, _pin: &mut PIN) -> nb::Result { - match (self.reading_channel, self.peripheral.adcsra.read().adsc().bit_is_set()) { - // Measurement on current pin is ongoing - (Some(channel), true) if channel == PIN::channel() => Err(nb::Error::WouldBlock), - // Measurement on current pin completed - (Some(channel), false) if channel == PIN::channel() => { - self.reading_channel = None; - Ok(self.peripheral.adc.read().bits().into()) - }, - // Measurement on other pin is ongoing - (Some(_), _) => { - self.reading_channel = None; - Err(nb::Error::WouldBlock) - }, - // Start measurement - (None, _) => { - self.reading_channel = Some(PIN::channel()); - { - let $periph_var = &mut self.peripheral; - let $id_var = PIN::channel(); - - $set_mux - } - self.peripheral.adcsra.modify(|_, w| w.adsc().set_bit()); - Err(nb::Error::WouldBlock) - }, + #[inline] + fn raw_set_channel(&mut self, channel: Self::Channel) { + let $periph_var = self; + let $chan_var = channel; + + $set_channel + } + + #[inline] + fn raw_enable_channel(&mut self, channel: Self::Channel) { + match channel { + $( + $(#[$pin_attr])* + x if x == $pin_channel => self.$didr.modify(|_, w| w.$didr_method().set_bit()), + )+ + _ => unreachable!(), } } } $( - impl Channel<$Adc> for $PXi { - type ID = $ID; - fn channel() -> Self::ID { - $ChannelID - } + $(#[$pin_attr])* + impl $crate::adc::AdcChannel<$HAL, $ADC> for $crate::port::Pin<$crate::port::mode::Analog, $pin> { + #[inline] + fn channel(&self) -> $Channel { + $pin_channel } + } + )+ - impl $PXi { - /// Make this pin a analog input and set the didr register - pub fn into_analog_input(self, adc: &mut $Adc) -> $PXi { - adc.peripheral.$didr.modify(|_, w| w.$didr_method().set_bit()); - $PXi { _mode: core::marker::PhantomData } - } + $($( + $(#[$channel_attr])* + impl $crate::adc::AdcChannel<$HAL, $ADC> for $channel_ty { + #[inline] + fn channel(&self) -> $Channel { + $channel } - )+ - } + } + + /// Convert this channel into a generic "[`Channel`][adc-channel]" type. + /// + /// The generic channel type can be used to store multiple channels in an array. + /// + /// [adc-channel]: crate::adc::Channel + $(#[$channel_attr])* + impl $channel_ty { + pub fn into_channel(self) -> $crate::adc::Channel<$HAL, $ADC> { + crate::adc::Channel::new(self) + } + } + )*)? + }; } diff --git a/avr-hal-generic/src/i2c.rs b/avr-hal-generic/src/i2c.rs index 928ad190bc..a5a016b070 100644 --- a/avr-hal-generic/src/i2c.rs +++ b/avr-hal-generic/src/i2c.rs @@ -1,4 +1,9 @@ //! I2C Implementations +//! +//! Check the documentation of [`I2c`] for details. + +use crate::port; +use core::marker::PhantomData; /// TWI Status Codes pub mod twi_status { @@ -99,6 +104,7 @@ pub mod twi_status { /// I2C Error #[derive(ufmt::derive::uDebug, Debug, Clone, Copy, Eq, PartialEq)] +#[repr(u8)] pub enum Error { /// Lost arbitration while trying to acquire bus ArbitrationLost, @@ -114,6 +120,7 @@ pub enum Error { /// I2C Transfer Direction #[derive(ufmt::derive::uDebug, Debug, Clone, Copy, Eq, PartialEq)] +#[repr(u8)] pub enum Direction { /// Write to a slave (LSB is 0) Write, @@ -121,370 +128,419 @@ pub enum Direction { Read, } -#[doc(hidden)] -pub fn i2cdetect(s: &mut W, mut f: F) -> Result<(), W::Error> +/// Internal trait for low-level I2C peripherals. +/// +/// This trait defines the common interface for all I2C peripheral variants. It is used as an +/// intermediate abstraction ontop of which the [`I2c`] API is built. **Prefer using the +/// [`I2c`] API instead of this trait.** +pub trait I2cOps { + /// Setup the bus for operation at a certain speed. + /// + /// **Warning**: This is a low-level method and should not be called directly from user code. + fn raw_setup(&mut self, speed: u32); + + /// Start a bus transaction to a certain `address` in either read or write mode. + /// + /// If a previous transaction was not stopped via `raw_stop()`, this should generate a repeated + /// start condition. + /// + /// **Warning**: This is a low-level method and should not be called directly from user code. + fn raw_start(&mut self, address: u8, direction: Direction) -> Result<(), Error>; + + /// Write some bytes to the bus. + /// + /// This method must only be called after a transaction in write mode was successfully started. + /// + /// **Warning**: This is a low-level method and should not be called directly from user code. + fn raw_write(&mut self, bytes: &[u8]) -> Result<(), Error>; + + /// Read some bytes from the bus. + /// + /// This method must only be called after a transaction in read mode was successfully started. + /// + /// **Warning**: This is a low-level method and should not be called directly from user code. + fn raw_read(&mut self, buffer: &mut [u8]) -> Result<(), Error>; + + /// Send a stop-condition and release the bus. + /// + /// This method must only be called after successfully starting a bus transaction. This method + /// does not need to block until the stop condition has actually occured. + /// + /// **Warning**: This is a low-level method and should not be called directly from user code. + fn raw_stop(&mut self) -> Result<(), Error>; +} + +/// I2C driver +/// +/// # Example +/// (for Arduino Uno) +/// ``` +/// let dp = arduino_hal::Peripherals::take().unwrap(); +/// let pins = arduino_hal::pins!(dp); +/// +/// let mut i2c = arduino_hal::I2c::new( +/// dp.TWI, +/// pins.a4.into_pull_up_input(), +/// pins.a5.into_pull_up_input(), +/// 50000, +/// ); +/// +/// // i2c implements the embedded-hal traits so it can be used with generic drivers. +/// ``` +pub struct I2c, SDA, SCL, CLOCK> { + p: I2C, + #[allow(dead_code)] + sda: SDA, + #[allow(dead_code)] + scl: SCL, + _clock: PhantomData, + _h: PhantomData, +} + +impl + I2c, port::Pin, CLOCK> where - // Detection function - F: FnMut(u8) -> Result, + I2C: I2cOps, port::Pin>, + SDAPIN: port::PinOps, + SCLPIN: port::PinOps, + CLOCK: crate::clock::Clock, { - s.write_str("\ -- 0 1 2 3 4 5 6 7 8 9 a b c d e f\r\n\ -00: ")?; - - fn u4_to_hex(b: u8) -> char { - match b { - x if x < 0xa => (0x30 + x).into(), - x if x < 0x10 => (0x57 + x).into(), - _ => '?', - } + /// Initialize an I2C peripheral on the given pins. + /// + /// Note that the SDA and SCL pins are hardwired for each I2C peripheral and you *must* pass + /// the correct ones. This is enforced at compile time. + /// + /// This method expects the internal pull-ups to be configured for both pins to comply with the + /// I2C specification. If you have external pull-ups connected, use + /// [`I2c::with_external_pullup`] instead. + pub fn new( + p: I2C, + sda: port::Pin, SDAPIN>, + scl: port::Pin, SCLPIN>, + speed: u32, + ) -> Self { + let mut i2c = Self { + p, + sda: sda.forget_imode(), + scl: scl.forget_imode(), + _clock: PhantomData, + _h: PhantomData, + }; + i2c.p.raw_setup::(speed); + i2c } - for addr in 0x02..=0x77 { - let (ah, al) = (u4_to_hex(addr >> 4), u4_to_hex(addr & 0xf)); + /// Initialize an I2C peripheral on the given pins. + /// + /// Note that the SDA and SCL pins are hardwired for each I2C peripheral and you *must* pass + /// the correct ones. This is enforced at compile time. + /// + /// This method expects that external resistors pull up SDA and SCL. + pub fn with_external_pullup( + p: I2C, + sda: port::Pin, SDAPIN>, + scl: port::Pin, SCLPIN>, + speed: u32, + ) -> Self { + let mut i2c = Self { + p, + sda: sda.forget_imode(), + scl: scl.forget_imode(), + _clock: PhantomData, + _h: PhantomData, + }; + i2c.p.raw_setup::(speed); + i2c + } +} - if addr % 0x10 == 0 { - s.write_str("\r\n")?; - s.write_char(ah)?; - s.write_str("0:")?; +impl, SDA, SCL, CLOCK> I2c +where + CLOCK: crate::clock::Clock, + crate::delay::Delay: hal::blocking::delay::DelayMs, +{ + /// Test whether a device answers on a certain address. + pub fn ping_device(&mut self, address: u8, direction: Direction) -> Result { + match self.p.raw_start(address, direction) { + Ok(_) => { + self.p.raw_stop()?; + Ok(true) + } + Err(Error::AddressNack) => Ok(false), + Err(e) => Err(e), } + } - match f(addr) { - Ok(true) => { - s.write_char(' ')?; - s.write_char(ah)?; - s.write_char(al)?; - }, - Ok(false) => { - s.write_str(" --")?; - }, - Err(e) => { - s.write_str(" E")?; - s.write_char(u4_to_hex(e as u8))?; - }, + /// Scan the bus for connected devices. This method will output an summary in the format known + /// from [`i2cdetect(8)`][i2cdetect-linux] on the selected serial connection. For example: + /// + /// ```text + /// - 0 1 2 3 4 5 6 7 8 9 a b c d e f + /// 00: -- -- -- -- -- -- -- -- -- -- -- -- -- -- + /// 10: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- + /// 20: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- + /// 30: -- -- -- -- -- -- -- -- 38 39 -- -- -- -- -- -- + /// 40: -- -- -- -- -- -- -- -- 48 -- -- -- -- -- -- -- + /// 50: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- + /// 60: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- + /// 70: -- -- -- -- -- -- -- -- + /// ``` + /// + /// [i2cdetect-linux]: https://man.archlinux.org/man/community/i2c-tools/i2cdetect.8.en + pub fn i2cdetect( + &mut self, + w: &mut W, + direction: Direction, + ) -> Result<(), W::Error> { + use hal::blocking::delay::DelayMs; + let mut delay = crate::delay::Delay::::new(); + + w.write_str( + "\ +- 0 1 2 3 4 5 6 7 8 9 a b c d e f\r\n\ +00: ", + )?; + + fn u4_to_hex(b: u8) -> char { + match b { + x if x < 0xa => (0x30 + x).into(), + x if x < 0x10 => (0x57 + x).into(), + _ => '?', + } } - } - s.write_str("\r\n")?; + for address in 0x02..=0x77 { + let (ah, al) = (u4_to_hex(address >> 4), u4_to_hex(address & 0xf)); - Ok(()) -} + if address % 0x10 == 0 { + w.write_str("\r\n")?; + w.write_char(ah)?; + w.write_str("0:")?; + } -#[doc(hidden)] -pub type I2cFloating = crate::port::mode::Input; -#[doc(hidden)] -pub type I2cPullUp = crate::port::mode::Input; + match self.ping_device(address, direction) { + Ok(true) => { + w.write_char(' ')?; + w.write_char(ah)?; + w.write_char(al)?; + } + Ok(false) => { + w.write_str(" --")?; + } + Err(e) => { + w.write_str(" E")?; + w.write_char(u4_to_hex(e as u8))?; + } + } -/// Implement I2C traits for a TWI peripheral -#[macro_export] -macro_rules! impl_twi_i2c { - ( - $(#[$i2c_attr:meta])* - pub struct $I2c:ident { - peripheral: $I2C:ty, - pins: { - sda: $sdamod:ident::$SDA:ident, - scl: $sclmod:ident::$SCL:ident, - }, - } - ) => {$crate::paste::paste! { - $(#[$i2c_attr])* - pub struct [<$I2c Master>] { - p: $I2C, - _clock: ::core::marker::PhantomData, - sda: $sdamod::$SDA, - scl: $sclmod::$SCL, + delay.delay_ms(10u16); } - impl [<$I2c Master>] - where - CLOCK: $crate::clock::Clock, - { - /// Initialize the I2C bus - /// - /// `new()` will enable the internal pull-ups to comply with the I2C - /// specification. If you have external pull-ups connected, please - /// use `new_with_external_pullup()` instead. - pub fn new( - p: $I2C, - sda: $sdamod::$SDA<$crate::port::mode::Input<$crate::port::mode::PullUp>>, - scl: $sclmod::$SCL<$crate::port::mode::Input<$crate::port::mode::PullUp>>, - speed: u32, - ) -> [<$I2c Master>] { - let mut i2c = [<$I2c Master>] { - p, - sda, - scl, - _clock: ::core::marker::PhantomData, - }; + w.write_str("\r\n")?; - i2c.set_speed(speed); - i2c - } - } + Ok(()) + } +} - impl [<$I2c Master>] - where - CLOCK: $crate::clock::Clock, - { - /// Initialize the I2C bus, without enabling internal pull-ups - /// - /// This function should be used if your hardware design includes - /// pull-up resistors outside the MCU. If you do not have these, - /// please use `new()` instead. - pub fn new_with_external_pullup( - p: $I2C, - sda: $sdamod::$SDA<$crate::port::mode::Input<$crate::port::mode::Floating>>, - scl: $sclmod::$SCL<$crate::port::mode::Input<$crate::port::mode::Floating>>, - speed: u32, - ) -> [<$I2c Master>] { - let mut i2c = [<$I2c Master>] { - p, - sda, - scl, - _clock: ::core::marker::PhantomData, - }; +impl, SDA, SCL, CLOCK> hal::blocking::i2c::Write + for I2c +{ + type Error = Error; - i2c.set_speed(speed); - i2c - } - } + fn write(&mut self, address: u8, bytes: &[u8]) -> Result<(), Self::Error> { + self.p.raw_start(address, Direction::Write)?; + self.p.raw_write(bytes)?; + self.p.raw_stop()?; + Ok(()) + } +} + +impl, SDA, SCL, CLOCK> hal::blocking::i2c::Read + for I2c +{ + type Error = Error; + + fn read(&mut self, address: u8, buffer: &mut [u8]) -> Result<(), Self::Error> { + self.p.raw_start(address, Direction::Read)?; + self.p.raw_read(buffer)?; + self.p.raw_stop()?; + Ok(()) + } +} + +impl, SDA, SCL, CLOCK> hal::blocking::i2c::WriteRead + for I2c +{ + type Error = Error; + + fn write_read( + &mut self, + address: u8, + bytes: &[u8], + buffer: &mut [u8], + ) -> Result<(), Self::Error> { + self.p.raw_start(address, Direction::Write)?; + self.p.raw_write(bytes)?; + self.p.raw_start(address, Direction::Read)?; + self.p.raw_read(buffer)?; + self.p.raw_stop()?; + Ok(()) + } +} - impl [<$I2c Master>] - where - CLOCK: $crate::clock::Clock, +#[macro_export] +macro_rules! impl_i2c_twi { + ( + hal: $HAL:ty, + peripheral: $I2C:ty, + sda: $sdapin:ty, + scl: $sclpin:ty, + ) => { + impl + $crate::i2c::I2cOps< + $HAL, + $crate::port::Pin<$crate::port::mode::Input, $sdapin>, + $crate::port::Pin<$crate::port::mode::Input, $sclpin>, + > for $I2C { - fn set_speed(&mut self, speed: u32){ + #[inline] + fn raw_setup(&mut self, speed: u32) { // Calculate TWBR register value let twbr = ((CLOCK::FREQ / speed) - 16) / 2; - self.p.twbr.write(|w| unsafe { w.bits(twbr as u8) }); + self.twbr.write(|w| unsafe { w.bits(twbr as u8) }); // Disable prescaler - self.p.twsr.write(|w| w.twps().prescaler_1()); + self.twsr.write(|w| w.twps().prescaler_1()); } - /// Check whether a slave answers ACK for a given address - /// - /// Note that some devices might not respond to both read and write - /// operations. - pub fn ping_slave( - &mut self, - addr: u8, - dir: $crate::i2c::Direction, - ) -> Result { - match self.start(addr, dir) { - Err($crate::i2c::Error::AddressNack) => Ok(false), - Err(e) => Err(e), - Ok(()) => { - self.stop(); - Ok(true) - }, - } - } - - fn start( - &mut self, - addr: u8, - dir: $crate::i2c::Direction, - ) -> Result<(), $crate::i2c::Error> { + #[inline] + fn raw_start(&mut self, address: u8, direction: Direction) -> Result<(), Error> { // Write start condition - self.p.twcr.write(|w| w - .twen().set_bit() - .twint().set_bit() - .twsta().set_bit() - ); - self.wait(); + self.twcr + .write(|w| w.twen().set_bit().twint().set_bit().twsta().set_bit()); + // wait() + while self.twcr.read().twint().bit_is_clear() {} // Validate status - match self.p.twsr.read().tws().bits() { - $crate::i2c::twi_status::TW_START - | $crate::i2c::twi_status::TW_REP_START => (), - $crate::i2c::twi_status::TW_MT_ARB_LOST + match self.twsr.read().tws().bits() { + $crate::i2c::twi_status::TW_START | $crate::i2c::twi_status::TW_REP_START => (), + $crate::i2c::twi_status::TW_MT_ARB_LOST | $crate::i2c::twi_status::TW_MR_ARB_LOST => { return Err($crate::i2c::Error::ArbitrationLost); - }, + } $crate::i2c::twi_status::TW_BUS_ERROR => { return Err($crate::i2c::Error::BusError); - }, + } _ => { return Err($crate::i2c::Error::Unknown); - }, + } } // Send slave address - let dirbit = if dir == $crate::i2c::Direction::Read { 1 } else { 0 }; - let rawaddr = (addr << 1) | dirbit; - self.p.twdr.write(|w| unsafe { w.bits(rawaddr) }); - self.transact(); + let dirbit = if direction == $crate::i2c::Direction::Read { + 1 + } else { + 0 + }; + let rawaddr = (address << 1) | dirbit; + self.twdr.write(|w| unsafe { w.bits(rawaddr) }); + // transact() + self.twcr.write(|w| w.twen().set_bit().twint().set_bit()); + while self.twcr.read().twint().bit_is_clear() {} // Check if the slave responded - match self.p.twsr.read().tws().bits() { - $crate::i2c::twi_status::TW_MT_SLA_ACK + match self.twsr.read().tws().bits() { + $crate::i2c::twi_status::TW_MT_SLA_ACK | $crate::i2c::twi_status::TW_MR_SLA_ACK => (), - $crate::i2c::twi_status::TW_MT_SLA_NACK + $crate::i2c::twi_status::TW_MT_SLA_NACK | $crate::i2c::twi_status::TW_MR_SLA_NACK => { // Stop the transaction if it did not respond - self.stop(); + self.raw_stop()?; return Err($crate::i2c::Error::AddressNack); - }, - $crate::i2c::twi_status::TW_MT_ARB_LOST + } + $crate::i2c::twi_status::TW_MT_ARB_LOST | $crate::i2c::twi_status::TW_MR_ARB_LOST => { return Err($crate::i2c::Error::ArbitrationLost); - }, + } $crate::i2c::twi_status::TW_BUS_ERROR => { return Err($crate::i2c::Error::BusError); - }, + } _ => { return Err($crate::i2c::Error::Unknown); - }, + } } Ok(()) } - fn wait(&mut self) { - while self.p.twcr.read().twint().bit_is_clear() { } - } - - fn transact(&mut self) { - self.p.twcr.write(|w| w.twen().set_bit().twint().set_bit()); - while self.p.twcr.read().twint().bit_is_clear() { } - } - - fn write_data(&mut self, bytes: &[u8]) -> Result<(), $crate::i2c::Error> { + #[inline] + fn raw_write(&mut self, bytes: &[u8]) -> Result<(), Error> { for byte in bytes { - self.p.twdr.write(|w| unsafe { w.bits(*byte) }); - self.transact(); + self.twdr.write(|w| unsafe { w.bits(*byte) }); + // transact() + self.twcr.write(|w| w.twen().set_bit().twint().set_bit()); + while self.twcr.read().twint().bit_is_clear() {} - match self.p.twsr.read().tws().bits() { + match self.twsr.read().tws().bits() { $crate::i2c::twi_status::TW_MT_DATA_ACK => (), $crate::i2c::twi_status::TW_MT_DATA_NACK => { - self.stop(); + self.raw_stop()?; return Err($crate::i2c::Error::DataNack); - }, + } $crate::i2c::twi_status::TW_MT_ARB_LOST => { return Err($crate::i2c::Error::ArbitrationLost); - }, + } $crate::i2c::twi_status::TW_BUS_ERROR => { return Err($crate::i2c::Error::BusError); - }, + } _ => { return Err($crate::i2c::Error::Unknown); - }, + } } } Ok(()) } - fn read_data(&mut self, buffer: &mut [u8]) -> Result<(), $crate::i2c::Error> { + #[inline] + fn raw_read(&mut self, buffer: &mut [u8]) -> Result<(), Error> { let last = buffer.len() - 1; for (i, byte) in buffer.iter_mut().enumerate() { if i != last { - self.p.twcr.write(|w| w.twint().set_bit().twen().set_bit().twea().set_bit()); - self.wait(); + self.twcr + .write(|w| w.twint().set_bit().twen().set_bit().twea().set_bit()); + // wait() + while self.twcr.read().twint().bit_is_clear() {} } else { - self.p.twcr.write(|w| w.twint().set_bit().twen().set_bit()); - self.wait(); + self.twcr.write(|w| w.twint().set_bit().twen().set_bit()); + // wait() + while self.twcr.read().twint().bit_is_clear() {} } - match self.p.twsr.read().tws().bits() { - $crate::i2c::twi_status::TW_MR_DATA_ACK + match self.twsr.read().tws().bits() { + $crate::i2c::twi_status::TW_MR_DATA_ACK | $crate::i2c::twi_status::TW_MR_DATA_NACK => (), $crate::i2c::twi_status::TW_MR_ARB_LOST => { return Err($crate::i2c::Error::ArbitrationLost); - }, + } $crate::i2c::twi_status::TW_BUS_ERROR => { return Err($crate::i2c::Error::BusError); - }, + } _ => { return Err($crate::i2c::Error::Unknown); - }, + } } - *byte = self.p.twdr.read().bits(); + *byte = self.twdr.read().bits(); } Ok(()) } - fn stop(&mut self) { - self.p.twcr.write(|w| w - .twen().set_bit() - .twint().set_bit() - .twsto().set_bit() - ); - } - } - - impl [<$I2c Master>] - where - CLOCK: $crate::clock::Clock, - $crate::delay::Delay: $crate::hal::blocking::delay::DelayMs, - { - /// Output an `i2cdetect`-like summary of connected slaves to a serial device - /// - /// Note that output for `Read` and `Write` might differ. - pub fn i2cdetect( - &mut self, - w: &mut W, - dir: $crate::i2c::Direction, - ) -> Result<(), W::Error> { - let mut delay = $crate::delay::Delay::::new(); - $crate::i2c::i2cdetect(w, |a| { - use $crate::prelude::*; - - delay.delay_ms(10u16); - self.ping_slave(a, dir) - }) - } - } - - - impl $crate::hal::blocking::i2c::Write for [<$I2c Master>] - where - CLOCK: $crate::clock::Clock, - { - type Error = $crate::i2c::Error; - - fn write(&mut self, address: u8, bytes: &[u8]) -> Result<(), Self::Error> { - self.start(address, $crate::i2c::Direction::Write)?; - self.write_data(bytes)?; - self.stop(); - Ok(()) - } - } - - impl $crate::hal::blocking::i2c::Read for [<$I2c Master>] - where - CLOCK: $crate::clock::Clock, - { - type Error = $crate::i2c::Error; - - fn read(&mut self, address: u8, buffer: &mut [u8]) -> Result<(), Self::Error> { - self.start(address, $crate::i2c::Direction::Read)?; - self.read_data(buffer)?; - self.stop(); - Ok(()) - } - } - - impl $crate::hal::blocking::i2c::WriteRead for [<$I2c Master>] - where - CLOCK: $crate::clock::Clock, - { - type Error = $crate::i2c::Error; - - fn write_read( - &mut self, - address: u8, - bytes: &[u8], - buffer: &mut [u8], - ) -> Result<(), Self::Error> { - self.start(address, $crate::i2c::Direction::Write)?; - self.write_data(bytes)?; - self.start(address, $crate::i2c::Direction::Read)?; - self.read_data(buffer)?; - self.stop(); + #[inline] + fn raw_stop(&mut self) -> Result<(), Error> { + self.twcr + .write(|w| w.twen().set_bit().twint().set_bit().twsto().set_bit()); Ok(()) } } - }}; + }; } diff --git a/avr-hal-generic/src/lib.rs b/avr-hal-generic/src/lib.rs index c803b973bf..590ef7d1a9 100644 --- a/avr-hal-generic/src/lib.rs +++ b/avr-hal-generic/src/lib.rs @@ -35,3 +35,9 @@ pub mod prelude { pub use void::ResultVoidErrExt as _; pub use ufmt::uWrite as _; } + +// For making certain traits unimplementable from outside this crate. +mod sealed { + pub trait Sealed {} +} +pub(crate) use sealed::Sealed; diff --git a/avr-hal-generic/src/port.rs b/avr-hal-generic/src/port.rs index 81003aa22a..5b05bf1bde 100644 --- a/avr-hal-generic/src/port.rs +++ b/avr-hal-generic/src/port.rs @@ -1,733 +1,574 @@ -//! PORTx digital IO Implementations +//! Digital IO implementations for the `PORT#` peripherals //! -//! # Design Rationale -//! Each pin has a distinct type which allows pin-dependent HAL functionality to ensure at -//! compile-time that the correct pins are used. For example, certain peripherals have the IO -//! hardwired to some specific pins which can't be changed. For purposes where the exact pin does -//! not matter, the distinct types can be 'downgraded' into a generic `Pin` type. See the -//! section about [downgrading](#downgrading) further down. -//! -//! To instanciate the pin types, a port is `.split()` into its pins: -//! -//! ```ignore -//! let dp = atmega32u4::Peripherals::take().unwrap(); -//! -//! let mut portd = dp.PORTD.split(); -//! -//! let pd2 = portd.pd2.into_output(&mut portd.ddr); -//! ``` -//! -//! Board crates usually provide a wrapper around that which makes access more convenient: -//! -//! ```ignore -//! let dp = arduino_leonardo::Peripherals::take().unwrap(); -//! -//! let mut pins = arduino_leonardo::Pins::new( -//! dp.PORTB, -//! dp.PORTC, -//! dp.PORTD, -//! dp.PORTE, -//! ); -//! -//! let mut led0 = pins.led_rx.into_output(&mut pins.ddr); -//! let mut led1 = pins.led_tx.into_output(&mut pins.ddr); -//! let mut led2 = pins.d13.into_output(&mut pins.ddr); -//! ``` -//! -//! # Modes -//! A pin's mode is modelled via the `` generic parameter. Only when the pin is in the -//! correct mode, relevant methods (e.g. `set_high()`) are available. Changing the mode is done -//! via conversion methods that consume the pin: -//! -//! ```ignore -//! // By default, pins are floating inputs -//! let pd2: PD2> = portd.pd2; -//! -//! // Convert into pull-up input -//! let pd2: PD2> = pd2.into_pull_up_input(&mut portd.ddr); -//! -//! // Convert into output -//! let pd2: PD2 = pd2.into_output(&mut portd.ddr); -//! -//! // Convert into tri-state input and output. -//! let pd2: PD2 = pd2.into_tri_state(&mut portd.ddr); -//! ``` -//! -//! ### Digital Input -//! Digital Input pins (i.e. where `MODE` = `mode::Input<_>`) have the following methods available: -//! -//! ```ignore -//! // `true` if the pin is high, `false` if it is low -//! pd2.is_high().void_unwrap(); -//! -//! // `true if the pin is low, `false` if it is high -//! pd2.is_low().void_unwrap(); -//! ``` -//! -//! ### Digital Output -//! Digital Output pins (i.e. where `MODE` = `mode::Output`) can be used like this: -//! -//! ```ignore -//! // Set high or low -//! pd2.set_high().void_unwrap(); -//! pd2.set_low().void_unwrap(); -//! -//! // Check what the pin was last set to -//! pd2.is_set_high().void_unwrap(); -//! pd2.is_set_low().void_unwrap(); -//! ``` -//! -//! ### Digital Tri-State Output and Input -//! Digital I/O pins in tri-state mode (i.e. where `MODE` = `mode::TriState`), -//! usually with an external pull-up, are useful for a one wire bus. -//! They can be used as both output and input pins, like this: -//! -//! ```ignore -//! // Actively drive the pin low. -//! pd2.set_low().void_unwrap(); -//! // Release the pin, allowing the external pull-up to pull the pin -//! // in the absence of another driver -//! pd2.set_high().void_unwrap(); -//! -//! // `true` if the pin is electrically high, `false` if it is low -//! pd2.is_high().void_unwrap(); -//! // `true` if the pin is electrically low, driven by either the -//! // microcontroller or externally -//! pd2.is_low().void_unwrap(); -//! ``` -//! -//! ### Other Modes -//! Apart from input and output, certain pins can have other functionality associated with them. -//! E.g. some pins can be used for PWM output, others as ADC inputs. For those pins, specific -//! conversion methods exist: -//! -//! ```ignore -//! // Digital IO by default -//! let pd2 = portd.pd2; -//! -//! // Make a pin an ADC channel -//! let pd2_analog = pd2.into_analog_input(&mut adc); -//! -//! // Make a pin a PWM output -//! let pd2_pwm = pd2.into_output().into_pwm(&mut timer0); -//! ``` -//! -//! ## Downgrading -//! As described above, usually each pin has its own distinct type. This is useful in a lot of -//! cases but can be difficult to deal with when code does not care about the exact pin(s) it is -//! working with. An easy example is trying to store a number of pins in an array; this is not -//! possible when each pin has its own type. -//! -//! For those usecases, a generic `Pin` type exists which can represent any pin. Specific pins are -//! converted using the `.downgrade()` method: -//! -//! ```ignore -//! let pd2 = portd.pd2.into_output(&mut portd.ddr); -//! let pd3 = portd.pd3.into_output(&mut portd.ddr); -//! -//! let pins: [Pin; 2] = [pd2.downgrade(), pd3.downgrade()]; -//! ``` +//! Please take a look at the documentation for [`Pin`] for a detailed explanation. + +use core::marker::PhantomData; -/// IO Modes +pub trait PinMode: crate::Sealed {} +/// GPIO pin modes pub mod mode { - /// Any digital IO mode - pub trait DigitalIO: private::Unimplementable {} - /// Any input mode - pub trait InputMode: private::Unimplementable {} - - /// Pin configured as a digital input - pub struct Input { - _m: core::marker::PhantomData, - } - /// Pin configured as a digital output + use core::marker::PhantomData; + + pub trait Io: crate::Sealed + super::PinMode {} + + /// Pin is configured as a digital output. pub struct Output; - /// Pin configured as an ADC channel - pub struct Analog; - /// Pin configured as PWM output - pub struct Pwm { - _m: core::marker::PhantomData, - } - /// Pin configured in open drain mode. - pub struct TriState; + impl super::PinMode for Output {} + impl Io for Output {} + impl crate::Sealed for Output {} - impl private::Unimplementable for Output {} - impl private::Unimplementable for Input {} - impl private::Unimplementable for TriState {} - impl DigitalIO for Output {} - impl DigitalIO for Input {} - impl DigitalIO for TriState {} + pub trait InputMode: crate::Sealed {} - /// Pin input configured **without** internal pull-up - pub struct Floating; - /// Pin input configured with internal pull-up - pub struct PullUp; + /// Pin is configured as digital input (floating or pulled-up). + pub struct Input { + pub(crate) _imode: PhantomData, + } + impl super::PinMode for Input {} + impl Io for Input {} + impl crate::Sealed for Input {} - impl private::Unimplementable for Floating {} - impl private::Unimplementable for PullUp {} + /// Floating input, used like `Input`. + pub struct Floating; impl InputMode for Floating {} + impl crate::Sealed for Floating {} + + /// Pulled-up input, used like `Input`. + pub struct PullUp; impl InputMode for PullUp {} + impl crate::Sealed for PullUp {} + + /// Any input (floating or pulled-up), used like `Input`. + pub struct AnyInput; + impl InputMode for AnyInput {} + impl crate::Sealed for AnyInput {} + + /// Pin is configured as an analog input (for the ADC). + pub struct Analog; +} + +pub trait PinOps { + type Dynamic; + + fn into_dynamic(self) -> Self::Dynamic; + + unsafe fn out_set(&mut self); + unsafe fn out_clear(&mut self); + unsafe fn out_toggle(&mut self); + unsafe fn out_get(&self) -> bool; - mod private { - pub trait Unimplementable {} + unsafe fn in_get(&self) -> bool; + + unsafe fn make_output(&mut self); + unsafe fn make_input(&mut self, pull_up: bool); +} + +/// Representation of an MCU pin. +/// +/// # Design Rationale +/// We want individual types per pin to model constraints which depend on a specific pin. For +/// example, some peripherals are internally hard-wired to certain pins of the MCU. +/// +/// Additionally, the mode of a pin should also be a part of the type to model enforcement of pins +/// being in a certain mode and preventing misuse like for example calling `set_high()` on a pin +/// configured as input. +/// +/// To do this, the [`Pin`] type is generic over the `MODE` (input, output, ...) and the `PIN` +/// (pd0, pb5, pc6, ...). +/// +/// Of course, in some applications one does not care about the specific pin used. For these +/// situations, the specific pin types can be "downgraded" into a dynamic type that can represent +/// any pin. See [Downgrading](#downgrading) for more details. +/// +/// # Instantiation +/// The `Peripherals` struct in HAL and board-support crates usually contains a `.pins` field which +/// is of type `Pins`. This `Pins` struct in turn has fields for each individual pin, in its +/// default mode. You can then move the pin out of this struct to reconfigure it (examples in this +/// documentation are for `atmega-hal`): +/// +/// ```ignore +/// use atmega_hal::port::{Pin, mode, self}; +/// +/// let dp = atmega_hal::Peripherals::take().unwrap(); +/// let pins = atmega_hal::pins!(dp); +/// +/// let output: Pin = pins.pd3.into_output(); +/// ``` +pub struct Pin { + pub(crate) pin: PIN, + pub(crate) _mode: PhantomData, +} + +impl Pin, PIN> { + #[doc(hidden)] + pub fn new(pin: PIN) -> Self { + Pin { + pin, + _mode: PhantomData, + } } } -/// Create a generic pin to be used for downgrading -#[macro_export] -macro_rules! impl_generic_pin { - ( - pub enum $GenericPin:ident { - $($PortEnum:ident($PORTX:ty, $reg_port:ident, $reg_pin:ident, $reg_ddr:ident),)+ +/// # Configuration +/// To change the mode of a pin, use one of the following conversion functions. They consume the +/// original [`Pin`] and return one with the desired mode. Only when a pin is in the correct mode, +/// does it have the mode-relevant methods availailable (e.g. `set_high()` is only available for +/// `Output` pins). +impl Pin { + /// Convert this pin into an output pin, setting the state to low. + /// See [Digital Output](#digital-output). + pub fn into_output(mut self) -> Pin { + unsafe { self.pin.out_clear() }; + unsafe { self.pin.make_output() }; + Pin { + pin: self.pin, + _mode: PhantomData, } - ) => { - mod generic_pin { - use $crate::hal::digital::v2 as digital; - use $crate::port::mode; - use $crate::void::Void; - use core::marker; - - /// Generic pin type. - /// - /// As described in the [general Digital IO documentation][1], this type can represent - /// any pin for use-cases where the exact pin is not relevant. This is especially - /// useful when, e.g. wanting to store a number of pins in an array. - /// - /// The generic pin implements all the same digital IO methods (`set_high()`, - /// `set_low()`, `is_high()`, `is_low()`, etc.) as specific pin types, except that it - /// cannot be used for pin-specific functions (e.g. PWM, ADC Channel). - /// - /// [1]: ../../avr_hal_generic/port/index.html - pub enum $GenericPin { - $($PortEnum(u8, marker::PhantomData),)+ - } + } - // Input & Output implementations ------------------------- {{{ - // - Unsafe: The unsafe blocks in here are ok, because these - // operations will compile down to single, atomic - // `sbi`, `cbi`, `sbic`, `sbis` instructions. - impl digital::OutputPin for $GenericPin { - type Error = Void; - - fn set_high(&mut self) -> Result<(), Self::Error> { - match self { - $( - $GenericPin::$PortEnum(i, _) => unsafe { - (*<$PORTX>::ptr()) - .$reg_port - .modify(|r, w| { - w.bits(r.bits() | (1 << *i)) - }) - }, - )+ - } - Ok(()) - } + /// Convert this pin into an output pin, setting the state to high. + /// See [Digital Output](#digital-output). + pub fn into_output_high(mut self) -> Pin { + unsafe { self.pin.out_set() }; + unsafe { self.pin.make_output() }; + Pin { + pin: self.pin, + _mode: PhantomData, + } + } - fn set_low(&mut self) -> Result<(), Self::Error> { - match self { - $( - $GenericPin::$PortEnum(i, _) => unsafe { - (*<$PORTX>::ptr()) - .$reg_port - .modify(|r, w| { - w.bits(r.bits() & !(1 << *i)) - }) - }, - )+ - } - Ok(()) - } - } + /// Convert this pin into a floating input pin. See [Digital Input](#digital-input). + /// + /// *Note*: To read deterministic values from the pin, it must be externally pulled to a + /// defined level (either VCC or GND). + pub fn into_floating_input(mut self) -> Pin, PIN> { + unsafe { self.pin.make_input(false) }; + Pin { + pin: self.pin, + _mode: PhantomData, + } + } - impl digital::StatefulOutputPin for $GenericPin { - fn is_set_high(&self) -> Result { - Ok(match self { - $( - $GenericPin::$PortEnum(i, _) => unsafe { - (*<$PORTX>::ptr()) - .$reg_port.read().bits() & (1 << *i) != 0 - }, - )+ - }) - } + /// Convert this pin into a pulled-up input pin. See [Digital Input](#digital-input). + /// + /// With no external circuit pulling the pin low, it will be read high. + pub fn into_pull_up_input(mut self) -> Pin, PIN> { + unsafe { self.pin.make_input(true) }; + Pin { + pin: self.pin, + _mode: PhantomData, + } + } - fn is_set_low(&self) -> Result { - self.is_set_high().map(|b| !b) - } - } + /// Convert this pin into an analog input (ADC channel). See [Analog Input](#analog-input). + /// + /// Some pins can be repurposed as ADC channels. For those pins, the `into_analog_input()` + /// method is available. + pub fn into_analog_input( + self, + adc: &mut crate::adc::Adc, + ) -> Pin + where + Pin: crate::adc::AdcChannel, + ADC: crate::adc::AdcOps, + CLOCK: crate::clock::Clock, + { + let new = Pin { + pin: self.pin, + _mode: PhantomData, + }; + adc.enable_pin(&new); + new + } +} - impl digital::ToggleableOutputPin for $GenericPin { - type Error = Void; - - fn toggle(&mut self) -> Result<(), Self::Error> { - match self { - $( - $GenericPin::$PortEnum(i, _) => unsafe { - (*<$PORTX>::ptr()) - .$reg_pin - .write(|w| w.bits(1 << *i)) - }, - )+ - } - Ok(()) - } - } +/// # Downgrading +/// For applications where the exact pin is irrelevant, a specific pin can be downgraded to a +/// "dynamic pin" which can represent any pin: +/// +/// ```ignore +/// use atmega_hal::port::{Pin, mode}; +/// +/// let dp = atmega_hal::Peripherals::take().unwrap(); +/// let pins = atmega_hal::pins!(dp); +/// +/// let any_output_pin1: Pin = pins.pd0.into_output().downgrade(); +/// let any_output_pin2: Pin = pins.pd1.into_output().downgrade(); +/// +/// // Because they now have the same type, you can, for example, stuff them into an array: +/// let pins: [Pin; 2] = [any_output_pin1, any_output_pin2]; +/// ``` +impl Pin { + /// "Erase" type-level information about which specific pin is represented. + /// + /// *Note*: The returned "dynamic" pin has runtime overhead compared to a specific pin. + pub fn downgrade(self) -> Pin { + Pin { + pin: self.pin.into_dynamic(), + _mode: PhantomData, + } + } +} - impl digital::InputPin for $GenericPin> { - type Error = Void; - - fn is_high(&self) -> Result { - Ok(match self { - $( - $GenericPin::$PortEnum(i, _) => unsafe { - (*<$PORTX>::ptr()) - .$reg_pin.read().bits() & (1 << *i) != 0 - } - )+ - }) - } +/// # Input-Mode Downgrading +/// There is a second kind of downgrading: In some cases it is not important whether an input pin +/// is configured as [`mode::PullUp`] or [`mode::Floating`]. For this, you can "forget" the +/// concrete input mode, leaving you with a type that is the same for pull-up or floating inputs: +/// +/// ```ignore +/// use atmega_hal::port::{Pin, mode}; +/// +/// let dp = atmega_hal::Peripherals::take().unwrap(); +/// let pins = atmega_hal::pins!(dp); +/// +/// // This demo uses downgraded pins, but it works just as well +/// // with non-downgraded ones! +/// let input_pin1: Pin> = pins.pd0 +/// .into_floating_input() +/// .downgrade(); +/// let input_pin2: Pin> = pins.pd1 +/// .into_pull_up_input() +/// .downgrade(); +/// +/// // With the input mode "forgotten", they have the same type now, +/// // even if electically different. +/// let any_inputs: [Pin; 2] = [ +/// input_pin1.forget_imode(), +/// input_pin2.forget_imode(), +/// ]; +/// ``` +impl Pin, PIN> { + /// "Erase" type-level information about whether the pin is currently a pull-up or a floating + /// input. + pub fn forget_imode(self) -> Pin { + Pin { + pin: self.pin, + _mode: PhantomData, + } + } +} - fn is_low(&self) -> Result { - Ok(match self { - $( - $GenericPin::$PortEnum(i, _) => unsafe { - (*<$PORTX>::ptr()) - .$reg_pin.read().bits() & (1 << *i) == 0 - } - )+ - }) - } - } +/// # Digital Output +impl Pin { + /// Set pin high (pull it to supply voltage). + #[inline] + pub fn set_high(&mut self) { + unsafe { self.pin.out_set() } + } - impl digital::OutputPin for $GenericPin { - type Error = Void; - - fn set_high(&mut self) -> Result<(), Self::Error> { - match self { - $( - $GenericPin::$PortEnum(i, _) => unsafe { - (*<$PORTX>::ptr()).$reg_ddr.modify(|r, w| { - w.bits(r.bits() & !(1 << *i)) - }) - }, - )+ - } - Ok(()) - } + /// Set pin low (pull it to GND). + #[inline] + pub fn set_low(&mut self) { + unsafe { self.pin.out_clear() } + } - fn set_low(&mut self) -> Result<(), Self::Error> { - match self { - $( - $GenericPin::$PortEnum(i, _) => unsafe { - (*<$PORTX>::ptr()).$reg_ddr.modify(|r, w| { - w.bits(r.bits() | (1 << *i)) - }) - }, - )+ - } - Ok(()) - } - } + /// Toggle a high pin to low and a low pin to high. + #[inline] + pub fn toggle(&mut self) { + unsafe { self.pin.out_toggle() } + } - impl digital::InputPin for $GenericPin { - type Error = Void; - - fn is_high(&self) -> Result { - Ok(match self { - $( - $GenericPin::$PortEnum(i, _) => unsafe { - (*<$PORTX>::ptr()) - .$reg_pin.read().bits() & (1 << *i) != 0 - } - )+ - }) - } + /// Check whether the pin is set high. + /// + /// *Note*: The electrical state of the pin might differ due to external circuitry. + #[inline] + pub fn is_set_high(&self) -> bool { + unsafe { self.pin.out_get() } + } - fn is_low(&self) -> Result { - Ok(match self { - $( - $GenericPin::$PortEnum(i, _) => unsafe { - (*<$PORTX>::ptr()) - .$reg_pin.read().bits() & (1 << *i) == 0 - } - )+ - }) - } - } - // -------------------------------------------------------- }}} - } - pub use self::generic_pin::$GenericPin; - }; + /// Check whether the pin is set low. + /// + /// *Note*: The electrical state of the pin might differ due to external circuitry. + #[inline] + pub fn is_set_low(&self) -> bool { + !unsafe { self.pin.out_get() } + } +} + +/// # Digital Input +impl Pin, PIN> { + /// Check whether the pin is driven high. + #[inline] + pub fn is_high(&self) -> bool { + unsafe { self.pin.in_get() } + } + + /// Check whether the pin is driven low. + #[inline] + pub fn is_low(&self) -> bool { + !unsafe { self.pin.in_get() } + } +} + +/// # Analog Input +/// +/// Some pins can be configured as ADC channels. For those pins, `analog_read()` can be used to +/// read the voltage. `analog_read()` corresponds to a blocking ADC read: +/// +/// ``` +/// let dp = atmega_hal::Peripherals::take().unwrap(); +/// let pins = atmega_hal::pins!(dp); +/// let mut adc = atmega_hal::Adc::new(dp.ADC, Default::default()); +/// +/// let a0 = dp.pc0.into_analog_input(&mut adc); +/// +/// let voltage = a0.analog_read(&mut adc); +/// // ^- this is equivalent to -v +/// let voltage = adc.read_blocking(&a0); +/// ``` +impl Pin { + pub fn analog_read(&self, adc: &mut crate::adc::Adc) -> u16 + where + Pin: crate::adc::AdcChannel, + ADC: crate::adc::AdcOps, + CLOCK: crate::clock::Clock, + { + adc.read_blocking(self) + } + + /// Convert this pin into a generic [`Channel`][adc-channel] type. + /// + /// The generic channel type can be used to store multiple channels in an array. + /// + /// [adc-channel]: crate::adc::Channel + pub fn into_channel(self) -> crate::adc::Channel + where + Pin: crate::adc::AdcChannel, + ADC: crate::adc::AdcOps, + { + crate::adc::Channel::new(self) + } } -/// Implement pin abstractions for a port peripheral #[macro_export] -macro_rules! impl_port { - // With a generic pin +macro_rules! impl_port_traditional { ( - pub mod $portx:ident { - #[port_ext] - use $portext_use:path; - - #[generic_pin] - use $GenericPin:ident::$PortEnum:ident; + enum Ports { + $($PortName:ident: ($Port:ty, $port_port_reg:ident, $port_pin_reg:ident, $port_ddr_reg:ident),)+ + } - impl $PortExt:ident for $PORTX:ty { - regs: ($reg_pin:ident, $reg_ddr:ident, $reg_port:ident), - $($pxi:ident: ($PXi:ident, $i:expr),)+ - } + $(#[$pins_attr:meta])* + pub struct Pins { + $($pin:ident: $Pin:ident = ($PinPort:ty, $PinPortName:ident, $pin_num:expr, + $pin_port_reg:ident, $pin_pin_reg:ident, + $pin_ddr_reg:ident),)+ } ) => { - $crate::impl_port! { - pub mod $portx { - #[port_ext] - use $portext_use; - - impl $PortExt for $PORTX { - regs: ($reg_pin, $reg_ddr, $reg_port), - $($pxi: ($PXi, $i),)+ - } - } + pub use $crate::port::mode; + + /// Type-alias for a pin type which can represent any concrete pin. + /// + /// Sometimes it is easier to handle pins if they are all of the same type. By default, + /// each pin gets its own distinct type in `avr-hal`, but by + /// [downgrading][avr_hal_generic::port::Pin#downgrading], you can cast them into this + /// "dynamic" type. Do note, however, that using this dynamic type has a runtime cost. + pub type Pin = $crate::port::Pin; + + $(#[$pins_attr])* + pub struct Pins { + $(pub $pin: Pin< + mode::Input, + $Pin, + >,)+ } - // Downgrade implementation ------------------------------- {{{ - $( - impl $portx::$PXi { - /// Downgrade this pin into a type that is generic over all pins. - /// - /// The main use for this function is to store multiple pins in an array. Please - /// note that generic pins have a runtime overhead. - /// - /// See the [general Digital IO documentation][1] and the [`Pin` type][2] for more - /// information. - /// - /// # Example - /// ```rust - /// let p1 = portb.pb1.downgrade(); - /// let p2 = portc.pc7.downgrade(); - /// let pins = [p1, p2]; - /// ``` - /// - /// [1]: ../../../avr_hal_generic/port/index.html - /// [2]: ../enum.Pin.html - pub fn downgrade(self) -> $GenericPin { - $GenericPin::$PortEnum($i, ::core::marker::PhantomData) + impl Pins { + pub fn new( + $(_: $Port,)+ + ) -> Self { + Self { + $($pin: $crate::port::Pin::new( + $Pin { _private: (), } + ),)+ } } - )+ - // -------------------------------------------------------- }}} - }; - // Without a generic pin - ( - pub mod $portx:ident { - #[port_ext] - use $portext_use:path; + } - impl $PortExt:ident for $PORTX:ty { - regs: ($reg_pin:ident, $reg_ddr:ident, $reg_port:ident), - $($pxi:ident: ($PXi:ident, $i:expr),)+ - } + #[repr(u8)] + pub enum DynamicPort { + $($PortName,)+ } - ) => { - pub mod $portx { - use core::marker; - use $crate::void::Void; - use $crate::hal::digital::v2 as digital; - use $crate::port::mode; - - // We have to "use" the port-ext trait so we can implement it inside - // the macro. - use $portext_use; - - pub struct Parts { - pub ddr: DDR, - $( - pub $pxi: $PXi>, - )+ - } - impl $PortExt for $PORTX { - type Parts = Parts; + pub struct Dynamic { + port: DynamicPort, + // We'll store the mask instead of the pin number because this allows much less code to + // be generated for the trait method implementations. + mask: u8, + } - fn split(self) -> Parts { - Parts { - ddr: DDR { _0: () }, - $($pxi: $PXi { _mode: marker::PhantomData },)+ - } + impl Dynamic { + fn new(port: DynamicPort, pin_num: u8) -> Self { + Self { + port, + mask: 1 << pin_num, } } + } - /// Marker trait for types that can be used as DDR - pub trait AsDDR { - fn as_ddr(&self) -> &DDR; - } + impl $crate::port::PinOps for Dynamic { + type Dynamic = Self; - pub struct DDR { - _0: (), + #[inline] + fn into_dynamic(self) -> Self::Dynamic { + self } - impl AsDDR for DDR { - fn as_ddr(&self) -> &DDR { self } + #[inline] + unsafe fn out_set(&mut self) { + match self.port { + $(DynamicPort::$PortName => (*<$Port>::ptr()).$port_port_reg.modify(|r, w| { + w.bits(r.bits() | self.mask) + }),)+ + } } - $( - /// Type representing a specific pin. - /// - /// See the [general Digital IO documentation][1] for more info. In short: - /// - /// - Mode is changed with - /// - `.into_output()` - /// - `.into_floating_input()` - /// - `.into_pull_up_input()` - /// - Input pins are sampled with - /// - `.is_high().void_unwrap()` - /// - `.is_low().void_unwrap()` - /// - Output pins are set with - /// - `.set_high().void_unwrap()` - /// - `.set_low().void_unwrap()` - /// - /// and can be checked with - /// - `.is_set_high().void_unwrap()` - /// - `.is_set_low().void_unwrap()` - /// - Pins can be downgraded into a generic type using `.downgrade()`. - /// - /// [1]: ../../../avr_hal_generic/port/index.html - pub struct $PXi { - pub(crate)_mode: marker::PhantomData, + #[inline] + unsafe fn out_clear(&mut self) { + match self.port { + $(DynamicPort::$PortName => (*<$Port>::ptr()).$port_port_reg.modify(|r, w| { + w.bits(r.bits() & !self.mask) + }),)+ } + } - // Mode Switch implementations ---------------------------- {{{ - // - Unsafe: The unsafe blocks in here are ok, because these - // operations will compile down to single, atomic - // `sbi`, `cbi`, `sbic`, `sbis` instructions. - impl $PXi { - // The following methods are only defined if the pin is in - // a digital-io mode. This ensures that a pin used by another - // peripheral can't be converted back (because that would - // not be universally possible). - - /// Make this pin a digital output. - pub fn into_output(self, ddr: &D) -> $PXi { - unsafe { - (*<$PORTX>::ptr()).$reg_ddr.modify(|r, w| { - w.bits(r.bits() | (1 << $i)) - }); - } - $PXi { _mode: marker::PhantomData } - } - - /// Make this pin a digital input **without** enabling the internal pull-up. - pub fn into_floating_input(self, ddr: &D) -> $PXi> { - unsafe { - (*<$PORTX>::ptr()).$reg_ddr.modify(|r, w| { - w.bits(r.bits() & !(1 << $i)) - }); - (*<$PORTX>::ptr()).$reg_port.modify(|r, w| { - w.bits(r.bits() & !(1 << $i)) - }); - } - $PXi { _mode: marker::PhantomData } - } - - /// Make this pin a digital input and enable the internal pull-up. - pub fn into_pull_up_input(self, ddr: &D) -> $PXi> { - unsafe { - (*<$PORTX>::ptr()).$reg_ddr.modify(|r, w| { - w.bits(r.bits() & !(1 << $i)) - }); - (*<$PORTX>::ptr()).$reg_port.modify(|r, w| { - w.bits(r.bits() | (1 << $i)) - }); - } - $PXi { _mode: marker::PhantomData } - } - - /// Make this pin a tri-state pin. Default state is released (high) mode. - /// Internal pull-up is not used. - /// - /// Note that, as always, it is ***not safe*** to connect the external - /// pull-up to a voltage higher than VCC + 0.5. See your chip's - /// datasheet for more details. - pub fn into_tri_state(self, ddr: &D) -> $PXi { - unsafe { - (*<$PORTX>::ptr()).$reg_ddr.modify(|r, w| { - w.bits(r.bits() & !(1 << $i)) - }); - (*<$PORTX>::ptr()).$reg_port.modify(|r, w| { - w.bits(r.bits() & !(1 << $i)) - }); - } - $PXi { _mode: marker::PhantomData } - } + #[inline] + unsafe fn out_toggle(&mut self) { + match self.port { + $(DynamicPort::$PortName => (*<$Port>::ptr()).$port_pin_reg.modify(|r, w| { + w.bits(r.bits() | self.mask) + }),)+ } - // -------------------------------------------------------- }}} - - // Input & Output implementations ------------------------- {{{ - // - Unsafe: The unsafe blocks in here are ok, because these - // operations will compile down to single, atomic - // `sbi`, `cbi`, `sbic`, `sbis` instructions. - impl digital::OutputPin for $PXi { - type Error = Void; - - fn set_high(&mut self) -> Result<(), Self::Error> { - unsafe { - (*<$PORTX>::ptr()).$reg_port.modify(|r, w| { - w.bits(r.bits() | (1 << $i)) - }); - } - Ok(()) - } + } - fn set_low(&mut self) -> Result<(), Self::Error> { - unsafe { - (*<$PORTX>::ptr()).$reg_port.modify(|r, w| { - w.bits(r.bits() & !(1 << $i)) - }); - } - Ok(()) - } + #[inline] + unsafe fn out_get(&self) -> bool { + match self.port { + $(DynamicPort::$PortName => (*<$Port>::ptr()).$port_port_reg.read().bits() + & self.mask != 0,)+ } + } - impl digital::StatefulOutputPin for $PXi { - fn is_set_high(&self) -> Result { - Ok(unsafe { - (*<$PORTX>::ptr()).$reg_port.read().bits() - } & (1 << $i) != 0) - } - - fn is_set_low(&self) -> Result { - self.is_set_high().map(|b| !b) - } + #[inline] + unsafe fn in_get(&self) -> bool { + match self.port { + $(DynamicPort::$PortName => (*<$Port>::ptr()).$port_pin_reg.read().bits() + & self.mask != 0,)+ } + } - impl digital::ToggleableOutputPin for $PXi { - type Error = Void; + #[inline] + unsafe fn make_output(&mut self) { + match self.port { + $(DynamicPort::$PortName => (*<$Port>::ptr()).$port_ddr_reg.modify(|r, w| { + w.bits(r.bits() | self.mask) + }),)+ + } + } - fn toggle(&mut self) -> Result<(), Self::Error> { - unsafe { - (*<$PORTX>::ptr()).$reg_pin.write(|w| { - w.bits(1 << $i) - }); - } - Ok(()) - } + #[inline] + unsafe fn make_input(&mut self, pull_up: bool) { + match self.port { + $(DynamicPort::$PortName => (*<$Port>::ptr()).$port_ddr_reg.modify(|r, w| { + w.bits(r.bits() & !self.mask) + }),)+ + } + if pull_up { + self.out_clear() + } else { + self.out_set() } + } + } - impl digital::InputPin for $PXi> { - type Error = Void; + $( + pub struct $Pin { + _private: () + } - fn is_high(&self) -> Result { - Ok(unsafe { - (*<$PORTX>::ptr()).$reg_pin.read().bits() - } & (1 << $i) != 0) - } + impl $crate::port::PinOps for $Pin { + type Dynamic = Dynamic; - fn is_low(&self) -> Result { - Ok(unsafe { - (*<$PORTX>::ptr()).$reg_pin.read().bits() - } & (1 << $i) == 0) - } + #[inline] + fn into_dynamic(self) -> Self::Dynamic { + Dynamic::new(DynamicPort::$PinPortName, $pin_num) } - impl digital::OutputPin for $PXi { - type Error = Void; + #[inline] + unsafe fn out_set(&mut self) { + (*<$PinPort>::ptr()).$pin_port_reg.modify(|r, w| { + w.bits(r.bits() | (1 << $pin_num)) + }) + } - fn set_high(&mut self) -> Result<(), Self::Error> { - unsafe { - (*<$PORTX>::ptr()).$reg_ddr.modify(|r, w| { - w.bits(r.bits() & !(1 << $i)) - }); - } - Ok(()) - } + #[inline] + unsafe fn out_clear(&mut self) { + (*<$PinPort>::ptr()).$pin_port_reg.modify(|r, w| { + w.bits(r.bits() & !(1 << $pin_num)) + }) + } - fn set_low(&mut self) -> Result<(), Self::Error> { - unsafe { - (*<$PORTX>::ptr()).$reg_ddr.modify(|r, w| { - w.bits(r.bits() | (1 << $i)) - }); - } - Ok(()) - } + #[inline] + unsafe fn out_toggle(&mut self) { + (*<$PinPort>::ptr()).$pin_pin_reg.modify(|r, w| { + w.bits(r.bits() | (1 << $pin_num)) + }) } - impl digital::InputPin for $PXi { - type Error = Void; + #[inline] + unsafe fn out_get(&self) -> bool { + (*<$PinPort>::ptr()).$pin_port_reg.read().bits() & (1 << $pin_num) != 0 + } - fn is_high(&self) -> Result { - Ok(unsafe { - (*<$PORTX>::ptr()).$reg_pin.read().bits() - } & (1 << $i) != 0) - } + #[inline] + unsafe fn in_get(&self) -> bool { + (*<$PinPort>::ptr()).$pin_pin_reg.read().bits() & (1 << $pin_num) != 0 + } - fn is_low(&self) -> Result { - Ok(unsafe { - (*<$PORTX>::ptr()).$reg_pin.read().bits() - } & (1 << $i) == 0) - } + #[inline] + unsafe fn make_output(&mut self) { + (*<$PinPort>::ptr()).$pin_ddr_reg.modify(|r, w| { + w.bits(r.bits() | (1 << $pin_num)) + }) } - // -------------------------------------------------------- }}} - )+ - } + #[inline] + unsafe fn make_input(&mut self, pull_up: bool) { + (*<$PinPort>::ptr()).$pin_ddr_reg.modify(|r, w| { + w.bits(r.bits() & !(1 << $pin_num)) + }); + if pull_up { + self.out_set() + } else { + self.out_clear() + } + } + } + )+ }; } -/// Create a pin reexport struct for convenient access #[macro_export] -macro_rules! impl_board_pins { +macro_rules! renamed_pins { ( - #[port_defs] - use $portpath:path; - - $(#[$ddr_attr:meta])* - pub struct $DDR:ident { - $($portx:ident: $PORTX:ty,)+ - } + type Pin = $PinType:ident; $(#[$pins_attr:meta])* - pub struct $Pins:ident { - $( - $(#[$pin_attr:meta])* - pub $name:ident: $pinport:ident::$pin:ident::$Pin:ident, - )+ + pub struct Pins from $McuPins:ty { + $($(#[$pin_attr:meta])* pub $pin:ident: $Pin:ty = $pin_orig:ident,)+ } ) => { - use $portpath::{$($portx),+}; - - $(#[$ddr_attr])* - pub struct $DDR { - $($portx: $portx::DDR,)+ - } - - $( - impl $portx::AsDDR for $DDR { - fn as_ddr(&self) -> &$portx::DDR { - &self.$portx - } - } - )+ - $(#[$pins_attr])* - pub struct $Pins { - pub ddr: $DDR, - $( - $(#[$pin_attr])* - pub $name: $pinport::$Pin< - $crate::port::mode::Input<$crate::port::mode::Floating> - >, - )+ + pub struct Pins { + $($(#[$pin_attr])* + pub $pin: $PinType< + $crate::port::mode::Input<$crate::port::mode::Floating>, + $Pin, + >,)+ } - impl $Pins { - pub fn new($($portx: $PORTX),+) -> $Pins { - $(let $portx = $portx.split();)+ - - $Pins { - ddr: $DDR { - $($portx: $portx.ddr,)+ - }, - $($name: $pinport.$pin,)+ + impl Pins { + pub fn with_mcu_pins(pins: $McuPins) -> Self { + Self { + $($pin: pins.$pin_orig,)+ } } } diff --git a/avr-hal-generic/src/spi.rs b/avr-hal-generic/src/spi.rs index fe26748fde..202021cce2 100644 --- a/avr-hal-generic/src/spi.rs +++ b/avr-hal-generic/src/spi.rs @@ -1,4 +1,6 @@ //! SPI Implementation +use crate::port; +use core::marker::PhantomData; use embedded_hal::spi; /// Oscillator Clock Frequency division options. @@ -64,220 +66,272 @@ impl Default for Settings { } } +/// Internal trait for low-level SPI peripherals +/// +/// This trait defines the common interface for all SPI peripheral variants. It is used as an +/// intermediate abstraction ontop of which the [`Spi`] API is built. **Prefer using the +/// [`Spi`] API instead of this trait.** +pub trait SpiOps { + fn raw_setup(&mut self, settings: &Settings); + fn raw_release(&mut self); -/// Implement traits for a SPI interface -#[macro_export] -macro_rules! impl_spi { - ( - $(#[$spi_attr:meta])* - pub struct $Spi:ident { - peripheral: $SPI:ty, - pins: { - sclk: $sclkmod:ident::$SCLK:ident, - mosi: $mosimod:ident::$MOSI:ident, - miso: $misomod:ident::$MISO:ident, - cs: $csmod:ident::$CS:ident, - } - } - ) => { - /// First match was without a 'ChipSelectPin' - /// we set it here to a default name and then - /// recusiv expand to the real inplementation - $crate::impl_spi! { - pub struct $Spi { - peripheral: $SPI, - pins: { - sclk: $sclkmod::$SCLK, - mosi: $mosimod::$MOSI, - miso: $misomod::$MISO, - cs: $csmod::$CS, - } - } - pub struct ChipSelectPin; - } - }; - + fn raw_check_iflag(&self) -> bool; + fn raw_read(&self) -> u8; + fn raw_write(&mut self, byte: u8); +} - ( - $(#[$spi_attr:meta])* - pub struct $Spi:ident { - peripheral: $SPI:ty, - pins: { - sclk: $sclkmod:ident::$SCLK:ident, - mosi: $mosimod:ident::$MOSI:ident, - miso: $misomod:ident::$MISO:ident, - cs: $csmod:ident::$CS:ident, - } - } - pub struct $ChipSelectPin:ident; - ) => { +/// Wrapper for the CS pin +/// +/// Used to contain the chip-select pin during operation to prevent its mode from being +/// changed from Output. This is necessary because the SPI state machine would otherwise +/// reset itself to SPI slave mode immediately. This wrapper can be used just like an +/// output pin, because it implements all the same traits from embedded-hal. +pub struct ChipSelectPin(port::Pin); - /// Wrapper for the CS pin - /// - /// Used to contain the chip-select pin during operation to prevent its mode from being - /// changed from Output. This is necessary because the SPI state machine would otherwise - /// reset itself to SPI slave mode immediately. This wrapper can be used just like an - /// output pin, because it implements all the same traits from embedded-hal. - pub struct $ChipSelectPin($csmod::$CS<$crate::port::mode::Output>); - impl $crate::hal::digital::v2::OutputPin for $ChipSelectPin { - type Error = $crate::void::Void; - fn set_low(&mut self) -> Result<(), Self::Error> { - self.0.set_low() - } - fn set_high(&mut self) -> Result<(), Self::Error> { - self.0.set_high() - } - } - impl $crate::hal::digital::v2::StatefulOutputPin for $ChipSelectPin { - fn is_set_low(&self) -> Result { - self.0.is_set_low() - } - fn is_set_high(&self) -> Result { - self.0.is_set_high() - } - } - impl $crate::hal::digital::v2::ToggleableOutputPin for $ChipSelectPin { - type Error = $crate::void::Void; - fn toggle(&mut self) -> Result<(), Self::Error> { - self.0.toggle() - } - } +impl hal::digital::v2::OutputPin for ChipSelectPin { + type Error = crate::void::Void; + fn set_low(&mut self) -> Result<(), Self::Error> { + self.0.set_low(); + Ok(()) + } + fn set_high(&mut self) -> Result<(), Self::Error> { + self.0.set_high(); + Ok(()) + } +} - /// Behavior for a SPI interface. - /// - /// Stores the SPI peripheral for register access. In addition, it takes - /// ownership of the MOSI and MISO pins to ensure they are in the correct mode. - /// Instantiate with the `new` method. - $(#[$spi_attr])* - pub struct $Spi { - peripheral: $SPI, - sclk: $sclkmod::$SCLK<$crate::port::mode::Output>, - mosi: $mosimod::$MOSI<$crate::port::mode::Output>, - miso: $misomod::$MISO<$crate::port::mode::Input>, - settings: Settings, - is_write_in_progress: bool, - } +impl hal::digital::v2::StatefulOutputPin for ChipSelectPin { + fn is_set_low(&self) -> Result { + Ok(self.0.is_set_low()) + } + fn is_set_high(&self) -> Result { + Ok(self.0.is_set_high()) + } +} - impl $Spi<$crate::port::mode::PullUp> { - /// Instantiate an SPI with the registers, SCLK/MOSI/MISO/CS pins, and settings, - /// with the internal pull-up enabled on the MISO pin. - /// - /// The pins are not actually used directly, but they are moved into the struct in - /// order to enforce that they are in the correct mode, and cannot be used by anyone - /// else while SPI is active. CS is placed into a `ChipSelectPin` instance and given - /// back so that its output state can be changed as needed. - pub fn new( - peripheral: $SPI, - sclk: $sclkmod::$SCLK<$crate::port::mode::Output>, - mosi: $mosimod::$MOSI<$crate::port::mode::Output>, - miso: $misomod::$MISO<$crate::port::mode::Input<$crate::port::mode::PullUp>>, - cs: $csmod::$CS<$crate::port::mode::Output>, - settings: Settings - ) -> (Self, $ChipSelectPin) { - let spi = $Spi { - peripheral, - sclk, - mosi, - miso, - settings, - is_write_in_progress: false, - }; - spi.setup(); - (spi, $ChipSelectPin(cs)) - } - } +impl hal::digital::v2::ToggleableOutputPin for ChipSelectPin { + type Error = crate::void::Void; + fn toggle(&mut self) -> Result<(), Self::Error> { + self.0.toggle(); + Ok(()) + } +} + +/// Behavior for a SPI interface. +/// +/// Stores the SPI peripheral for register access. In addition, it takes +/// ownership of the MOSI and MISO pins to ensure they are in the correct mode. +/// Instantiate with the `new` method. +pub struct Spi { + p: SPI, + sclk: port::Pin, + mosi: port::Pin, + miso: port::Pin, + write_in_progress: bool, + _cs: PhantomData, + _h: PhantomData, +} + +impl Spi +where + SPI: SpiOps, + SCLKPIN: port::PinOps, + MOSIPIN: port::PinOps, + MISOPIN: port::PinOps, + CSPIN: port::PinOps, +{ + /// Instantiate an SPI with the registers, SCLK/MOSI/MISO/CS pins, and settings, + /// with the internal pull-up enabled on the MISO pin. + /// + /// The pins are not actually used directly, but they are moved into the struct in + /// order to enforce that they are in the correct mode, and cannot be used by anyone + /// else while SPI is active. CS is placed into a `ChipSelectPin` instance and given + /// back so that its output state can be changed as needed. + pub fn new( + p: SPI, + sclk: port::Pin, + mosi: port::Pin, + miso: port::Pin, MISOPIN>, + cs: port::Pin, + settings: Settings, + ) -> (Self, ChipSelectPin) { + let mut spi = Self { + p, + sclk, + mosi, + miso: miso.forget_imode(), + write_in_progress: false, + _cs: PhantomData, + _h: PhantomData, + }; + spi.p.raw_setup(&settings); + (spi, ChipSelectPin(cs)) + } - impl $Spi<$crate::port::mode::Floating> { - /// Instantiate an SPI with the registers, SCLK/MOSI/MISO/CS pins, and settings, - /// with an external pull-up on the MISO pin. - /// - /// The pins are not actually used directly, but they are moved into the struct in - /// order to enforce that they are in the correct mode, and cannot be used by anyone - /// else while SPI is active. CS is placed into a `ChipSelectPin` instance and given - /// back so that its output state can be changed as needed. - pub fn with_external_pullup( - peripheral: $SPI, - sclk: $sclkmod::$SCLK<$crate::port::mode::Output>, - mosi: $mosimod::$MOSI<$crate::port::mode::Output>, - miso: $misomod::$MISO<$crate::port::mode::Input<$crate::port::mode::Floating>>, - settings: Settings - ) -> Self { - let spi = $Spi { - peripheral, - sclk, - mosi, - miso, - settings, - is_write_in_progress: false, - }; - spi.setup(); - spi + /// Instantiate an SPI with the registers, SCLK/MOSI/MISO/CS pins, and settings, + /// with an external pull-up on the MISO pin. + /// + /// The pins are not actually used directly, but they are moved into the struct in + /// order to enforce that they are in the correct mode, and cannot be used by anyone + /// else while SPI is active. + pub fn with_external_pullup( + p: SPI, + sclk: port::Pin, + mosi: port::Pin, + miso: port::Pin, MISOPIN>, + cs: port::Pin, + settings: Settings, + ) -> (Self, ChipSelectPin) { + let mut spi = Self { + p, + sclk, + mosi, + miso: miso.forget_imode(), + write_in_progress: false, + _cs: PhantomData, + _h: PhantomData, + }; + spi.p.raw_setup(&settings); + (spi, ChipSelectPin(cs)) + } + + /// Reconfigure the SPI peripheral after initializing + pub fn reconfigure(&mut self, settings: Settings) -> nb::Result<(), crate::void::Void> { + // wait for any in-flight writes to complete + self.flush()?; + self.p.raw_setup(&settings); + Ok(()) + } + + /// Disable the SPI device and release ownership of the peripheral + /// and pins. Instance can no-longer be used after this is + /// invoked. + pub fn release( + mut self, + cs: ChipSelectPin, + ) -> ( + SPI, + port::Pin, + port::Pin, + port::Pin, + port::Pin, + ) { + self.p.raw_release(); + (self.p, self.sclk, self.mosi, self.miso, cs.0) + } + + fn flush(&mut self) -> nb::Result<(), void::Void> { + if self.write_in_progress { + if self.p.raw_check_iflag() { + self.write_in_progress = false; + } else { + return Err(nb::Error::WouldBlock); } } + Ok(()) + } - impl $Spi { - /// Disable the SPI device and release ownership of the peripheral - /// and pins. Instance can no-longer be used after this is - /// invoked. - pub fn release(self, cs: $ChipSelectPin) -> ( - $SPI, - $sclkmod::$SCLK<$crate::port::mode::Output>, - $mosimod::$MOSI<$crate::port::mode::Output>, - $misomod::$MISO<$crate::port::mode::Input>, - $csmod::$CS<$crate::port::mode::Output>, - ) { - self.peripheral.spcr.write(|w| { - w.spe().clear_bit() - }); - (self.peripheral, self.sclk, self.mosi, self.miso, cs.0) - } + fn receive(&mut self) -> u8 { + self.p.raw_read() + } - /// Write a byte to the data register, which begins transmission - /// automatically. - fn write(&mut self, byte: u8) { - self.is_write_in_progress = true; - self.peripheral.spdr.write(|w| unsafe { w.bits(byte) }); - } + fn write(&mut self, byte: u8) { + self.write_in_progress = true; + self.p.raw_write(byte); + } +} - /// Check if write flag is set, and return a WouldBlock error if it is not. - fn flush(&mut self) -> $crate::nb::Result<(), $crate::void::Void> { - if self.is_write_in_progress { - if self.peripheral.spsr.read().spif().bit_is_set() { - self.is_write_in_progress = false; - } else { - return Err($crate::nb::Error::WouldBlock); - } - } - Ok(()) - } +/// FullDuplex trait implementation, allowing this struct to be provided to +/// drivers that require it for operation. Only 8-bit word size is supported +/// for now. +impl spi::FullDuplex + for Spi +where + SPI: SpiOps, + SCLKPIN: port::PinOps, + MOSIPIN: port::PinOps, + MISOPIN: port::PinOps, + CSPIN: port::PinOps, +{ + type Error = void::Void; + + /// Sets up the device for transmission and sends the data + fn send(&mut self, byte: u8) -> nb::Result<(), Self::Error> { + self.flush()?; + self.write(byte); + Ok(()) + } + + /// Reads and returns the response in the data register + fn read(&mut self) -> nb::Result { + self.flush()?; + Ok(self.receive()) + } +} + +/// Default Transfer trait implementation. Only 8-bit word size is supported for now. +impl hal::blocking::spi::transfer::Default + for Spi +where + SPI: SpiOps, + SCLKPIN: port::PinOps, + MOSIPIN: port::PinOps, + MISOPIN: port::PinOps, + CSPIN: port::PinOps, +{ +} + +/// Default Write trait implementation. Only 8-bit word size is supported for now. +impl hal::blocking::spi::write::Default + for Spi +where + SPI: SpiOps, + SCLKPIN: port::PinOps, + MOSIPIN: port::PinOps, + MISOPIN: port::PinOps, + CSPIN: port::PinOps, +{ +} +/// Implement traits for a SPI interface +#[macro_export] +macro_rules! impl_spi { + ( + hal: $HAL:ty, + peripheral: $SPI:ty, + sclk: $sclkpin:ty, + mosi: $mosipin:ty, + miso: $misopin:ty, + cs: $cspin:ty, + ) => { + impl $crate::spi::SpiOps<$HAL, $sclkpin, $mosipin, $misopin, $cspin> for $SPI { /// Sets up the control/status registers with the right settings for this secondary device - fn setup(&self) { + fn raw_setup(&mut self, settings: &Settings) { use $crate::hal::spi; // set up control register - self.peripheral.spcr.write(|w| { + self.spcr.write(|w| { // enable SPI w.spe().set_bit(); // Set to primary mode w.mstr().set_bit(); // set up data order control bit - match self.settings.data_order { + match settings.data_order { DataOrder::MostSignificantFirst => w.dord().clear_bit(), DataOrder::LeastSignificantFirst => w.dord().set_bit(), }; // set up polarity control bit - match self.settings.mode.polarity { + match settings.mode.polarity { spi::Polarity::IdleHigh => w.cpol().set_bit(), spi::Polarity::IdleLow => w.cpol().clear_bit(), }; // set up phase control bit - match self.settings.mode.phase { + match settings.mode.phase { spi::Phase::CaptureOnFirstTransition => w.cpha().clear_bit(), spi::Phase::CaptureOnSecondTransition => w.cpha().set_bit(), }; // set up clock rate control bit - match self.settings.clock { + match settings.clock { SerialClockRate::OscfOver2 => w.spr().fosc_4_2(), SerialClockRate::OscfOver4 => w.spr().fosc_4_2(), SerialClockRate::OscfOver8 => w.spr().fosc_16_8(), @@ -288,7 +342,7 @@ macro_rules! impl_spi { } }); // set up 2x clock rate status bit - self.peripheral.spsr.write(|w| match self.settings.clock { + self.spsr.write(|w| match settings.clock { SerialClockRate::OscfOver2 => w.spi2x().set_bit(), SerialClockRate::OscfOver4 => w.spi2x().clear_bit(), SerialClockRate::OscfOver8 => w.spi2x().set_bit(), @@ -298,44 +352,27 @@ macro_rules! impl_spi { SerialClockRate::OscfOver128 => w.spi2x().clear_bit(), }); } - // to reconfigure the peripheral after initializing - pub fn reconfigure(&mut self, settings: Settings) -> $crate::nb::Result<(), $crate::void::Void> { - // wait for any in-flight writes to complete - self.flush()?; - self.settings = settings; - self.setup(); - Ok(()) - } - } - /// FullDuplex trait implementation, allowing this struct to be provided to - /// drivers that require it for operation. Only 8-bit word size is supported - /// for now. - impl $crate::hal::spi::FullDuplex for $Spi { - type Error = $crate::void::Void; - - /// Sets up the device for transmission and sends the data - fn send(&mut self, byte: u8) -> $crate::nb::Result<(), Self::Error> { - self.flush()?; - self.write(byte); - Ok(()) + /// Disable the peripheral + fn raw_release(&mut self) { + self.spcr.write(|w| w.spe().clear_bit()); } - /// Reads and returns the response in the data register - fn read(&mut self) -> $crate::nb::Result { - self.flush()?; - Ok(self.peripheral.spdr.read().bits()) + /// Check the interrupt flag to see if the write has completed + fn raw_check_iflag(&self) -> bool { + self.spsr.read().spif().bit_is_set() } - } - /// Default Trasmer trait implementation. Only 8-bit word size is supported for now. - impl $crate::hal::blocking::spi::transfer::Default for $Spi - { - } + /// Read a byte from the data register + fn raw_read(&self) -> u8 { + self.spdr.read().bits() + } - /// Default Write trait implementation. Only 8-bit word size is supported for now. - impl $crate::hal::blocking::spi::write::Default for $Spi - { + /// Write a byte to the data register, which begins transmission + /// automatically. + fn raw_write(&mut self, byte: u8) { + self.spdr.write(|w| unsafe { w.bits(byte) }); + } } }; } diff --git a/avr-hal-generic/src/usart.rs b/avr-hal-generic/src/usart.rs index eaea508386..1e4181d1d9 100644 --- a/avr-hal-generic/src/usart.rs +++ b/avr-hal-generic/src/usart.rs @@ -6,6 +6,8 @@ use core::cmp::Ordering; use core::marker; use void::ResultVoidExt; +use crate::port; + /// Representation of a USART baudrate /// /// Precalculated parameters for configuring a certain USART baudrate. @@ -160,7 +162,7 @@ pub enum Event { /// This trait defines the common interface for all USART peripheral variants. It is used as an /// intermediate abstraction ontop of which the [`Usart`] API is built. **Prefer using the /// [`Usart`] API instead of this trait.** -pub trait UsartOps { +pub trait UsartOps { /// Enable & initialize this USART peripheral to the given baudrate. /// /// **Warning**: This is a low-level method and should not be called directly from user code. @@ -219,29 +221,50 @@ pub trait UsartOps { /// ufmt::uwriteln!(&mut serial, "Got {}!\r", b).void_unwrap(); /// } /// ``` -pub struct Usart, RX, TX, CLOCK> { +pub struct Usart, RX, TX, CLOCK> { p: USART, rx: RX, tx: TX, _clock: marker::PhantomData, + _h: marker::PhantomData, } -impl, RX, TX, CLOCK> Usart { +impl + Usart< + H, + USART, + port::Pin, + port::Pin, + CLOCK, + > +where + USART: UsartOps, port::Pin>, + RXPIN: port::PinOps, + TXPIN: port::PinOps, +{ /// Initialize a USART peripheral on the given pins. /// /// Note that the RX and TX pins are hardwired for each USART peripheral and you *must* pass /// the correct ones. This is enforced at compile time. - pub fn new(p: USART, rx: RX, tx: TX, baudrate: Baudrate) -> Self { + pub fn new( + p: USART, + rx: port::Pin, RXPIN>, + tx: port::Pin, + baudrate: Baudrate, + ) -> Self { let mut usart = Self { p, - rx, + rx: rx.forget_imode(), tx, _clock: marker::PhantomData, + _h: marker::PhantomData, }; usart.p.raw_init(baudrate); usart } +} +impl, RX, TX, CLOCK> Usart { /// Deinitialize/disable this peripheral and release the pins. pub fn release(mut self) -> (USART, RX, TX) { self.p.raw_deinit(); @@ -284,8 +307,8 @@ impl, RX, TX, CLOCK> Usart { pub fn split( self, ) -> ( - UsartReader, - UsartWriter, + UsartReader, + UsartWriter, ) { ( UsartReader { @@ -293,18 +316,20 @@ impl, RX, TX, CLOCK> Usart { rx: self.rx, _tx: marker::PhantomData, _clock: marker::PhantomData, + _h: marker::PhantomData, }, UsartWriter { p: self.p, tx: self.tx, _rx: marker::PhantomData, _clock: marker::PhantomData, + _h: marker::PhantomData, }, ) } } -impl, RX, TX, CLOCK> ufmt::uWrite for Usart { +impl, RX, TX, CLOCK> ufmt::uWrite for Usart { type Error = void::Void; fn write_str(&mut self, s: &str) -> Result<(), Self::Error> { @@ -315,8 +340,8 @@ impl, RX, TX, CLOCK> ufmt::uWrite for Usart, RX, TX, CLOCK> hal::serial::Write - for Usart +impl, RX, TX, CLOCK> hal::serial::Write + for Usart { type Error = void::Void; @@ -329,7 +354,9 @@ impl, RX, TX, CLOCK> hal::serial::Write } } -impl, RX, TX, CLOCK> hal::serial::Read for Usart { +impl, RX, TX, CLOCK> hal::serial::Read + for Usart +{ type Error = void::Void; fn read(&mut self) -> nb::Result { @@ -344,11 +371,12 @@ impl, RX, TX, CLOCK> hal::serial::Read for Usart, RX, TX, CLOCK> { +pub struct UsartWriter, RX, TX, CLOCK> { p: USART, tx: TX, _rx: marker::PhantomData, _clock: marker::PhantomData, + _h: marker::PhantomData, } /// Reader half of a [`Usart`] peripheral. @@ -357,38 +385,49 @@ pub struct UsartWriter, RX, TX, CLOCK> { /// concurrently receiving and transmitting data from different contexts. /// /// The reader half most notably implements [`embedded_hal::serial::Read`] for receiving data. -pub struct UsartReader, RX, TX, CLOCK> { +pub struct UsartReader, RX, TX, CLOCK> { p: USART, rx: RX, _tx: marker::PhantomData, _clock: marker::PhantomData, + _h: marker::PhantomData, } -impl, RX, TX, CLOCK> UsartWriter { +impl, RX, TX, CLOCK> UsartWriter { /// Merge this `UsartWriter` with a [`UsartReader`] back into a single [`Usart`] peripheral. - pub fn reunite(self, other: UsartReader) -> Usart { + pub fn reunite( + self, + other: UsartReader, + ) -> Usart { Usart { p: self.p, rx: other.rx, tx: self.tx, _clock: marker::PhantomData, + _h: marker::PhantomData, } } } -impl, RX, TX, CLOCK> UsartReader { +impl, RX, TX, CLOCK> UsartReader { /// Merge this `UsartReader` with a [`UsartWriter`] back into a single [`Usart`] peripheral. - pub fn reunite(self, other: UsartWriter) -> Usart { + pub fn reunite( + self, + other: UsartWriter, + ) -> Usart { Usart { p: self.p, rx: self.rx, tx: other.tx, _clock: marker::PhantomData, + _h: marker::PhantomData, } } } -impl, RX, TX, CLOCK> ufmt::uWrite for UsartWriter { +impl, RX, TX, CLOCK> ufmt::uWrite + for UsartWriter +{ type Error = void::Void; fn write_str(&mut self, s: &str) -> Result<(), Self::Error> { @@ -399,8 +438,8 @@ impl, RX, TX, CLOCK> ufmt::uWrite for UsartWriter, RX, TX, CLOCK> hal::serial::Write - for UsartWriter +impl, RX, TX, CLOCK> hal::serial::Write + for UsartWriter { type Error = void::Void; @@ -413,8 +452,8 @@ impl, RX, TX, CLOCK> hal::serial::Write } } -impl, RX, TX, CLOCK> hal::serial::Read - for UsartReader +impl, RX, TX, CLOCK> hal::serial::Read + for UsartReader { type Error = void::Void; @@ -426,15 +465,17 @@ impl, RX, TX, CLOCK> hal::serial::Read #[macro_export] macro_rules! impl_usart_traditional { ( + hal: $HAL:ty, peripheral: $USART:ty, register_suffix: $n:expr, - rx: $rxmod:ident::$RX:ident, - tx: $txmod:ident::$TX:ident, + rx: $rxpin:ty, + tx: $txpin:ty, ) => { $crate::paste::paste! { impl $crate::usart::UsartOps< - $rxmod::$RX<$crate::port::mode::Input<$crate::port::mode::Floating>>, - $txmod::$TX<$crate::port::mode::Output>, + $HAL, + $crate::port::Pin<$crate::port::mode::Input, $rxpin>, + $crate::port::Pin<$crate::port::mode::Output, $txpin>, > for $USART { fn raw_init(&mut self, baudrate: $crate::usart::Baudrate) { self.[].write(|w| unsafe { w.bits(baudrate.ubrr) }); diff --git a/boards/arduino-diecimila/Cargo.toml b/boards/arduino-diecimila/Cargo.toml deleted file mode 100644 index d6f26c13f5..0000000000 --- a/boards/arduino-diecimila/Cargo.toml +++ /dev/null @@ -1,19 +0,0 @@ -[package] -name = "arduino-diecimila" -version = "0.1.0" -authors = ["Karl Thorén "] -edition = "2018" - -[features] -default = ["rt"] -rt = ["atmega168-hal/rt"] - -[dependencies] -atmega168-hal = { path = "../../chips/atmega168-hal/" } -avr-hal-generic = { path = "../../avr-hal-generic/" } - -[dev-dependencies] -panic-halt = "0.2.0" -nb = "0.1.2" -ufmt = "0.1.0" - diff --git a/boards/arduino-diecimila/examples/diecimila-blink.rs b/boards/arduino-diecimila/examples/diecimila-blink.rs deleted file mode 100644 index a368ad23c6..0000000000 --- a/boards/arduino-diecimila/examples/diecimila-blink.rs +++ /dev/null @@ -1,29 +0,0 @@ -#![no_std] -#![no_main] - -extern crate panic_halt; -use arduino_diecimila::prelude::*; - -#[arduino_diecimila::entry] -fn main() -> ! { - let dp = arduino_diecimila::Peripherals::take().unwrap(); - - let mut delay = arduino_diecimila::Delay::new(); - let mut pins = arduino_diecimila::Pins::new(dp.PORTB, dp.PORTC, dp.PORTD); - - // Digital pin 13 is also connected to an onboard LED marked "L" - let mut led = pins.d13.into_output(&mut pins.ddr); - - led.set_high().void_unwrap(); - - loop { - led.toggle().void_unwrap(); - delay.delay_ms(200u8); - led.toggle().void_unwrap(); - delay.delay_ms(200u8); - led.toggle().void_unwrap(); - delay.delay_ms(200u8); - led.toggle().void_unwrap(); - delay.delay_ms(200u8); - } -} diff --git a/boards/arduino-diecimila/examples/diecimila-panic.rs b/boards/arduino-diecimila/examples/diecimila-panic.rs deleted file mode 100644 index d4a997ab78..0000000000 --- a/boards/arduino-diecimila/examples/diecimila-panic.rs +++ /dev/null @@ -1,44 +0,0 @@ -#![no_std] -#![no_main] - -use arduino_diecimila::prelude::*; - -#[panic_handler] -fn panic(info: &core::panic::PanicInfo) -> ! { - let mut serial: arduino_diecimila::Serial = - unsafe { core::mem::MaybeUninit::uninit().assume_init() }; - - ufmt::uwriteln!(&mut serial, "Firmware panic!\r").void_unwrap(); - - if let Some(loc) = info.location() { - ufmt::uwriteln!( - &mut serial, - " At {}:{}:{}\r", - loc.file(), - loc.line(), - loc.column(), - ) - .void_unwrap(); - } - - loop {} -} - -#[arduino_diecimila::entry] -fn main() -> ! { - let dp = arduino_diecimila::Peripherals::take().unwrap(); - - let mut pins = arduino_diecimila::Pins::new(dp.PORTB, dp.PORTC, dp.PORTD); - - let mut serial = arduino_diecimila::Serial::new( - dp.USART0, - pins.d0, - pins.d1.into_output(&mut pins.ddr), - 57600.into_baudrate(), - ); - - ufmt::uwriteln!(&mut serial, "Hello from Arduino!\r").void_unwrap(); - // Panic messages cannot yet be captured because they rely on core::fmt - // which is way too big for AVR - panic!(); -} diff --git a/boards/arduino-diecimila/examples/diecimila-pwm.rs b/boards/arduino-diecimila/examples/diecimila-pwm.rs deleted file mode 100644 index f9006ba58e..0000000000 --- a/boards/arduino-diecimila/examples/diecimila-pwm.rs +++ /dev/null @@ -1,30 +0,0 @@ -#![no_std] -#![no_main] - -extern crate panic_halt; -use arduino_diecimila::prelude::*; - -#[arduino_diecimila::entry] -fn main() -> ! { - let dp = arduino_diecimila::Peripherals::take().unwrap(); - - let mut delay = arduino_diecimila::Delay::new(); - let mut pins = arduino_diecimila::Pins::new(dp.PORTB, dp.PORTC, dp.PORTD); - - // Timer 0 is connected to pin d6. - let mut timer0 = arduino_diecimila::pwm::Timer0Pwm::new(dp.TC0, arduino_diecimila::pwm::Prescaler::Prescale64); - - // Use pin d6 in PWM mode. - let mut led = pins.d6.into_output(&mut pins.ddr).into_pwm(&mut timer0); - - led.set_duty(128); - led.enable(); - - loop { - for i in 0..=255u16 { - let duty: u16 = i * i / 256; - led.set_duty(duty as u8); - delay.delay_ms(10u16); - } - } -} diff --git a/boards/arduino-diecimila/src/lib.rs b/boards/arduino-diecimila/src/lib.rs deleted file mode 100644 index f783a911d3..0000000000 --- a/boards/arduino-diecimila/src/lib.rs +++ /dev/null @@ -1,25 +0,0 @@ -#![no_std] - -// Expose hal & pac crates -pub use atmega168_hal as hal; -pub use crate::hal::pac; - -/// See [`avr_device::entry`](https://docs.rs/avr-device/latest/avr_device/attr.entry.html). -#[cfg(feature = "rt")] -pub use crate::hal::entry; - -mod pins; - -pub use crate::pac::Peripherals; -pub use crate::pins::*; -pub use crate::hal::adc; -pub mod prelude { - pub use crate::hal::prelude::*; - pub use crate::hal::usart::BaudrateArduinoExt as _; -} -pub use crate::hal::pwm; -pub use crate::hal::spi; - -pub type Delay = crate::hal::delay::Delay; -pub type Serial = crate::hal::usart::Usart0; -pub type I2cMaster = crate::hal::i2c::I2cMaster; diff --git a/boards/arduino-leonardo/Cargo.toml b/boards/arduino-leonardo/Cargo.toml deleted file mode 100644 index 041a1a2424..0000000000 --- a/boards/arduino-leonardo/Cargo.toml +++ /dev/null @@ -1,19 +0,0 @@ -[package] -name = "arduino-leonardo" -version = "0.1.0" -authors = ["Rahix "] -edition = "2018" - -[features] -default = ["rt"] -rt = ["atmega32u4-hal/rt"] - -[dependencies] -atmega32u4-hal = { path = "../../chips/atmega32u4-hal/" } -avr-hal-generic = { path = "../../avr-hal-generic/" } - -[dev-dependencies] -panic-halt = "0.2.0" -nb = "0.1.2" -ufmt = "0.1.0" -avr-device = "0.3" diff --git a/boards/arduino-leonardo/examples/leonardo-adc.rs b/boards/arduino-leonardo/examples/leonardo-adc.rs deleted file mode 100644 index d159da8ac9..0000000000 --- a/boards/arduino-leonardo/examples/leonardo-adc.rs +++ /dev/null @@ -1,59 +0,0 @@ -#![no_std] -#![no_main] - -use arduino_leonardo::adc; -use arduino_leonardo::prelude::*; -use panic_halt as _; - -#[arduino_leonardo::entry] -fn main() -> ! { - let dp = arduino_leonardo::Peripherals::take().unwrap(); - - let mut pins = arduino_leonardo::Pins::new(dp.PORTB, dp.PORTC, dp.PORTD, dp.PORTE, dp.PORTF); - - let mut serial = arduino_leonardo::Serial::new( - dp.USART1, - pins.d0, - pins.d1.into_output(&mut pins.ddr), - 57600.into_baudrate(), - ); - - ufmt::uwriteln!(&mut serial, "Reading analog inputs ...\r").void_unwrap(); - - let mut adc = adc::Adc::new(dp.ADC, Default::default()); - - let (vbg, gnd, temp): (u16, u16, u16) = ( - nb::block!(adc.read(&mut adc::channel::Vbg)).void_unwrap(), - nb::block!(adc.read(&mut adc::channel::Gnd)).void_unwrap(), - nb::block!(adc.read(&mut adc::channel::Temperature)).void_unwrap(), - ); - - ufmt::uwriteln!(&mut serial, "Vbandgap: {}\r", vbg).void_unwrap(); - ufmt::uwriteln!(&mut serial, "GND: {}\r", gnd).void_unwrap(); - ufmt::uwriteln!(&mut serial, "Temperature Sensor: {}\r", temp).void_unwrap(); - - let mut a0 = pins.a0.into_analog_input(&mut adc); - let mut a1 = pins.a1.into_analog_input(&mut adc); - let mut a2 = pins.a2.into_analog_input(&mut adc); - let mut a3 = pins.a3.into_analog_input(&mut adc); - let mut a4 = pins.a4.into_analog_input(&mut adc); - let mut a5 = pins.a5.into_analog_input(&mut adc); - - loop { - let values: [u16; 6] = [ - nb::block!(adc.read(&mut a0)).void_unwrap(), - nb::block!(adc.read(&mut a1)).void_unwrap(), - nb::block!(adc.read(&mut a2)).void_unwrap(), - nb::block!(adc.read(&mut a3)).void_unwrap(), - nb::block!(adc.read(&mut a4)).void_unwrap(), - nb::block!(adc.read(&mut a5)).void_unwrap(), - ]; - - for (i, v) in values.iter().enumerate() { - ufmt::uwrite!(&mut serial, "A{}: {} ", i, v).void_unwrap(); - } - ufmt::uwriteln!(&mut serial, "\r").void_unwrap(); - - arduino_leonardo::delay_ms(1000); - } -} diff --git a/boards/arduino-leonardo/examples/leonardo-blink.rs b/boards/arduino-leonardo/examples/leonardo-blink.rs deleted file mode 100644 index 41f1b813c0..0000000000 --- a/boards/arduino-leonardo/examples/leonardo-blink.rs +++ /dev/null @@ -1,30 +0,0 @@ -#![no_std] -#![no_main] - -use arduino_leonardo::prelude::*; -use panic_halt as _; - -#[arduino_leonardo::entry] -fn main() -> ! { - let dp = arduino_leonardo::Peripherals::take().unwrap(); - - let mut pins = arduino_leonardo::Pins::new(dp.PORTB, dp.PORTC, dp.PORTD, dp.PORTE, dp.PORTF); - - let mut led0 = pins.led_rx.into_output(&mut pins.ddr); - let mut led1 = pins.led_tx.into_output(&mut pins.ddr); - let mut led2 = pins.d13.into_output(&mut pins.ddr); - - led0.set_high().void_unwrap(); - led1.set_high().void_unwrap(); - led2.set_high().void_unwrap(); - - let mut leds = [led0.downgrade(), led1.downgrade(), led2.downgrade()]; - - loop { - for i in 0..3 { - leds[i].toggle().void_unwrap(); - leds[(i + 2) % 3].toggle().void_unwrap(); - arduino_leonardo::delay_ms(200); - } - } -} diff --git a/boards/arduino-leonardo/examples/leonardo-i2cdetect.rs b/boards/arduino-leonardo/examples/leonardo-i2cdetect.rs deleted file mode 100644 index 20ec170052..0000000000 --- a/boards/arduino-leonardo/examples/leonardo-i2cdetect.rs +++ /dev/null @@ -1,35 +0,0 @@ -#![no_std] -#![no_main] - -use arduino_leonardo::prelude::*; -use panic_halt as _; - -#[arduino_leonardo::entry] -fn main() -> ! { - let dp = arduino_leonardo::Peripherals::take().unwrap(); - - let mut pins = arduino_leonardo::Pins::new(dp.PORTB, dp.PORTC, dp.PORTD, dp.PORTE, dp.PORTF); - let mut serial = arduino_leonardo::Serial::new( - dp.USART1, - pins.d0, - pins.d1.into_output(&mut pins.ddr), - 57600.into_baudrate(), - ); - let mut i2c = arduino_leonardo::I2cMaster::new( - dp.TWI, - pins.d2.into_pull_up_input(&mut pins.ddr), - pins.d3.into_pull_up_input(&mut pins.ddr), - 50000, - ); - - ufmt::uwriteln!(&mut serial, "Write direction test:\r").void_unwrap(); - i2c.i2cdetect(&mut serial, arduino_leonardo::hal::i2c::Direction::Write) - .void_unwrap(); - ufmt::uwriteln!(&mut serial, "\r\nRead direction test:\r").void_unwrap(); - i2c.i2cdetect(&mut serial, arduino_leonardo::hal::i2c::Direction::Read) - .void_unwrap(); - - loop { - arduino_leonardo::delay_ms(1000); - } -} diff --git a/boards/arduino-leonardo/examples/leonardo-interrupt.rs b/boards/arduino-leonardo/examples/leonardo-interrupt.rs deleted file mode 100644 index 7a3da347f3..0000000000 --- a/boards/arduino-leonardo/examples/leonardo-interrupt.rs +++ /dev/null @@ -1,60 +0,0 @@ -#![no_std] -#![no_main] -#![feature(abi_avr_interrupt)] - -use arduino_leonardo::prelude::*; -use panic_halt as _; - -// This pin will be used from the interrupt handler -use arduino_leonardo::hal::port; -static mut PIN: Option> = None; - -#[arduino_leonardo::entry] -fn main() -> ! { - let dp = arduino_leonardo::Peripherals::take().unwrap(); - - let mut pins = arduino_leonardo::Pins::new(dp.PORTB, dp.PORTC, dp.PORTD, dp.PORTE, dp.PORTF); - - let mut led0 = pins.led_rx.into_output(&mut pins.ddr); - let mut led1 = pins.led_tx.into_output(&mut pins.ddr); - - let mut led = pins.d13.into_output(&mut pins.ddr); - - led0.set_high().void_unwrap(); - led1.set_low().void_unwrap(); - led.set_low().void_unwrap(); - - unsafe { - PIN = Some(led); - } - - // In theory this should not be necessary ... But if you previously had - // a sketch from Arduino loaded, the USB device will not have been reset. - // Because of this we will be spammed with interrupts which will never - // stop because they are never handled. - dp.USB_DEVICE.usbcon.reset(); - - // Initialize INT6 - // There is not yet a hal implementation, which is why we need to do this - // manually - let ei = dp.EXINT; - // TODO: Patch EXINT so we at least don't need manual values here - ei.eicrb.write(|w| w.isc6().bits(0x02)); - ei.eimsk.write(|w| w.int().bits(0x40)); - - // Enable interrupts - unsafe { - avr_device::interrupt::enable(); - } - - loop { - led0.toggle().void_unwrap(); - led1.toggle().void_unwrap(); - arduino_leonardo::delay_ms(300); - } -} - -#[avr_device::interrupt(atmega32u4)] -unsafe fn INT6() { - PIN.as_mut().unwrap().toggle().void_unwrap(); -} diff --git a/boards/arduino-leonardo/examples/leonardo-panic.rs b/boards/arduino-leonardo/examples/leonardo-panic.rs deleted file mode 100644 index 7d3792b610..0000000000 --- a/boards/arduino-leonardo/examples/leonardo-panic.rs +++ /dev/null @@ -1,45 +0,0 @@ -#![no_std] -#![no_main] - -use arduino_leonardo::hal::port::mode; -use arduino_leonardo::prelude::*; - -#[panic_handler] -fn panic(info: &core::panic::PanicInfo) -> ! { - let mut serial: arduino_leonardo::Serial = - unsafe { core::mem::MaybeUninit::uninit().assume_init() }; - - ufmt::uwriteln!(&mut serial, "Firmware panic!\r").void_unwrap(); - - if let Some(loc) = info.location() { - ufmt::uwriteln!( - &mut serial, - " At {}:{}:{}\r", - loc.file(), - loc.line(), - loc.column(), - ) - .void_unwrap(); - } - - loop {} -} - -#[arduino_leonardo::entry] -fn main() -> ! { - let dp = arduino_leonardo::Peripherals::take().unwrap(); - - let mut pins = arduino_leonardo::Pins::new(dp.PORTB, dp.PORTC, dp.PORTD, dp.PORTE, dp.PORTF); - - let mut serial = arduino_leonardo::Serial::new( - dp.USART1, - pins.d0, - pins.d1.into_output(&mut pins.ddr), - 57600.into_baudrate(), - ); - - ufmt::uwriteln!(&mut serial, "Hello from Arduino!\r").void_unwrap(); - // Panic messages cannot yet be captured because they rely on core::fmt - // which is way too big for AVR - panic!(); -} diff --git a/boards/arduino-leonardo/examples/leonardo-pwm.rs b/boards/arduino-leonardo/examples/leonardo-pwm.rs deleted file mode 100644 index 2f8474c0d5..0000000000 --- a/boards/arduino-leonardo/examples/leonardo-pwm.rs +++ /dev/null @@ -1,28 +0,0 @@ -#![no_std] -#![no_main] - -use arduino_leonardo::prelude::*; -use arduino_leonardo::pwm; -use panic_halt as _; - -#[arduino_leonardo::entry] -fn main() -> ! { - let dp = arduino_leonardo::Peripherals::take().unwrap(); - - let mut pins = arduino_leonardo::Pins::new(dp.PORTB, dp.PORTC, dp.PORTD, dp.PORTE, dp.PORTF); - - let mut timer4 = pwm::Timer4Pwm::new(dp.TC4, pwm::Prescaler::Prescale64); - - let mut led = pins.d13.into_output(&mut pins.ddr).into_pwm(&mut timer4); - - led.set_duty(128); - led.enable(); - - loop { - for i in 0..=255u16 { - let duty: u16 = i * i / 256; - led.set_duty(duty as u8); - arduino_leonardo::delay_ms(10); - } - } -} diff --git a/boards/arduino-leonardo/examples/leonardo-serial.rs b/boards/arduino-leonardo/examples/leonardo-serial.rs deleted file mode 100644 index aef1004391..0000000000 --- a/boards/arduino-leonardo/examples/leonardo-serial.rs +++ /dev/null @@ -1,29 +0,0 @@ -#![no_std] -#![no_main] - -use arduino_leonardo::prelude::*; -use panic_halt as _; - -#[arduino_leonardo::entry] -fn main() -> ! { - let dp = arduino_leonardo::Peripherals::take().unwrap(); - - let mut pins = arduino_leonardo::Pins::new(dp.PORTB, dp.PORTC, dp.PORTD, dp.PORTE, dp.PORTF); - - let mut serial = arduino_leonardo::Serial::new( - dp.USART1, - pins.d0, - pins.d1.into_output(&mut pins.ddr), - 57600.into_baudrate(), - ); - - 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(); - } -} diff --git a/boards/arduino-leonardo/examples/leonardo-spi-feedback.rs b/boards/arduino-leonardo/examples/leonardo-spi-feedback.rs deleted file mode 100644 index 6bd5c46ef2..0000000000 --- a/boards/arduino-leonardo/examples/leonardo-spi-feedback.rs +++ /dev/null @@ -1,50 +0,0 @@ -//! 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 ICSP pin 10 to ICSP pin 11. -//! -//! Once this program is written to the board, you can use the board's serial -//! connection to see the output. 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_leonardo::prelude::*; -use arduino_leonardo::spi; -use nb::block; -use panic_halt as _; - -#[arduino_leonardo::entry] -fn main() -> ! { - let dp = arduino_leonardo::Peripherals::take().unwrap(); - - let mut pins = arduino_leonardo::Pins::new(dp.PORTB, dp.PORTC, dp.PORTD, dp.PORTE, dp.PORTF); - - let mut serial = arduino_leonardo::Serial::new( - dp.USART1, - pins.d0, - pins.d1.into_output(&mut pins.ddr), - 57600.into_baudrate(), - ); - - // Create SPI interface. - let (mut spi, _) = spi::Spi::new( - dp.SPI, - pins.sck.into_output(&mut pins.ddr), - pins.mosi.into_output(&mut pins.ddr), - pins.miso.into_pull_up_input(&mut pins.ddr), - pins.led_rx.into_output(&mut pins.ddr), - spi::Settings::default(), - ); - - loop { - // Send a byte - block!(spi.send(0b00001111)).void_unwrap(); - // Because MISO is connected to MOSI, the read data should be the same - let data = block!(spi.read()).void_unwrap(); - - ufmt::uwriteln!(&mut serial, "data: {}\r", data).void_unwrap(); - arduino_leonardo::delay_ms(1000); - } -} diff --git a/boards/arduino-leonardo/examples/leonardo-watchdog.rs b/boards/arduino-leonardo/examples/leonardo-watchdog.rs deleted file mode 100644 index b353846ffc..0000000000 --- a/boards/arduino-leonardo/examples/leonardo-watchdog.rs +++ /dev/null @@ -1,24 +0,0 @@ -#![no_std] -#![no_main] - -use arduino_leonardo::prelude::*; -use arduino_leonardo::wdt; -use panic_halt as _; - -#[arduino_leonardo::entry] -fn main() -> ! { - let dp = arduino_leonardo::Peripherals::take().unwrap(); - - let mut pins = arduino_leonardo::Pins::new(dp.PORTB, dp.PORTC, dp.PORTD, dp.PORTE, dp.PORTF); - - let mut led = pins.d13.into_output(&mut pins.ddr); - - let mut watchdog = wdt::Wdt::new(&dp.CPU.mcusr, dp.WDT); - watchdog.start(wdt::Timeout::Ms2000); - - loop { - led.toggle().void_unwrap(); - arduino_leonardo::delay_ms(500); - watchdog.feed(); - } -} diff --git a/boards/arduino-leonardo/leonardo-runner.sh b/boards/arduino-leonardo/leonardo-runner.sh deleted file mode 100755 index 75efaef583..0000000000 --- a/boards/arduino-leonardo/leonardo-runner.sh +++ /dev/null @@ -1,60 +0,0 @@ -#!/usr/bin/env sh -set -e - -case "$(uname -s)" in - Linux*) OS="Linux";; - Darwin*) OS="Mac";; - *) OS="Unknown";; -esac - -if ! command -v numfmt > /dev/null 2>&1 -then - echo "numfmt is needed for human-readable sizes." >&2 - echo "please install https://command-not-found.com/numfmt" >&2 - alias numfmt=true -fi - -if ! command -v avrdude > /dev/null 2>&1 -then - echo "required avrdude could not be found!" >&2 - echo "please install https://command-not-found.com/avrdude" >&2 - exit 1 -fi - -if [ $OS = "Linux" ]; then - SERIAL_PORT="/dev/ttyACM0" -elif [ $OS = "Mac" ]; then - SERIAL_PORT="/dev/cu.usbmodem146201" -else - echo "unsupported OS, things might not work" >&2 - SERIAL_PORT="/dev/ttyACM0" -fi - -if [ "$1" = "--help" ] || [ "$1" = "-h" ]; then - echo "usage: $0 " >&2 - exit 1 -fi - -if [ "$#" -lt 1 ]; then - echo "$0: no ELF file given" >&2 - exit 1 -fi - -NAME="$(basename "$1")" -SIZE_TEXT="$(avr-size "$1" | tail -1 | cut -f1)" -SIZE_DATA="$(avr-size "$1" | tail -1 | cut -f2)" -SIZE_BSS="$(avr-size "$1" | tail -1 | cut -f3)" - -printf "\n" -printf "Program: %s\n" "$NAME" -printf "Size:\n" -printf " .text %s (exact: %d)\n" "$(numfmt --to=si --padding=9 "$SIZE_TEXT")" "$SIZE_TEXT" -printf " .data %s (exact: %d)\n" "$(numfmt --to=si --padding=9 "$SIZE_DATA")" "$SIZE_DATA" -printf " .bss %s (exact: %d)\n" "$(numfmt --to=si --padding=9 "$SIZE_BSS")" "$SIZE_BSS" -printf "\n" -printf "Please bring up the bootloader and press ENTER!\n" -read -r -printf "Attempting to flash ...\n" -printf "\n" - -avrdude -qq -patmega32u4 -cavr109 -P"${SERIAL_PORT}" -b57600 -D "-Uflash:w:$1:e" diff --git a/boards/arduino-leonardo/src/lib.rs b/boards/arduino-leonardo/src/lib.rs deleted file mode 100644 index 71abfe9dbd..0000000000 --- a/boards/arduino-leonardo/src/lib.rs +++ /dev/null @@ -1,244 +0,0 @@ -//! Board Support Crate for _Arduino Leonardo_. -//! -//! This crate provides abstractions for interfacing with the hardware of Arduino Leonardo. It -//! re-exports functionality from the underlying HAL in ways that make more sense for this -//! particular board. For example, the pins are named by what is printed on the PCB instead of the -//! MCU names. -//! -//! # Examples -//! A number of examples can be found in the [`examples/`][ex] subdirectory of this crate. -//! -//! [ex]: https://github.com/Rahix/avr-hal/tree/master/boards/arduino-leonardo/examples -//! -//! # Getting Started -//! Please follow the guide from [`avr-hal`'s README][guide] for steps on how to set up a project -//! with this board. A rough skeleton for an application looks like this: -//! -//! ```no_run -//! #![no_std] -//! #![no_main] -//! -//! // Pull in the panic handler from panic-halt -//! extern crate panic_halt; -//! -//! // The prelude just exports all HAL traits anonymously which makes -//! // all trait methods available. This is probably something that -//! // should always be added. -//! use arduino_leonardo::prelude::*; -//! -//! // Define the entry-point for the application. This can only be -//! // done once in the entire dependency tree. -//! #[arduino_leonardo::entry] -//! fn main() -> ! { -//! // Get the peripheral singletons for interacting with them. -//! let dp = arduino_leonardo::Peripherals::take().unwrap(); -//! -//! unimplemented!() -//! } -//! ``` -//! -//! [guide]: https://github.com/Rahix/avr-hal#starting-your-own-project - -#![no_std] - -// Expose hal & pac crates -pub use atmega32u4_hal as hal; -pub use crate::hal::pac; - -/// See [`avr_device::entry`](https://docs.rs/avr-device/latest/avr_device/attr.entry.html). -#[cfg(feature = "rt")] -pub use crate::hal::entry; - -pub use crate::pac::Peripherals; - -mod pins; -pub use crate::pins::*; - -pub mod prelude { - pub use crate::hal::prelude::*; - pub use crate::hal::usart::BaudrateExt as _; -} -pub use crate::hal::usart; - -/// Busy-Delay -/// -/// **Note**: For just delaying, using [`arduino_leonardo::delay_ms()`][delay_ms] or -/// [`arduino_leonardo::delay_us()`][delay_us] is probably the better choice. This type is more -/// useful when an `embedded-hal` driver needs a delay implementation. -/// -/// [delay_ms]: fn.delay_ms.html -/// [delay_us]: fn.delay_us.html -pub type Delay = hal::delay::Delay; - -/// Wait (busy spin) for `ms` milliseconds -pub fn delay_ms(ms: u16) { - use prelude::*; - - Delay::new().delay_ms(ms) -} - -/// Wait (busy spin) for `us` microseconds -pub fn delay_us(us: u16) { - use prelude::*; - - Delay::new().delay_us(us) -} - -/// Support for the Serial Peripheral Interface -/// -/// # Example -/// For a full example, see [`examples/leonardo-spi-feedback.rs`][ex-spi]. In short: -/// ```no_run -/// let dp = arduino_leonardo::Peripherals::take().unwrap(); -/// -/// let mut pins = arduino_leonardo::Pins::new(dp.PORTB, dp.PORTC, dp.PORTD, dp.PORTE); -/// -/// // Create SPI interface. -/// let mut spi = arduino_leonardo::spi::Spi::new( -/// dp.SPI, -/// pins.sck.into_output(&mut pins.ddr), -/// pins.mosi.into_output(&mut pins.ddr), -/// pins.miso.into_pull_up_input(&mut pins.ddr), -/// pins.led_rx.into_output(&mut pins.ddr), -/// arduino_leonardo::spi::Settings::default(), -/// ); -/// ``` -/// -/// [ex-spi]: https://github.com/Rahix/avr-hal/blob/master/boards/arduino-leonardo/examples/leonardo-spi-feedback.rs -pub mod spi { - pub use atmega32u4_hal::spi::*; -} - -/// Support for the Analog to Digital Converter -/// -/// # Example -/// For a full example, see [`examples/leonardo-adc.rs`][ex-adc]. In short: -/// ```no_run -/// let dp = arduino_leonardo::Peripherals::take().unwrap(); -/// -/// let mut pins = arduino_leonardo::Pins::new(dp.PORTB, dp.PORTC, dp.PORTD, dp.PORTE); -/// -/// let mut adc = arduino_leonardo::adc::Adc::new(dp.ADC, Default::default()); -/// -/// let v_bandgap: u16 = nb::block!( -/// adc.read(&mut arduino_leonardo::adc::channel::Vbg) -/// ).void_unwrap(), -/// -/// let portf = dp.PORTF.split(); -/// let mut a0 = portf.pf7.into_analog_input(&mut adc); -/// let mut a1 = portf.pf6.into_analog_input(&mut adc); -/// let mut a2 = portf.pf5.into_analog_input(&mut adc); -/// let mut a3 = portf.pf4.into_analog_input(&mut adc); -/// let mut a4 = portf.pf1.into_analog_input(&mut adc); -/// let mut a5 = portf.pf0.into_analog_input(&mut adc); -/// -/// let v: u16 = nb::block!(adc.read(&mut a0)).void_unwrap(), -/// ``` -/// -/// [ex-adc]: https://github.com/Rahix/avr-hal/blob/master/boards/arduino-leonardo/examples/leonardo-adc.rs -pub mod adc { - pub use atmega32u4_hal::adc::*; -} - -/// Support for PWM pins -/// -/// The 4 timers of ATmega32U4 can be used for PWM on certain pins. -/// The PWM methods are from `embedded_hal::PwmPin`. -/// -/// # Example -/// For a full example, see [`examples/leonardo-pwm.rs`][ex-pwm]. In short: -/// ``` -/// let mut pins = arduino_leonardo::Pins::new(dp.PORTB, dp.PORTC, dp.PORTD, dp.PORTE); -/// let mut timer1 = arduino_leonardo::pwm::Timer1Pwm::new( -/// dp.TC1, -/// arduino_leonardo::pwm::Prescaler::Prescale64, -/// ); -/// -/// let mut d3 = pins.d3.into_output(&mut pins.ddr).into_pwm(&mut timer0); -/// -/// d3.set_duty(128); -/// d3.enable(); -/// ``` -/// -/// [ex-pwm]: https://github.com/Rahix/avr-hal/blob/master/boards/arduino-leonardo/examples/leonardo-pwm.rs -/// -/// Here is an overview of pins and which timer they work with: -/// -/// | Pin | Conversion Method | Alternate Conversion Method | -/// | --- | --- | --- | -/// | `pins.d3` | `.into_pwm(&mut timer0)` | | -/// | `pins.d5` | `.into_pwm(&mut timer3)` | | -/// | `pins.d6` | `.into_pwm(&mut timer4)` | | -/// | `pins.d9` | `.into_pwm(&mut timer1)` | | -/// | `pins.d10` | `.into_pwm(&mut timer1)` | `.into_pwm4(&mut timer4)` | -/// | `pins.d11` | `.into_pwm(&mut timer0)` | `.into_pwm1(&mut timer1)` | -/// | `pins.d13` | `.into_pwm(&mut timer4)` | | -pub mod pwm { - pub use atmega32u4_hal::pwm::*; -} - -/// Serial (UART) interface on pins `D0` (RX) and `D1` (TX) -/// -/// # Example -/// For a full example, see [`examples/leonardo-serial.rs`][ex-serial]. In short: -/// ```no_run -/// let dp = arduino_leonardo::Peripherals::take().unwrap(); -/// -/// let mut pins = arduino_leonardo::Pins::new(dp.PORTB, dp.PORTC, dp.PORTD, dp.PORTE); -/// -/// let mut serial = arduino_leonardo::Serial::new( -/// dp.USART1, -/// pins.d0, -/// pins.d1.into_output(&mut pins.ddr), -/// 57600.into_baudrate(), -/// ); -/// -/// ufmt::uwriteln!(&mut serial, "Hello from Arduino!\r").void_unwrap(); -/// ``` -/// -/// [ex-serial]: https://github.com/Rahix/avr-hal/blob/master/boards/arduino-leonardo/examples/leonardo-serial.rs -pub type Serial = hal::usart::Usart1; - -/// I2C Master on pins `D2` (SDA) and `D3` (SCL) -/// -/// # Example -/// For a full example, see [`examples/leonardo-i2cdetect.rs`][ex-i2c]. In short: -/// ```no_run -/// let dp = arduino_leonardo::Peripherals::take().unwrap(); -/// -/// let mut pins = arduino_leonardo::Pins::new(dp.PORTB, dp.PORTC, dp.PORTD, dp.PORTE); -/// -/// let mut i2c = arduino_leonardo::I2cMaster::new( -/// dp.TWI, -/// pins.d2.into_pull_up_input(&mut pins.ddr), -/// pins.d3.into_pull_up_input(&mut pins.ddr), -/// 50000, -/// ); -/// ``` -/// -/// [ex-i2c]: https://github.com/Rahix/avr-hal/blob/master/boards/arduino-leonardo/examples/leonardo-i2cdetect.rs -pub type I2cMaster = hal::i2c::I2cMaster; -#[doc(hidden)] -#[deprecated = "Please use `I2cMaster` instead of `I2c`"] -pub type I2c = I2cMaster; - -/// Support for the Watchdog Timer -/// -/// # Note -/// Changing the watchdog configuration requires two separate writes to WDTCSR where the second -/// write must occur within 4 cycles of the first or the configuration will not change. You may need -/// to adjust optimization settings to prevent other operations from being emitted between these two -/// writes. -/// -/// # Example -/// ``` -/// let mut watchdog = arduino_leonardo::wdt::Wdt::new(&dp.CPU.mcusr, dp.WDT); -/// watchdog.start(arduino_leonardo::wdt::Timeout::Ms8000); -/// -/// loop { -/// watchdog.feed(); -/// } -/// ``` -pub mod wdt { - pub use atmega32u4_hal::wdt::*; -} diff --git a/boards/arduino-mega2560/.cargo/config.toml b/boards/arduino-mega2560/.cargo/config.toml deleted file mode 100644 index 0f2cde0270..0000000000 --- a/boards/arduino-mega2560/.cargo/config.toml +++ /dev/null @@ -1,5 +0,0 @@ -[build] -target = "../../avr-specs/avr-atmega2560.json" - -[unstable] -build-std = ["core"] diff --git a/boards/arduino-mega2560/Cargo.toml b/boards/arduino-mega2560/Cargo.toml deleted file mode 100644 index aea9e7f17d..0000000000 --- a/boards/arduino-mega2560/Cargo.toml +++ /dev/null @@ -1,18 +0,0 @@ -[package] -name = "arduino-mega2560" -version = "0.1.0" -authors = ["Andrew Dona-Couch "] -edition = "2018" - -[features] -default = ["rt"] -rt = ["atmega2560-hal/rt"] - -[dependencies] -atmega2560-hal = { path = "../../chips/atmega2560-hal/" } -avr-hal-generic = { path = "../../avr-hal-generic/" } - -[dev-dependencies] -panic-halt = "0.2.0" -nb = "0.1.2" -ufmt = "0.1.0" diff --git a/boards/arduino-mega2560/examples/mega2560-adc.rs b/boards/arduino-mega2560/examples/mega2560-adc.rs deleted file mode 100644 index 9b7df8d1cc..0000000000 --- a/boards/arduino-mega2560/examples/mega2560-adc.rs +++ /dev/null @@ -1,89 +0,0 @@ -#![no_std] -#![no_main] - -extern crate panic_halt; -use arduino_mega2560::prelude::*; - -#[arduino_mega2560::entry] -fn main() -> ! { - let dp = arduino_mega2560::Peripherals::take().unwrap(); - - let mut pins = arduino_mega2560::Pins::new( - dp.PORTA, - dp.PORTB, - dp.PORTC, - dp.PORTD, - dp.PORTE, - dp.PORTF, - dp.PORTG, - dp.PORTH, - dp.PORTJ, - dp.PORTK, - dp.PORTL, - ); - let mut delay = arduino_mega2560::Delay::new(); - - let mut serial = arduino_mega2560::Serial::new( - dp.USART0, - pins.d0, - pins.d1.into_output(&mut pins.ddr), - 57600.into_baudrate(), - ); - - ufmt::uwriteln!(&mut serial, "Reading analog inputs ...\r").void_unwrap(); - - let mut adc = arduino_mega2560::adc::Adc::new(dp.ADC, Default::default()); - - let (vbg, gnd): (u16, u16) = ( - nb::block!(adc.read(&mut arduino_mega2560::adc::channel::Vbg)).void_unwrap(), - nb::block!(adc.read(&mut arduino_mega2560::adc::channel::Gnd)).void_unwrap(), - ); - - ufmt::uwriteln!(&mut serial, "Vbandgap: {}\r", vbg).void_unwrap(); - ufmt::uwriteln!(&mut serial, "GND: {}\r", gnd).void_unwrap(); - - let mut a0 = pins.a0.into_analog_input(&mut adc); - let mut a1 = pins.a1.into_analog_input(&mut adc); - let mut a2 = pins.a2.into_analog_input(&mut adc); - let mut a3 = pins.a3.into_analog_input(&mut adc); - let mut a4 = pins.a4.into_analog_input(&mut adc); - let mut a5 = pins.a5.into_analog_input(&mut adc); - let mut a6 = pins.a6.into_analog_input(&mut adc); - let mut a7 = pins.a7.into_analog_input(&mut adc); - let mut a8 = pins.a8.into_analog_input(&mut adc); - let mut a9 = pins.a9.into_analog_input(&mut adc); - let mut a10 = pins.a10.into_analog_input(&mut adc); - let mut a11 = pins.a11.into_analog_input(&mut adc); - let mut a12 = pins.a12.into_analog_input(&mut adc); - let mut a13 = pins.a13.into_analog_input(&mut adc); - let mut a14 = pins.a14.into_analog_input(&mut adc); - let mut a15 = pins.a15.into_analog_input(&mut adc); - - loop { - let values: [u16; 16] = [ - nb::block!(adc.read(&mut a0)).void_unwrap(), - nb::block!(adc.read(&mut a1)).void_unwrap(), - nb::block!(adc.read(&mut a2)).void_unwrap(), - nb::block!(adc.read(&mut a3)).void_unwrap(), - nb::block!(adc.read(&mut a4)).void_unwrap(), - nb::block!(adc.read(&mut a5)).void_unwrap(), - nb::block!(adc.read(&mut a6)).void_unwrap(), - nb::block!(adc.read(&mut a7)).void_unwrap(), - nb::block!(adc.read(&mut a8)).void_unwrap(), - nb::block!(adc.read(&mut a9)).void_unwrap(), - nb::block!(adc.read(&mut a10)).void_unwrap(), - nb::block!(adc.read(&mut a11)).void_unwrap(), - nb::block!(adc.read(&mut a12)).void_unwrap(), - nb::block!(adc.read(&mut a13)).void_unwrap(), - nb::block!(adc.read(&mut a14)).void_unwrap(), - nb::block!(adc.read(&mut a15)).void_unwrap(), - ]; - - for (i, v) in values.iter().enumerate() { - ufmt::uwrite!(&mut serial, "A{}: {} ", i, v).void_unwrap(); - } - ufmt::uwriteln!(&mut serial, "\r").void_unwrap(); - - delay.delay_ms(1000u16); - } -} diff --git a/boards/arduino-mega2560/examples/mega2560-blink.rs b/boards/arduino-mega2560/examples/mega2560-blink.rs deleted file mode 100644 index 9aa3b3a971..0000000000 --- a/boards/arduino-mega2560/examples/mega2560-blink.rs +++ /dev/null @@ -1,32 +0,0 @@ -#![no_std] -#![no_main] - -extern crate panic_halt; -use arduino_mega2560::prelude::*; - -#[arduino_mega2560::entry] -fn main() -> ! { - let dp = arduino_mega2560::Peripherals::take().unwrap(); - - let mut delay = arduino_mega2560::Delay::new(); - let mut pins = arduino_mega2560::Pins::new( - dp.PORTA, - dp.PORTB, - dp.PORTC, - dp.PORTD, - dp.PORTE, - dp.PORTF, - dp.PORTG, - dp.PORTH, - dp.PORTJ, - dp.PORTK, - dp.PORTL, - ); - - let mut led = pins.d13.into_output(&mut pins.ddr); - - loop { - led.toggle().void_unwrap(); - delay.delay_ms(1000u16); - } -} diff --git a/boards/arduino-mega2560/examples/mega2560-i2cdetect.rs b/boards/arduino-mega2560/examples/mega2560-i2cdetect.rs deleted file mode 100644 index 3a1f214f18..0000000000 --- a/boards/arduino-mega2560/examples/mega2560-i2cdetect.rs +++ /dev/null @@ -1,37 +0,0 @@ -#![no_std] -#![no_main] - -extern crate panic_halt; -use arduino_mega2560::prelude::*; - -#[arduino_mega2560::entry] -fn main() -> ! { - let dp = arduino_mega2560::Peripherals::take().unwrap(); - - let mut delay = arduino_mega2560::Delay::new(); - - let mut porte = dp.PORTE.split(); - let mut portd = dp.PORTD.split(); - - let mut serial = arduino_mega2560::Serial::new( - dp.USART0, - porte.pe0, - porte.pe1.into_output(&mut porte.ddr), - 57600.into_baudrate(), - ); - let mut i2c = arduino_mega2560::I2cMaster::new( - dp.TWI, - portd.pd1.into_pull_up_input(&mut portd.ddr), - portd.pd0.into_pull_up_input(&mut portd.ddr), - 50000, - ); - - ufmt::uwriteln!(&mut serial, "Write direction test:\r").void_unwrap(); - i2c.i2cdetect(&mut serial, arduino_mega2560::hal::i2c::Direction::Write).void_unwrap(); - ufmt::uwriteln!(&mut serial, "\r\nRead direction test:\r").void_unwrap(); - i2c.i2cdetect(&mut serial, arduino_mega2560::hal::i2c::Direction::Read).void_unwrap(); - - loop { - delay.delay_ms(1000u16); - } -} diff --git a/boards/arduino-mega2560/examples/mega2560-panic.rs b/boards/arduino-mega2560/examples/mega2560-panic.rs deleted file mode 100644 index b1e8fc01fa..0000000000 --- a/boards/arduino-mega2560/examples/mega2560-panic.rs +++ /dev/null @@ -1,44 +0,0 @@ -#![no_std] -#![no_main] - -use arduino_mega2560::prelude::*; - -#[panic_handler] -fn panic(info: &core::panic::PanicInfo) -> ! { - let mut serial: arduino_mega2560::Serial = unsafe { - core::mem::MaybeUninit::uninit().assume_init() - }; - - ufmt::uwriteln!(&mut serial, "Firmware panic!\r").void_unwrap(); - - if let Some(loc) = info.location() { - ufmt::uwriteln!( - &mut serial, - " At {}:{}:{}\r", - loc.file(), - loc.line(), - loc.column(), - ).void_unwrap(); - } - - loop {} -} - -#[arduino_mega2560::entry] -fn main() -> ! { - let dp = arduino_mega2560::Peripherals::take().unwrap(); - - let mut porte = dp.PORTE.split(); - - let mut serial = arduino_mega2560::Serial::new( - dp.USART0, - porte.pe0, - porte.pe1.into_output(&mut porte.ddr), - 57600.into_baudrate(), - ); - - ufmt::uwriteln!(&mut serial, "Hello from MEGA2560!\r").void_unwrap(); - // Panic messages cannot yet be captured because they rely on core::fmt - // which is way too big for AVR - panic!(); -} diff --git a/boards/arduino-mega2560/examples/mega2560-pwm.rs b/boards/arduino-mega2560/examples/mega2560-pwm.rs deleted file mode 100644 index 47d12830dc..0000000000 --- a/boards/arduino-mega2560/examples/mega2560-pwm.rs +++ /dev/null @@ -1,41 +0,0 @@ -#![no_std] -#![no_main] - -extern crate panic_halt; -use arduino_mega2560::prelude::*; -use arduino_mega2560::pwm; - -#[arduino_mega2560::entry] -fn main() -> ! { - let dp = arduino_mega2560::Peripherals::take().unwrap(); - - let mut delay = arduino_mega2560::Delay::new(); - - let mut pins = arduino_mega2560::Pins::new( - dp.PORTA, - dp.PORTB, - dp.PORTC, - dp.PORTD, - dp.PORTE, - dp.PORTF, - dp.PORTG, - dp.PORTH, - dp.PORTJ, - dp.PORTK, - dp.PORTL, - ); - let mut timer0 = pwm::Timer0Pwm::new(dp.TC0, pwm::Prescaler::Prescale64); - - let mut pin = pins.d13.into_output(&mut pins.ddr).into_pwm(&mut timer0); - - pin.set_duty(128); - pin.enable(); - - loop { - for i in 0..=255_u16 { - let duty = i * i / 256; - pin.set_duty(duty as u8); - delay.delay_ms(10_u16); - } - } -} diff --git a/boards/arduino-mega2560/examples/mega2560-serial.rs b/boards/arduino-mega2560/examples/mega2560-serial.rs deleted file mode 100644 index 538f1ffe86..0000000000 --- a/boards/arduino-mega2560/examples/mega2560-serial.rs +++ /dev/null @@ -1,30 +0,0 @@ -#![no_std] -#![no_main] - -extern crate panic_halt; -use arduino_mega2560::prelude::*; - -#[arduino_mega2560::entry] -fn main() -> ! { - let dp = arduino_mega2560::Peripherals::take().unwrap(); - - let mut porte = dp.PORTE.split(); - let mut serial = arduino_mega2560::Serial::new( - dp.USART0, - porte.pe0, - porte.pe1.into_output(&mut porte.ddr), - 57600.into_baudrate(), - ); - - 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 - serial.write_str("You pressed ").void_unwrap(); - nb::block!(serial.write(b)).void_unwrap(); - serial.write_str("!\r\n").void_unwrap(); - } -} diff --git a/boards/arduino-mega2560/examples/mega2560-spi-feedback.rs b/boards/arduino-mega2560/examples/mega2560-spi-feedback.rs deleted file mode 100644 index 52cb9f697f..0000000000 --- a/boards/arduino-mega2560/examples/mega2560-spi-feedback.rs +++ /dev/null @@ -1,67 +0,0 @@ -//! 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 `~50` to pin `~51`. -//! -//! 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] - -extern crate panic_halt; -use arduino_mega2560::prelude::*; -use arduino_mega2560::spi::{Settings, Spi}; -use nb::block; - -#[arduino_mega2560::entry] -fn main() -> ! { - let dp = arduino_mega2560::Peripherals::take().unwrap(); - let mut delay = arduino_mega2560::Delay::new(); - let mut pins = arduino_mega2560::Pins::new( - dp.PORTA, - dp.PORTB, - dp.PORTC, - dp.PORTD, - dp.PORTE, - dp.PORTF, - dp.PORTG, - dp.PORTH, - dp.PORTJ, - dp.PORTK, - dp.PORTL, - ); - // set up serial interface for text output - let mut serial = arduino_mega2560::Serial::new( - dp.USART0, - pins.d0, - pins.d1.into_output(&mut pins.ddr), - 57600.into_baudrate(), - ); - - // Create SPI interface. - let (mut spi, _) = Spi::new( - dp.SPI, - pins.d52.into_output(&mut pins.ddr), - pins.d51.into_output(&mut pins.ddr), - pins.d50.into_pull_up_input(&mut pins.ddr), - pins.d53.into_output(&mut pins.ddr), - Settings::default(), - ); - - loop { - // Send a byte - block!(spi.send(0b00001111)).void_unwrap(); - // Because MISO is connected to MOSI, the read data should be the same - let data = block!(spi.read()).void_unwrap(); - - ufmt::uwriteln!(&mut serial, "data: {}\r", data).void_unwrap(); - delay.delay_ms(1000u16); - } -} diff --git a/boards/arduino-mega2560/src/lib.rs b/boards/arduino-mega2560/src/lib.rs deleted file mode 100644 index 5b8ada112d..0000000000 --- a/boards/arduino-mega2560/src/lib.rs +++ /dev/null @@ -1,86 +0,0 @@ -#![no_std] - -// Expose hal & pac crates -pub use atmega2560_hal as hal; -pub use crate::hal::pac; - -/// See [`avr_device::entry`](https://docs.rs/avr-device/latest/avr_device/attr.entry.html). -#[cfg(feature = "rt")] -pub use crate::hal::entry; - -pub use crate::pac::Peripherals; - -mod pins; -pub use crate::pins::*; - -pub mod prelude { - pub use crate::hal::prelude::*; - pub use crate::hal::usart::BaudrateExt as _; -} - -pub use crate::hal::spi; -pub use crate::hal::adc; - -pub type Delay = crate::hal::delay::Delay; -pub type Serial = crate::usart::Usart0; - -pub mod usart { - pub use avr_hal_generic::usart::*; - - pub type Usart0 = crate::hal::usart::Usart0; - pub type Usart1 = crate::hal::usart::Usart1; - pub type Usart2 = crate::hal::usart::Usart2; - pub type Usart3 = crate::hal::usart::Usart3; -} - -pub type I2cMaster = crate::hal::i2c::I2cMaster; -#[doc(hidden)] -#[deprecated = "Please use `I2cMaster` instead of `I2c`"] -pub type I2c = I2cMaster; - -/// Support for PWM pins -/// -/// The 6 timers of ATmega2560 can be used for PWM on certain pins. -/// The PWM methods are from `embedded_hal::PwmPin`. -/// -/// # Example -/// For a full example, see [`examples/mega2560-pwm.rs`][ex-pwm]. In short: -/// ``` -/// let mut pins = arduino_mega2560::Pins::new( -/// dp.PORTA, dp.PORTB, dp.PORTC, dp.PORTD, -/// dp.PORTE, dp.PORTF, dp.PORTG, dp.PORTH, -/// dp.PORTJ, dp.PORTK, dp.PORTL, -/// ); -/// -/// let mut timer0 = arduino_mega2560::pwm::Timer0Pwm::new( -/// dp.TC0, -/// arduino_mega2560::pwm::Prescaler::Prescale64, -/// ); -/// -/// let mut pin = pins.d13.into_output(&mut pins.ddr).into_pwm(&mut timer0); -/// -/// pin.set_duty(128); -/// pin.enable(); -/// ``` -/// -/// Here is an overview of pins and which timer they work with: -/// -/// | Pin | Conversion Method | Alternate Conversion Method | -/// | --- | --- | --- | -/// `pins.d2` | `.into_pwm(&mut timer3)` | | -/// `pins.d3` | `.into_pwm(&mut timer3)` | | -/// `pins.d4` | `.into_pwm(&mut timer0)` | | -/// `pins.d5` | `.into_pwm(&mut timer3)` | | -/// `pins.d6` | `.into_pwm(&mut timer4)` | | -/// `pins.d7` | `.into_pwm(&mut timer4)` | | -/// `pins.d8` | `.into_pwm(&mut timer4)` | | -/// `pins.d9` | `.into_pwm(&mut timer2)` | | -/// `pins.d10` | `.into_pwm(&mut timer2)` | | -/// `pins.d11` | `.into_pwm(&mut timer1)` | | -/// `pins.d12` | `.into_pwm(&mut timer1)` | | -/// `pins.d13` | `.into_pwm(&mut timer0)` | `.into_pwm1(&mut timer1)` | -/// -/// [ex-pwm]: https://github.com/sepotvin/avr-hal/blob/master/boards/arduino-mega2560/examples/mega2560-pwm.rs -pub mod pwm { - pub use crate::hal::pwm::*; -} diff --git a/boards/arduino-uno/Cargo.toml b/boards/arduino-uno/Cargo.toml deleted file mode 100644 index 9cdd8bd912..0000000000 --- a/boards/arduino-uno/Cargo.toml +++ /dev/null @@ -1,20 +0,0 @@ -[package] -name = "arduino-uno" -version = "0.1.0" -authors = ["Jonah Dahlquist "] -edition = "2018" - -[features] -default = ["rt"] -rt = ["atmega328p-hal/rt"] -arduino-nano = ["atmega328p-hal/adc-pins"] - -[dependencies] -atmega328p-hal = { path = "../../chips/atmega328p-hal/", features = ["atmega328p"] } -avr-hal-generic = { path = "../../avr-hal-generic/" } - -[dev-dependencies] -panic-halt = "0.2.0" -nb = "0.1.2" -ufmt = "0.1.0" -avr-device = "0.3" diff --git a/boards/arduino-uno/examples/uno-adc.rs b/boards/arduino-uno/examples/uno-adc.rs deleted file mode 100644 index 257626f1cf..0000000000 --- a/boards/arduino-uno/examples/uno-adc.rs +++ /dev/null @@ -1,77 +0,0 @@ -#![no_std] -#![no_main] - -use arduino_uno::adc; -use arduino_uno::prelude::*; -use panic_halt as _; - -// This example opens a serial connection to the host computer. On most POSIX operating systems -// (like GNU/Linux or OSX), you can interface with the program by running (assuming the device -// appears as ttyACM0) -// -// $ sudo screen /dev/ttyACM0 9600 - -#[arduino_uno::entry] -fn main() -> ! { - let dp = arduino_uno::Peripherals::take().unwrap(); - - let mut pins = arduino_uno::Pins::new(dp.PORTB, dp.PORTC, dp.PORTD); - - let mut serial = - arduino_uno::Serial::new(dp.USART0, pins.d0, pins.d1.into_output(&mut pins.ddr), 9600.into_baudrate()); - - let mut adc = adc::Adc::new(dp.ADC, Default::default()); - - let (vbg, gnd): (u16, u16) = ( - nb::block!(adc.read(&mut adc::channel::Vbg)).void_unwrap(), - nb::block!(adc.read(&mut adc::channel::Gnd)).void_unwrap(), - ); - - ufmt::uwriteln!(&mut serial, "Vbandgap: {}\r", vbg).void_unwrap(); - ufmt::uwriteln!(&mut serial, "GND: {}\r", gnd).void_unwrap(); - - let mut a0 = pins.a0.into_analog_input(&mut adc); - let mut a1 = pins.a1.into_analog_input(&mut adc); - let mut a2 = pins.a2.into_analog_input(&mut adc); - let mut a3 = pins.a3.into_analog_input(&mut adc); - let mut a4 = pins.a4.into_analog_input(&mut adc); - let mut a5 = pins.a5.into_analog_input(&mut adc); - - loop { - let values: [u16; 6] = [ - nb::block!(adc.read(&mut a0)).void_unwrap(), - nb::block!(adc.read(&mut a1)).void_unwrap(), - nb::block!(adc.read(&mut a2)).void_unwrap(), - nb::block!(adc.read(&mut a3)).void_unwrap(), - nb::block!(adc.read(&mut a4)).void_unwrap(), - nb::block!(adc.read(&mut a5)).void_unwrap(), - ]; - - for (i, v) in values.iter().enumerate() { - ufmt::uwrite!(&mut serial, "A{}: {} ", i, v).void_unwrap(); - } - - // Arduino Nano has two more ADC pins A6 and A7. Accessing them works a bit different from - // the other pins as they are not normal IO pins. The code below shows how it works. - // - // The `arduino-nano` feature of this crate needs to be enabled to make them available. - // You can build the example for Arduino Nano like this: - // - // cargo +nightly build --example uno-adc --features arduino-nano - // - // And run it with: - // - // cargo +nightly run --example uno-adc --features arduino-nano - #[cfg(feature = "arduino-nano")] - { - let adc6: u16 = nb::block!(adc.read(&mut adc::channel::ADC6)).void_unwrap(); - ufmt::uwrite!(&mut serial, "A6: {} ", adc6).void_unwrap(); - - let adc7: u16 = nb::block!(adc.read(&mut adc::channel::ADC7)).void_unwrap(); - ufmt::uwrite!(&mut serial, "A7: {} ", adc7).void_unwrap(); - } - - ufmt::uwriteln!(&mut serial, "\r").void_unwrap(); - arduino_uno::delay_ms(1000); - } -} diff --git a/boards/arduino-uno/examples/uno-blink.rs b/boards/arduino-uno/examples/uno-blink.rs deleted file mode 100644 index 13e9bc396d..0000000000 --- a/boards/arduino-uno/examples/uno-blink.rs +++ /dev/null @@ -1,28 +0,0 @@ -#![no_std] -#![no_main] - -use arduino_uno::prelude::*; -use panic_halt as _; - -#[arduino_uno::entry] -fn main() -> ! { - let dp = arduino_uno::Peripherals::take().unwrap(); - - let mut pins = arduino_uno::Pins::new(dp.PORTB, dp.PORTC, dp.PORTD); - - // Digital pin 13 is also connected to an onboard LED marked "L" - let mut led = pins.d13.into_output(&mut pins.ddr); - - led.set_high().void_unwrap(); - - loop { - led.toggle().void_unwrap(); - arduino_uno::delay_ms(200); - led.toggle().void_unwrap(); - arduino_uno::delay_ms(200); - led.toggle().void_unwrap(); - arduino_uno::delay_ms(200); - led.toggle().void_unwrap(); - arduino_uno::delay_ms(800); - } -} diff --git a/boards/arduino-uno/examples/uno-i2cdetect.rs b/boards/arduino-uno/examples/uno-i2cdetect.rs deleted file mode 100644 index 92129ddeb0..0000000000 --- a/boards/arduino-uno/examples/uno-i2cdetect.rs +++ /dev/null @@ -1,35 +0,0 @@ -#![no_std] -#![no_main] - -use arduino_uno::prelude::*; -use panic_halt as _; - -#[arduino_uno::entry] -fn main() -> ! { - let dp = arduino_uno::Peripherals::take().unwrap(); - - let mut pins = arduino_uno::Pins::new(dp.PORTB, dp.PORTC, dp.PORTD); - let mut serial = arduino_uno::Serial::new( - dp.USART0, - pins.d0, - pins.d1.into_output(&mut pins.ddr), - 57600.into_baudrate(), - ); - let mut i2c = arduino_uno::I2cMaster::new( - dp.TWI, - pins.a4.into_pull_up_input(&mut pins.ddr), - pins.a5.into_pull_up_input(&mut pins.ddr), - 50000, - ); - - ufmt::uwriteln!(&mut serial, "Write direction test:\r").void_unwrap(); - i2c.i2cdetect(&mut serial, arduino_uno::hal::i2c::Direction::Write) - .void_unwrap(); - ufmt::uwriteln!(&mut serial, "\r\nRead direction test:\r").void_unwrap(); - i2c.i2cdetect(&mut serial, arduino_uno::hal::i2c::Direction::Read) - .void_unwrap(); - - loop { - arduino_uno::delay_ms(1000); - } -} diff --git a/boards/arduino-uno/examples/uno-panic.rs b/boards/arduino-uno/examples/uno-panic.rs deleted file mode 100644 index 7d77097d9c..0000000000 --- a/boards/arduino-uno/examples/uno-panic.rs +++ /dev/null @@ -1,44 +0,0 @@ -#![no_std] -#![no_main] - -use arduino_uno::prelude::*; - -#[panic_handler] -fn panic(info: &core::panic::PanicInfo) -> ! { - let mut serial: arduino_uno::Serial = - unsafe { core::mem::MaybeUninit::uninit().assume_init() }; - - ufmt::uwriteln!(&mut serial, "Firmware panic!\r").void_unwrap(); - - if let Some(loc) = info.location() { - ufmt::uwriteln!( - &mut serial, - " At {}:{}:{}\r", - loc.file(), - loc.line(), - loc.column(), - ) - .void_unwrap(); - } - - loop {} -} - -#[arduino_uno::entry] -fn main() -> ! { - let dp = arduino_uno::Peripherals::take().unwrap(); - - let mut pins = arduino_uno::Pins::new(dp.PORTB, dp.PORTC, dp.PORTD); - - let mut serial = arduino_uno::Serial::new( - dp.USART0, - pins.d0, - pins.d1.into_output(&mut pins.ddr), - 57600.into_baudrate(), - ); - - ufmt::uwriteln!(&mut serial, "Hello from Arduino!\r").void_unwrap(); - // Panic messages cannot yet be captured because they rely on core::fmt - // which is way too big for AVR - panic!(); -} diff --git a/boards/arduino-uno/examples/uno-pwm.rs b/boards/arduino-uno/examples/uno-pwm.rs deleted file mode 100644 index f3b6ea2f68..0000000000 --- a/boards/arduino-uno/examples/uno-pwm.rs +++ /dev/null @@ -1,28 +0,0 @@ -#![no_std] -#![no_main] - -use arduino_uno::prelude::*; -use arduino_uno::pwm; -use panic_halt as _; - -#[arduino_uno::entry] -fn main() -> ! { - let dp = arduino_uno::Peripherals::take().unwrap(); - - let mut pins = arduino_uno::Pins::new(dp.PORTB, dp.PORTC, dp.PORTD); - - let mut timer1 = pwm::Timer1Pwm::new(dp.TC1, pwm::Prescaler::Prescale64); - - let mut pin = pins.d9.into_output(&mut pins.ddr).into_pwm(&mut timer1); - - pin.set_duty(128); - pin.enable(); - - loop { - for i in 0..=255u16 { - let duty: u16 = i * i / 256; - pin.set_duty(duty as u8); - arduino_uno::delay_ms(10); - } - } -} diff --git a/boards/arduino-uno/examples/uno-serial.rs b/boards/arduino-uno/examples/uno-serial.rs deleted file mode 100644 index 39e59cca19..0000000000 --- a/boards/arduino-uno/examples/uno-serial.rs +++ /dev/null @@ -1,34 +0,0 @@ -#![no_std] -#![no_main] - -use arduino_uno::prelude::*; -use panic_halt as _; - -// This example opens a serial connection to the host computer. On most POSIX operating systems (like GNU/Linux or -// OSX), you can interface with the program by running (assuming the device appears as ttyACM0) -// -// $ sudo screen /dev/ttyACM0 57600 - -#[arduino_uno::entry] -fn main() -> ! { - let dp = arduino_uno::Peripherals::take().unwrap(); - - let mut pins = arduino_uno::Pins::new(dp.PORTB, dp.PORTC, dp.PORTD); - - let mut serial = arduino_uno::Serial::new( - dp.USART0, - pins.d0, - pins.d1.into_output(&mut pins.ddr), - 57600.into_baudrate(), - ); - - 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(); - } -} diff --git a/boards/arduino-uno/examples/uno-watchdog.rs b/boards/arduino-uno/examples/uno-watchdog.rs deleted file mode 100644 index 3f4f645e60..0000000000 --- a/boards/arduino-uno/examples/uno-watchdog.rs +++ /dev/null @@ -1,18 +0,0 @@ -#![no_std] -#![no_main] - -use arduino_uno::prelude::*; -use arduino_uno::wdt; -use panic_halt as _; - -#[arduino_uno::entry] -fn main() -> ! { - let dp = arduino_uno::Peripherals::take().unwrap(); - - let mut watchdog = wdt::Wdt::new(&dp.CPU.mcusr, dp.WDT); - watchdog.start(wdt::Timeout::Ms8000); - - loop { - watchdog.feed(); - } -} diff --git a/boards/arduino-uno/src/lib.rs b/boards/arduino-uno/src/lib.rs deleted file mode 100644 index 8454e7af11..0000000000 --- a/boards/arduino-uno/src/lib.rs +++ /dev/null @@ -1,248 +0,0 @@ -//! Board Support Crate for [Arduino Uno] (and compatible boards; [see below](#compatible-boards)). -//! -//! This crate provides abstractions for interfacing with the hardware of Arduino Uno. It -//! re-exports functionality from the underlying HAL in ways that make more sense for this -//! particular board. For example, the pins are named by what is printed on the PCB instead of the -//! MCU names. -//! -//! # Examples -//! A number of examples can be found in the [`examples/`][ex] subdirectory of this crate. -//! -//! [ex]: https://github.com/Rahix/avr-hal/tree/master/boards/arduino-uno/examples -//! -//! # Getting Started -//! Please follow the guide from [`avr-hal`'s README][guide] for steps on how to set up a project -//! with this board. A rough skeleton for an application looks like this: -//! -//! ```no_run -//! #![no_std] -//! #![no_main] -//! -//! // Pull in the panic handler from panic-halt -//! extern crate panic_halt; -//! -//! // The prelude just exports all HAL traits anonymously which makes -//! // all trait methods available. This is probably something that -//! // should always be added. -//! use arduino_uno::prelude::*; -//! -//! // Define the entry-point for the application. This can only be -//! // done once in the entire dependency tree. -//! #[arduino_uno::entry] -//! fn main() -> ! { -//! // Get the peripheral singletons for interacting with them. -//! let dp = arduino_uno::Peripherals::take().unwrap(); -//! -//! unimplemented!() -//! } -//! ``` -//! -//! [guide]: https://github.com/Rahix/avr-hal#starting-your-own-project -//! -//! # Compatible Boards -//! This crate primarily targets [Arduino Uno] but is also compatible with a number of very similar -//! boards. Where there are differences, those can be enabled with a crate feature. Here is an -//! overview: -//! -//! | Feature | Board | Differences against Uno | -//! | --- | --- | --- | -//! | `arduino-nano` | [Arduino Nano] | Additional `ADC6` and `ADC7` pins/channels (see [`examples/uno-adc.rs`]) | -//! -//! [`examples/uno-adc.rs`]: https://github.com/Rahix/avr-hal/blob/master/boards/arduino-uno/examples/uno-adc.rs -//! -//! [Arduino Uno]: https://store.arduino.cc/usa/arduino-uno-rev3 -//! [Arduino Nano]: https://store.arduino.cc/arduino-nano - -#![no_std] - -// Expose hal & pac crates -pub use atmega328p_hal as hal; -pub use crate::hal::pac; - -/// See [`avr_device::entry`](https://docs.rs/avr-device/latest/avr_device/attr.entry.html). -#[cfg(feature = "rt")] -pub use crate::hal::entry; - -pub use crate::pac::Peripherals; - -mod pins; -pub use crate::pins::*; - -pub mod prelude { - pub use crate::hal::prelude::*; - pub use crate::hal::usart::BaudrateArduinoExt as _; -} - -/// Busy-Delay -/// -/// **Note**: For just delaying, using [`arduino_uno::delay_ms()`][delay_ms] or -/// [`arduino_uno::delay_us()`][delay_us] is probably the better choice. This type is more useful -/// when an `embedded-hal` driver needs a delay implementation. -/// -/// [delay_ms]: fn.delay_ms.html -/// [delay_us]: fn.delay_us.html -pub type Delay = hal::delay::Delay; - -/// Wait (busy spin) for `ms` milliseconds -pub fn delay_ms(ms: u16) { - use prelude::*; - - Delay::new().delay_ms(ms) -} - -/// Wait (busy spin) for `us` microseconds -pub fn delay_us(us: u16) { - use prelude::*; - - Delay::new().delay_us(us) -} - -/// Support for the Serial Peripheral Interface -/// -/// # Example -/// For a full example, see [`examples/uno-spi-feedback.rs`][ex-spi]. In short: -/// ```no_run -/// let dp = arduino_uno::Peripherals::take().unwrap(); -/// -/// let mut pins = arduino_uno::Pins::new(dp.PORTB, dp.PORTC, dp.PORTD); -/// -/// // Create SPI interface. -/// let (mut spi, mut cs) = arduino_uno::spi::Spi::new( -/// dp.SPI, -/// pins.d13.into_output(&mut pins.ddr), -/// pins.d11.into_output(&mut pins.ddr), -/// pins.d12.into_pull_up_input(&mut pins.ddr), -/// pins.d10.into_output(&mut pins.ddr), -/// arduino_uno::spi::Settings::default(), -/// ); -/// ``` -/// -/// [ex-spi]: https://github.com/Rahix/avr-hal/blob/master/boards/arduino-uno/examples/uno-spi-feedback.rs -pub mod spi { - pub use atmega328p_hal::spi::*; -} - -/// Support for the Analog to Digital Converter -/// -/// # Example -/// For a full example, see [`examples/uno-adc.rs`][ex-adc]. In short: -/// ```no_run -/// let dp = arduino_uno::Peripherals::take().unwrap(); -/// -/// let mut pins = arduino_uno::Pins::new(dp.PORTB, dp.PORTC, dp.PORTD); -/// -/// let mut adc = arduino_uno::adc::Adc::new(dp.ADC, arduino_uno::adc::AdcSettings::default()); -/// -/// // Convert pin to Analog input -/// let mut a0 = pins.a0.into_analog_input(&mut adc); -/// -/// let aread: u16 = nb::block!{adc.read(&mut a0)}.void_unwrap(); -/// ``` -/// -/// [ex-adc]: https://github.com/Rahix/avr-hal/blob/master/boards/arduino-uno/examples/uno-adc.rs -pub mod adc { - pub use atmega328p_hal::adc::*; -} - -/// Support for PWM pins -/// -/// The 3 timers of ATmega328P can be used for PWM on certain pins. -/// The PWM methods are from `embedded_hal::PwmPin`. -/// -/// # Example -/// For a full example, see [`examples/uno-pwm.rs`][ex-pwm]. In short: -/// ``` -/// let mut pins = arduino_uno::Pins::new(dp.PORTB, dp.PORTC, dp.PORTD); -/// -/// let mut timer1 = arduino_uno::pwm::Timer1Pwm::new( -/// dp.TC1, -/// arduino_uno::pwm::Prescaler::Prescale64, -/// ); -/// -/// let mut pin = pins.d9.into_output(&mut pins.ddr).into_pwm(&mut timer1); -/// -/// pin.set_duty(128); -/// pin.enable(); -/// ``` -/// -/// Here is an overview of pins and which timer they work with: -/// -/// | Pin | Conversion Method | -/// | --- | --- | -/// | `pins.d3` | `.into_pwm(&mut timer2)` | -/// | `pins.d5` | `.into_pwm(&mut timer0)` | -/// | `pins.d6` | `.into_pwm(&mut timer0)` | -/// | `pins.d9` | `.into_pwm(&mut timer1)` | -/// | `pins.d10` | `.into_pwm(&mut timer1)` | -/// | `pins.d11` | `.into_pwm(&mut timer2)` | -/// -/// [ex-pwm]: https://github.com/Rahix/avr-hal/blob/master/boards/arduino-uno/examples/uno-pwm.rs -pub mod pwm { - pub use atmega328p_hal::pwm::*; -} - -/// Serial (UART) interface on pins `D0` (RX) and `D1` (TX) -/// -/// # Example -/// For a full example, see [`examples/leonardo-serial.rs`][ex-serial]. In short: -/// ```no_run -/// let dp = arduino_uno::Peripherals::take().unwrap(); -/// -/// let mut pins = arduino_uno::Pins::new(dp.PORTB, dp.PORTC, dp.PORTD); -/// -/// let mut serial = arduino_uno::Serial::new( -/// dp.USART0, -/// pins.d0, -/// pins.d1.into_output(&mut pins.ddr), -/// 57600.into_baudrate(), -/// ); -/// -/// ufmt::uwriteln!(&mut serial, "Hello from Arduino!\r").void_unwrap(); -/// ``` -/// -/// [ex-serial]: https://github.com/Rahix/avr-hal/blob/master/boards/arduino-uno/examples/uno-serial.rs -pub type Serial = hal::usart::Usart0; - -/// I2C Master on pins `A4` (SDA) and `A5` (SCL) -/// -/// # Example -/// For a full example, see [`examples/leonardo-i2cdetect.rs`][ex-i2c]. In short: -/// ```no_run -/// let dp = arduino_uno::Peripherals::take().unwrap(); -/// -/// let mut pins = arduino_uno::Pins::new(dp.PORTB, dp.PORTC, dp.PORTD); -/// -/// let mut i2c = arduino_uno::I2cMaster::new( -/// dp.TWI, -/// pins.a4.into_pull_up_input(&mut pins.ddr), -/// pins.a5.into_pull_up_input(&mut pins.ddr), -/// 50000, -/// ); -/// ``` -/// -/// [ex-i2c]: https://github.com/Rahix/avr-hal/blob/master/boards/arduino-uno/examples/uno-i2cdetect.rs -pub type I2cMaster = hal::i2c::I2cMaster; -#[doc(hidden)] -#[deprecated = "Please use `I2cMaster` instead of `I2c`"] -pub type I2c = I2cMaster; - -/// Support for the WatchDog Timer -/// -/// # Note -/// Changing the watchdog configuration requires two separate writes to WDTCSR where the second -/// write must occur within 4 cycles of the first or the configuration will not change. You may need -/// to adjust optimization settings to prevent other operations from being emitted between these two -/// writes. -/// -/// # Example -/// ``` -/// let mut watchdog = arduino_uno::wdt::Wdt::new(&dp.CPU.mcusr, dp.WDT); -/// watchdog.start(arduino_uno::wdt::Timeout::Ms8000); -/// -/// loop { -/// watchdog.feed(); -/// } -/// ``` -pub mod wdt { - pub use atmega328p_hal::wdt::*; -} diff --git a/boards/arduino-uno/uno-runner.sh b/boards/arduino-uno/uno-runner.sh deleted file mode 100755 index 066a598f17..0000000000 --- a/boards/arduino-uno/uno-runner.sh +++ /dev/null @@ -1,58 +0,0 @@ -#!/usr/bin/env sh -set -e - -case "$(uname -s)" in - Linux*) OS="Linux";; - Darwin*) OS="Mac";; - *) OS="Unknown";; -esac - -if ! command -v numfmt > /dev/null 2>&1 -then - echo "numfmt is needed for human-readable sizes." >&2 - echo "please install https://command-not-found.com/numfmt" >&2 - alias numfmt=true -fi - -if ! command -v avrdude > /dev/null 2>&1 -then - echo "required avrdude could not be found!" >&2 - echo "please install https://command-not-found.com/avrdude" >&2 - exit 1 -fi - -if [ $OS = "Linux" ]; then - SERIAL_PORT="/dev/ttyACM0" -elif [ $OS = "Mac" ]; then - SERIAL_PORT="/dev/cu.usbmodem146201" -else - echo "unsupported OS, things might not work" >&2 - SERIAL_PORT="/dev/ttyACM0" -fi - -if [ "$1" = "--help" ] || [ "$1" = "-h" ]; then - echo "usage: $0 " >&2 - exit 1 -fi - -if [ "$#" -lt 1 ]; then - echo "$0: no ELF file given" >&2 - exit 1 -fi - -NAME="$(basename "$1")" -SIZE_TEXT="$(avr-size "$1" | tail -1 | cut -f1)" -SIZE_DATA="$(avr-size "$1" | tail -1 | cut -f2)" -SIZE_BSS="$(avr-size "$1" | tail -1 | cut -f3)" - -printf "\n" -printf "Program: %s\n" "$NAME" -printf "Size:\n" -printf " .text %s (exact: %d)\n" "$(numfmt --to=si --padding=9 "$SIZE_TEXT")" "$SIZE_TEXT" -printf " .data %s (exact: %d)\n" "$(numfmt --to=si --padding=9 "$SIZE_DATA")" "$SIZE_DATA" -printf " .bss %s (exact: %d)\n" "$(numfmt --to=si --padding=9 "$SIZE_BSS")" "$SIZE_BSS" -printf "\n" -printf "Attempting to flash ...\n" -printf "\n" - -avrdude -q -patmega328p -carduino -P"${SERIAL_PORT}" -D "-Uflash:w:$1:e" diff --git a/boards/bigavr6/.cargo/config.toml b/boards/bigavr6/.cargo/config.toml deleted file mode 100644 index 7b7798dad7..0000000000 --- a/boards/bigavr6/.cargo/config.toml +++ /dev/null @@ -1,5 +0,0 @@ -[build] -target = "../../avr-specs/avr-atmega1280.json" - -[unstable] -build-std = ["core"] diff --git a/boards/bigavr6/Cargo.toml b/boards/bigavr6/Cargo.toml deleted file mode 100644 index d6d623b683..0000000000 --- a/boards/bigavr6/Cargo.toml +++ /dev/null @@ -1,18 +0,0 @@ -[package] -name = "bigavr6" -version = "0.1.0" -authors = ["Gabriel Pickl "] -edition = "2018" - -[features] -default = ["rt"] -rt = ["atmega1280-hal/rt"] - -[dependencies] -atmega1280-hal = { path = "../../chips/atmega1280-hal/" } -avr-hal-generic = { path = "../../avr-hal-generic/" } - -[dev-dependencies] -panic-halt = "0.2.0" -nb = "0.1.2" -ufmt = "0.1.0" diff --git a/boards/bigavr6/examples/bigavr6-blink.rs b/boards/bigavr6/examples/bigavr6-blink.rs deleted file mode 100644 index 9080f041b3..0000000000 --- a/boards/bigavr6/examples/bigavr6-blink.rs +++ /dev/null @@ -1,19 +0,0 @@ -#![no_std] -#![no_main] - -extern crate panic_halt; -use bigavr6::prelude::*; - -#[bigavr6::entry] -fn main() -> ! { - let dp = bigavr6::Peripherals::take().unwrap(); - - let mut delay = bigavr6::Delay::new(); - let mut porta = dp.PORTA.split(); - let mut led = porta.pa0.into_output(&mut porta.ddr); - - loop { - led.toggle().void_unwrap(); - delay.delay_ms(500u16); - } -} diff --git a/boards/bigavr6/examples/bigavr6-i2cdetect.rs b/boards/bigavr6/examples/bigavr6-i2cdetect.rs deleted file mode 100644 index 1c54b78da1..0000000000 --- a/boards/bigavr6/examples/bigavr6-i2cdetect.rs +++ /dev/null @@ -1,37 +0,0 @@ -#![no_std] -#![no_main] - -extern crate panic_halt; -use bigavr6::prelude::*; - -#[bigavr6::entry] -fn main() -> ! { - let dp = bigavr6::Peripherals::take().unwrap(); - - let mut delay = bigavr6::Delay::new(); - - let mut porte = dp.PORTE.split(); - let mut portd = dp.PORTD.split(); - - let mut serial = bigavr6::Serial::new( - dp.USART0, - porte.pe0, - porte.pe1.into_output(&mut porte.ddr), - 57600.into_baudrate(), - ); - let mut i2c = bigavr6::I2cMaster::new( - dp.TWI, - portd.pd1.into_pull_up_input(&mut portd.ddr), - portd.pd0.into_pull_up_input(&mut portd.ddr), - 50000, - ); - - ufmt::uwriteln!(&mut serial, "Write direction test:\r").void_unwrap(); - i2c.i2cdetect(&mut serial, bigavr6::hal::i2c::Direction::Write).void_unwrap(); - ufmt::uwriteln!(&mut serial, "\r\nRead direction test:\r").void_unwrap(); - i2c.i2cdetect(&mut serial, bigavr6::hal::i2c::Direction::Read).void_unwrap(); - - loop { - delay.delay_ms(1000 as u16); - } -} diff --git a/boards/bigavr6/examples/bigavr6-panic.rs b/boards/bigavr6/examples/bigavr6-panic.rs deleted file mode 100644 index d67f276fcf..0000000000 --- a/boards/bigavr6/examples/bigavr6-panic.rs +++ /dev/null @@ -1,44 +0,0 @@ -#![no_std] -#![no_main] - -use bigavr6::prelude::*; - -#[panic_handler] -fn panic(info: &core::panic::PanicInfo) -> ! { - let mut serial: bigavr6::Serial = unsafe { - core::mem::MaybeUninit::uninit().assume_init() - }; - - ufmt::uwriteln!(&mut serial, "Firmware panic!\r").void_unwrap(); - - if let Some(loc) = info.location() { - ufmt::uwriteln!( - &mut serial, - " At {}:{}:{}\r", - loc.file(), - loc.line(), - loc.column(), - ).void_unwrap(); - } - - loop {} -} - -#[bigavr6::entry] -fn main() -> ! { - let dp = bigavr6::Peripherals::take().unwrap(); - - let mut porte = dp.PORTE.split(); - - let mut serial = bigavr6::Serial::new( - dp.USART0, - porte.pe0, - porte.pe1.into_output(&mut porte.ddr), - 57600.into_baudrate(), - ); - - ufmt::uwriteln!(&mut serial, "Hello from BIGAVR6!\r").void_unwrap(); - // Panic messages cannot yet be captured because they rely on core::fmt - // which is way too big for AVR - panic!(); -} diff --git a/boards/bigavr6/examples/bigavr6-serial.rs b/boards/bigavr6/examples/bigavr6-serial.rs deleted file mode 100644 index 3ad6631de9..0000000000 --- a/boards/bigavr6/examples/bigavr6-serial.rs +++ /dev/null @@ -1,32 +0,0 @@ -#![no_std] -#![no_main] - -extern crate panic_halt; -use bigavr6::prelude::*; - -#[bigavr6::entry] -fn main() -> ! { - let dp = bigavr6::Peripherals::take().unwrap(); - - let mut porte = dp.PORTE.split(); - let mut serial = bigavr6::Serial::new( - dp.USART0, - porte.pe0, - porte.pe1.into_output(&mut porte.ddr), - 57600.into_baudrate(), - ); - - // The following would also work, but needs +600% more bytes - // writeln!(serial, "Hello from Arduino!\r").unwrap(); - serial.write_str("Hello from BIGAVR6!\r\n").void_unwrap(); - - loop { - // Read a byte from the serial connection - let b = nb::block!(serial.read()).void_unwrap(); - - // Answer - serial.write_str("You pressed ").void_unwrap(); - nb::block!(serial.write(b)).void_unwrap(); - serial.write_str("!\r\n").void_unwrap(); - } -} diff --git a/boards/bigavr6/src/lib.rs b/boards/bigavr6/src/lib.rs deleted file mode 100644 index 2c688eb0f4..0000000000 --- a/boards/bigavr6/src/lib.rs +++ /dev/null @@ -1,22 +0,0 @@ -#![no_std] - -// Expose hal & pac crates -pub use atmega1280_hal as hal; -pub use crate::hal::pac; - -/// See [`avr_device::entry`](https://docs.rs/avr-device/latest/avr_device/attr.entry.html). -#[cfg(feature = "rt")] -pub use crate::hal::entry; - -pub use crate::pac::Peripherals; -pub mod prelude { - pub use crate::hal::prelude::*; - pub use crate::hal::usart::BaudrateExt as _; -} - -pub type Delay = crate::hal::delay::Delay; -pub type Serial = crate::hal::usart::Usart0; -pub type I2cMaster = crate::hal::i2c::I2cMaster; -#[doc(hidden)] -#[deprecated = "Please use `I2cMaster` instead of `I2c`"] -pub type I2c = I2cMaster; diff --git a/boards/sparkfun-pro-micro/Cargo.toml b/boards/sparkfun-pro-micro/Cargo.toml deleted file mode 100644 index 628077cee3..0000000000 --- a/boards/sparkfun-pro-micro/Cargo.toml +++ /dev/null @@ -1,19 +0,0 @@ -[package] -name = "sparkfun-pro-micro" -version = "0.1.0" -authors = ["Cecile Tonglet "] -edition = "2018" - -[features] -default = ["rt"] -rt = ["atmega32u4-hal/rt"] - -[dependencies] -atmega32u4-hal = { path = "../../chips/atmega32u4-hal/" } -avr-hal-generic = { path = "../../avr-hal-generic/" } - -[dev-dependencies] -panic-halt = "0.2.0" -nb = "0.1.2" -ufmt = "0.1.0" -avr-device = "0.3" diff --git a/boards/sparkfun-pro-micro/examples/pro-micro-adc.rs b/boards/sparkfun-pro-micro/examples/pro-micro-adc.rs deleted file mode 100644 index f278aaca92..0000000000 --- a/boards/sparkfun-pro-micro/examples/pro-micro-adc.rs +++ /dev/null @@ -1,59 +0,0 @@ -#![no_std] -#![no_main] - -use sparkfun_pro_micro::adc; -use sparkfun_pro_micro::prelude::*; -use panic_halt as _; - -#[sparkfun_pro_micro::entry] -fn main() -> ! { - let dp = sparkfun_pro_micro::Peripherals::take().unwrap(); - - let mut pins = sparkfun_pro_micro::Pins::new(dp.PORTB, dp.PORTC, dp.PORTD, dp.PORTE, dp.PORTF); - - let mut serial = sparkfun_pro_micro::Serial::new( - dp.USART1, - pins.d0, - pins.d1.into_output(&mut pins.ddr), - 57600.into_baudrate(), - ); - - ufmt::uwriteln!(&mut serial, "Reading analog inputs ...\r").void_unwrap(); - - let mut adc = adc::Adc::new(dp.ADC, Default::default()); - - let (vbg, gnd, temp): (u16, u16, u16) = ( - nb::block!(adc.read(&mut sparkfun_pro_micro::adc::channel::Vbg)).void_unwrap(), - nb::block!(adc.read(&mut sparkfun_pro_micro::adc::channel::Gnd)).void_unwrap(), - nb::block!(adc.read(&mut sparkfun_pro_micro::adc::channel::Temperature)).void_unwrap(), - ); - - ufmt::uwriteln!(&mut serial, "Vbandgap: {}\r", vbg).void_unwrap(); - ufmt::uwriteln!(&mut serial, "GND: {}\r", gnd).void_unwrap(); - ufmt::uwriteln!(&mut serial, "Temperature Sensor: {}\r", temp).void_unwrap(); - - let mut a0 = pins.a0.into_analog_input(&mut adc); - let mut a1 = pins.a1.into_analog_input(&mut adc); - let mut a2 = pins.a2.into_analog_input(&mut adc); - let mut a3 = pins.a3.into_analog_input(&mut adc); - let mut d4 = pins.d4.into_analog_input(&mut adc); - let mut d8 = pins.d8.into_analog_input(&mut adc); - - loop { - let values: [u16; 6] = [ - nb::block!(adc.read(&mut a0)).void_unwrap(), - nb::block!(adc.read(&mut a1)).void_unwrap(), - nb::block!(adc.read(&mut a2)).void_unwrap(), - nb::block!(adc.read(&mut a3)).void_unwrap(), - nb::block!(adc.read(&mut d4)).void_unwrap(), - nb::block!(adc.read(&mut d8)).void_unwrap(), - ]; - - for (i, v) in values.iter().enumerate() { - ufmt::uwrite!(&mut serial, "A{}: {} ", i, v).void_unwrap(); - } - ufmt::uwriteln!(&mut serial, "\r").void_unwrap(); - - sparkfun_pro_micro::delay_ms(1000); - } -} diff --git a/boards/sparkfun-pro-micro/examples/pro-micro-blink.rs b/boards/sparkfun-pro-micro/examples/pro-micro-blink.rs deleted file mode 100644 index a77c539ffa..0000000000 --- a/boards/sparkfun-pro-micro/examples/pro-micro-blink.rs +++ /dev/null @@ -1,36 +0,0 @@ -#![no_std] -#![no_main] - -extern crate panic_halt; -use sparkfun_pro_micro::prelude::*; - -#[sparkfun_pro_micro::entry] -fn main() -> ! { - let dp = sparkfun_pro_micro::Peripherals::take().unwrap(); - - let mut pins = sparkfun_pro_micro::Pins::new(dp.PORTB, dp.PORTC, dp.PORTD, dp.PORTE, dp.PORTF); - - let mut led0 = pins.led_rx.into_output(&mut pins.ddr); - let mut led1 = pins.led_tx.into_output(&mut pins.ddr); - - led0.set_high().void_unwrap(); - led1.set_high().void_unwrap(); - - let mut time: u16 = 0; - loop { - if time % 2 == 0 { - led0.set_low().void_unwrap(); - } else { - led0.set_high().void_unwrap(); - } - - if time % 3 == 0 { - led1.set_low().void_unwrap(); - } else { - led1.set_high().void_unwrap(); - } - - sparkfun_pro_micro::delay_ms(500); - time = time.wrapping_add(1); - } -} diff --git a/boards/sparkfun-pro-micro/examples/pro-micro-i2cdetect.rs b/boards/sparkfun-pro-micro/examples/pro-micro-i2cdetect.rs deleted file mode 100644 index 64f1266be5..0000000000 --- a/boards/sparkfun-pro-micro/examples/pro-micro-i2cdetect.rs +++ /dev/null @@ -1,35 +0,0 @@ -#![no_std] -#![no_main] - -extern crate panic_halt; -use sparkfun_pro_micro::prelude::*; - -#[sparkfun_pro_micro::entry] -fn main() -> ! { - let dp = sparkfun_pro_micro::Peripherals::take().unwrap(); - - let mut pins = sparkfun_pro_micro::Pins::new(dp.PORTB, dp.PORTC, dp.PORTD, dp.PORTE, dp.PORTF); - let mut serial = sparkfun_pro_micro::Serial::new( - dp.USART1, - pins.d0, - pins.d1.into_output(&mut pins.ddr), - 57600.into_baudrate(), - ); - let mut i2c = sparkfun_pro_micro::I2cMaster::new( - dp.TWI, - pins.d2.into_pull_up_input(&mut pins.ddr), - pins.d3.into_pull_up_input(&mut pins.ddr), - 50000, - ); - - ufmt::uwriteln!(&mut serial, "Write direction test:\r").void_unwrap(); - i2c.i2cdetect(&mut serial, sparkfun_pro_micro::hal::i2c::Direction::Write) - .void_unwrap(); - ufmt::uwriteln!(&mut serial, "\r\nRead direction test:\r").void_unwrap(); - i2c.i2cdetect(&mut serial, sparkfun_pro_micro::hal::i2c::Direction::Read) - .void_unwrap(); - - loop { - sparkfun_pro_micro::delay_ms(1000); - } -} diff --git a/boards/sparkfun-pro-micro/examples/pro-micro-interrupt.rs b/boards/sparkfun-pro-micro/examples/pro-micro-interrupt.rs deleted file mode 100644 index e13e4916c8..0000000000 --- a/boards/sparkfun-pro-micro/examples/pro-micro-interrupt.rs +++ /dev/null @@ -1,60 +0,0 @@ -#![no_std] -#![no_main] -#![feature(abi_avr_interrupt)] - -extern crate panic_halt; -use sparkfun_pro_micro::prelude::*; - -// This pin will be used from the interrupt handler -use sparkfun_pro_micro::hal::port; -static mut PIN: Option> = None; - -#[sparkfun_pro_micro::entry] -fn main() -> ! { - let dp = sparkfun_pro_micro::Peripherals::take().unwrap(); - - let mut pins = sparkfun_pro_micro::Pins::new(dp.PORTB, dp.PORTC, dp.PORTD, dp.PORTE, dp.PORTF); - - let mut led0 = pins.led_rx.into_output(&mut pins.ddr); - let mut led1 = pins.led_tx.into_output(&mut pins.ddr); - - let mut led = pins.d3.into_output(&mut pins.ddr); - - led0.set_high().void_unwrap(); - led1.set_low().void_unwrap(); - led.set_low().void_unwrap(); - - unsafe { - PIN = Some(led); - } - - // In theory this should not be necessary ... But if you previously had - // a sketch from Arduino loaded, the USB device will not have been reset. - // Because of this we will be spammed with interrupts which will never - // stop because they are never handled. - dp.USB_DEVICE.usbcon.reset(); - - // Initialize INT6 - // There is not yet a hal implementation, which is why we need to do this - // manually - let ei = dp.EXINT; - // TODO: Patch EXINT so we at least don't need manual values here - ei.eicrb.write(|w| w.isc6().bits(0x02)); - ei.eimsk.write(|w| w.int().bits(0x40)); - - // Enable interrupts - unsafe { - avr_device::interrupt::enable(); - } - - loop { - led0.toggle().void_unwrap(); - led1.toggle().void_unwrap(); - sparkfun_pro_micro::delay_ms(300); - } -} - -#[avr_device::interrupt(atmega32u4)] -unsafe fn INT6() { - PIN.as_mut().unwrap().toggle().void_unwrap(); -} diff --git a/boards/sparkfun-pro-micro/examples/pro-micro-panic.rs b/boards/sparkfun-pro-micro/examples/pro-micro-panic.rs deleted file mode 100644 index 1a2937bd61..0000000000 --- a/boards/sparkfun-pro-micro/examples/pro-micro-panic.rs +++ /dev/null @@ -1,45 +0,0 @@ -#![no_std] -#![no_main] - -use sparkfun_pro_micro::prelude::*; -use sparkfun_pro_micro::hal::port::mode; - -#[panic_handler] -fn panic(info: &core::panic::PanicInfo) -> ! { - let mut serial: sparkfun_pro_micro::Serial = unsafe { - core::mem::MaybeUninit::uninit().assume_init() - }; - - ufmt::uwriteln!(&mut serial, "Firmware panic!\r").void_unwrap(); - - if let Some(loc) = info.location() { - ufmt::uwriteln!( - &mut serial, - " At {}:{}:{}\r", - loc.file(), - loc.line(), - loc.column(), - ).void_unwrap(); - } - - loop {} -} - -#[sparkfun_pro_micro::entry] -fn main() -> ! { - let dp = sparkfun_pro_micro::Peripherals::take().unwrap(); - - let mut pins = sparkfun_pro_micro::Pins::new(dp.PORTB, dp.PORTC, dp.PORTD, dp.PORTE, dp.PORTF); - - let mut serial = sparkfun_pro_micro::Serial::new( - dp.USART1, - pins.d0, - pins.d1.into_output(&mut pins.ddr), - 57600.into_baudrate(), - ); - - ufmt::uwriteln!(&mut serial, "Hello from Arduino!\r").void_unwrap(); - // Panic messages cannot yet be captured because they rely on core::fmt - // which is way too big for AVR - panic!(); -} diff --git a/boards/sparkfun-pro-micro/examples/pro-micro-pwm.rs b/boards/sparkfun-pro-micro/examples/pro-micro-pwm.rs deleted file mode 100644 index b60f5668df..0000000000 --- a/boards/sparkfun-pro-micro/examples/pro-micro-pwm.rs +++ /dev/null @@ -1,28 +0,0 @@ -#![no_std] -#![no_main] - -use sparkfun_pro_micro::prelude::*; -use sparkfun_pro_micro::pwm; -use panic_halt as _; - -#[sparkfun_pro_micro::entry] -fn main() -> ! { - let dp = sparkfun_pro_micro::Peripherals::take().unwrap(); - - let mut pins = sparkfun_pro_micro::Pins::new(dp.PORTB, dp.PORTC, dp.PORTD, dp.PORTE, dp.PORTF); - - let mut timer0 = pwm::Timer0Pwm::new(dp.TC0, pwm::Prescaler::Prescale64); - - let mut led = pins.d3.into_output(&mut pins.ddr).into_pwm(&mut timer0); - - led.set_duty(128); - led.enable(); - - loop { - for i in 0..=255u16 { - let duty: u16 = i * i / 256; - led.set_duty(duty as u8); - sparkfun_pro_micro::delay_ms(10); - } - } -} diff --git a/boards/sparkfun-pro-micro/examples/pro-micro-serial.rs b/boards/sparkfun-pro-micro/examples/pro-micro-serial.rs deleted file mode 100644 index c050c7d5ec..0000000000 --- a/boards/sparkfun-pro-micro/examples/pro-micro-serial.rs +++ /dev/null @@ -1,29 +0,0 @@ -#![no_std] -#![no_main] - -extern crate panic_halt; -use sparkfun_pro_micro::prelude::*; - -#[sparkfun_pro_micro::entry] -fn main() -> ! { - let dp = sparkfun_pro_micro::Peripherals::take().unwrap(); - - let mut pins = sparkfun_pro_micro::Pins::new(dp.PORTB, dp.PORTC, dp.PORTD, dp.PORTE, dp.PORTF); - - let mut serial = sparkfun_pro_micro::Serial::new( - dp.USART1, - pins.d0, - pins.d1.into_output(&mut pins.ddr), - 57600.into_baudrate(), - ); - - 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(); - } -} diff --git a/boards/sparkfun-pro-micro/examples/pro-micro-spi-feedback.rs b/boards/sparkfun-pro-micro/examples/pro-micro-spi-feedback.rs deleted file mode 100644 index 83a0167f76..0000000000 --- a/boards/sparkfun-pro-micro/examples/pro-micro-spi-feedback.rs +++ /dev/null @@ -1,50 +0,0 @@ -//! 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 ICSP pin 10 to ICSP pin 11. -//! -//! Once this program is written to the board, you can use the board's serial -//! connection to see the output. 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] - -extern crate panic_halt; -use sparkfun_pro_micro::prelude::*; -use sparkfun_pro_micro::spi; -use nb::block; - -#[sparkfun_pro_micro::entry] -fn main() -> ! { - let dp = sparkfun_pro_micro::Peripherals::take().unwrap(); - - let mut pins = sparkfun_pro_micro::Pins::new(dp.PORTB, dp.PORTC, dp.PORTD, dp.PORTE, dp.PORTF); - - let mut serial = sparkfun_pro_micro::Serial::new( - dp.USART1, - pins.d0, - pins.d1.into_output(&mut pins.ddr), - 57600.into_baudrate(), - ); - - // Create SPI interface. - let (mut spi, _) = spi::Spi::new( - dp.SPI, - pins.sck.into_output(&mut pins.ddr), - pins.mosi.into_output(&mut pins.ddr), - pins.miso.into_pull_up_input(&mut pins.ddr), - pins.led_rx.into_output(&mut pins.ddr), - spi::Settings::default(), - ); - - loop { - // Send a byte - block!(spi.send(0b00001111)).void_unwrap(); - // Because MISO is connected to MOSI, the read data should be the same - let data = block!(spi.read()).void_unwrap(); - - ufmt::uwriteln!(&mut serial, "data: {}\r", data).void_unwrap(); - sparkfun_pro_micro::delay_ms(1000); - } -} diff --git a/boards/sparkfun-pro-micro/pro-micro-runner.sh b/boards/sparkfun-pro-micro/pro-micro-runner.sh deleted file mode 100755 index 998d17e1fd..0000000000 --- a/boards/sparkfun-pro-micro/pro-micro-runner.sh +++ /dev/null @@ -1,60 +0,0 @@ -#!/usr/bin/env sh -set -e - -case "$(uname -s)" in - Linux*) OS="Linux";; - Darwin*) OS="Mac";; - *) OS="Unknown";; -esac - -if ! command -v numfmt > /dev/null 2>&1 -then - echo "numfmt is needed for human-readable sizes." >&2 - echo "please install https://command-not-found.com/numfmt" >&2 - alias numfmt=true -fi - -if ! command -v avrdude > /dev/null 2>&1 -then - echo "required avrdude could not be found!" >&2 - echo "please install https://command-not-found.com/avrdude" >&2 - exit 1 -fi - -if [ $OS = "Linux" ]; then - SERIAL_PORT="/dev/ttyACM0" -elif [ $OS = "Mac" ]; then - SERIAL_PORT="/dev/cu.usbmodem146201" -else - echo "unsupported OS, things might not work" >&2 - SERIAL_PORT="/dev/ttyACM0" -fi - -if [ "$1" = "--help" ] || [ "$1" = "-h" ]; then - echo "usage: $0 " >&2 - exit 1 -fi - -if [ "$#" -lt 1 ]; then - echo "$0: no ELF file given" >&2 - exit 1 -fi - -NAME="$(basename "$1")" -SIZE_TEXT="$(avr-size "$1" | tail -1 | cut -f1)" -SIZE_DATA="$(avr-size "$1" | tail -1 | cut -f2)" -SIZE_BSS="$(avr-size "$1" | tail -1 | cut -f3)" - -printf "\n" -printf "Program: %s\n" "$NAME" -printf "Size:\n" -printf " .text %s (exact: %d)\n" "$(numfmt --to=si --padding=9 "$SIZE_TEXT")" "$SIZE_TEXT" -printf " .data %s (exact: %d)\n" "$(numfmt --to=si --padding=9 "$SIZE_DATA")" "$SIZE_DATA" -printf " .bss %s (exact: %d)\n" "$(numfmt --to=si --padding=9 "$SIZE_BSS")" "$SIZE_BSS" -printf "\n" -printf "Please bring up the bootloader and press ENTER!\n" -read -r -printf "Attempting to flash ...\n" -printf "\n" - -avrdude -qq -patmega32u4 -cavr109 -P"${SERIAL_PORT}" -b57600 -D "-Uflash:w:$1:e" diff --git a/boards/sparkfun-pro-micro/src/lib.rs b/boards/sparkfun-pro-micro/src/lib.rs deleted file mode 100644 index d15f025c74..0000000000 --- a/boards/sparkfun-pro-micro/src/lib.rs +++ /dev/null @@ -1,219 +0,0 @@ -//! Board Support Crate for _SparkFun Pro Micro_. -//! -//! This crate provides abstractions for interfacing with the hardware of SparkFun Pro Micro. It -//! re-exports functionality from the underlying HAL in ways that make more sense for this -//! particular board. For example, the pins are named by what is printed on the PCB instead of the -//! MCU names. -//! -//! # Examples -//! A number of examples can be found in the [`examples/`][ex] subdirectory of this crate. -//! -//! [ex]: https://github.com/Rahix/avr-hal/tree/master/boards/sparkfun-pro-micro/examples -//! -//! # Getting Started -//! Please follow the guide from [`avr-hal`'s README][guide] for steps on how to set up a project -//! with this board. A rough skeleton for an application looks like this: -//! -//! ```no_run -//! #![no_std] -//! #![no_main] -//! -//! // Pull in the panic handler from panic-halt -//! extern crate panic_halt; -//! -//! // The prelude just exports all HAL traits anonymously which makes -//! // all trait methods available. This is probably something that -//! // should always be added. -//! use sparkfun_pro_micro::prelude::*; -//! -//! // Define the entry-point for the application. This can only be -//! // done once in the entire dependency tree. -//! #[sparkfun_pro_micro::entry] -//! fn main() -> ! { -//! // Get the peripheral singletons for interacting with them. -//! let dp = sparkfun_pro_micro::Peripherals::take().unwrap(); -//! -//! unimplemented!() -//! } -//! ``` -//! -//! [guide]: https://github.com/Rahix/avr-hal#starting-your-own-project - -#![no_std] - -pub use atmega32u4_hal as hal; -pub use crate::hal::pac; - -/// See [`avr_device::entry`](https://docs.rs/avr-device/latest/avr_device/attr.entry.html). -#[cfg(feature = "rt")] -pub use crate::hal::entry; - -mod pins; -pub use crate::pins::*; - -pub use crate::pac::Peripherals; -pub mod prelude { - pub use crate::hal::prelude::*; - pub use crate::hal::usart::BaudrateExt as _; -} - - -/// Busy-Delay -/// -/// **Note**: For just delaying, using [`sparkfun_pro_micro::delay_ms()`][delay_ms] or -/// [`sparkfun_pro_micro::delay_us()`][delay_us] is probably the better choice. This type is more -/// useful when an `embedded-hal` driver needs a delay implementation. -/// -/// [delay_ms]: fn.delay_ms.html -/// [delay_us]: fn.delay_us.html -pub type Delay = hal::delay::Delay; - -/// Wait (busy spin) for `ms` milliseconds -pub fn delay_ms(ms: u16) { - use prelude::*; - - Delay::new().delay_ms(ms) -} - -/// Wait (busy spin) for `us` microseconds -pub fn delay_us(us: u16) { - use prelude::*; - - Delay::new().delay_us(us) -} - -/// Support for the Serial Peripheral Interface -/// -/// # Example -/// For a full example, see [`examples/pro-micro-spi-feedback.rs`][ex-spi]. In short: -/// ```no_run -/// let dp = sparkfun_pro_micro::Peripherals::take().unwrap(); -/// -/// let mut pins = sparkfun_pro_micro::Pins::new(dp.PORTB, dp.PORTC, dp.PORTD, dp.PORTE, dp.PORTF); -/// -/// pins.led_rx.into_output(&mut pins.ddr); // Chip Select must be set to output mode. -/// -/// // Create SPI interface. -/// let mut spi = sparkfun_pro_micro::spi::Spi::new( -/// dp.SPI, -/// pins.sck.into_output(&mut pins.ddr), -/// pins.mosi.into_output(&mut pins.ddr), -/// pins.miso.into_pull_up_input(&mut pins.ddr), -/// sparkfun_pro_micro::spi::Settings::default(), -/// ); -/// ``` -/// -/// [ex-spi]: https://github.com/Rahix/avr-hal/blob/master/boards/sparkfun-pro-micro/examples/pro-micro-spi-feedback.rs -pub mod spi { - pub use atmega32u4_hal::spi::*; -} - -/// Support for the Analog to Digital Converter -/// -/// # Example -/// For a full example, see [`examples/pro-micro-adc.rs`][ex-adc]. In short: -/// ```no_run -/// let dp = sparkfun_pro_micro::Peripherals::take().unwrap(); -/// -/// let mut pins = sparkfun_pro_micro::Pins::new(dp.PORTB, dp.PORTC, dp.PORTD, dp.PORTE, dp.PORTF); -/// -/// let mut adc = sparkfun_pro_micro::adc::Adc::new(dp.ADC, Default::default()); -/// -/// let v_bandgap: u16 = nb::block!( -/// adc.read(&mut sparkfun_pro_micro::adc::channel::Vbg) -/// ).void_unwrap(), -/// -/// let portf = dp.PORTF.split(); -/// let mut a0 = portf.pf7.into_analog_input(&mut adc); -/// let mut a1 = portf.pf6.into_analog_input(&mut adc); -/// let mut a2 = portf.pf5.into_analog_input(&mut adc); -/// let mut a3 = portf.pf4.into_analog_input(&mut adc); -/// let mut a4 = portf.pf1.into_analog_input(&mut adc); -/// let mut a5 = portf.pf0.into_analog_input(&mut adc); -/// -/// let v: u16 = nb::block!(adc.read(&mut a0)).void_unwrap(), -/// ``` -/// -/// [ex-adc]: https://github.com/Rahix/avr-hal/blob/master/boards/sparkfun-pro-micro/examples/pro-micro-adc.rs -pub mod adc { - pub use atmega32u4_hal::adc::*; -} - -/// Support for PWM pins -/// -/// The 4 timers of ATmega32U4 can be used for PWM on certain pins. -/// The PWM methods are from `embedded_hal::PwmPin`. -/// -/// # Example -/// For a full example, see [`examples/pro-micro-pwm.rs`][ex-pwm]. In short: -/// ``` -/// let mut pins = sparkfun_pro_micro::Pins::new(dp.PORTB, dp.PORTC, dp.PORTD, dp.PORTE, dp.PORTF); -/// let mut timer1 = Timer1Pwm::new(dp.TC1); -/// -/// let mut d3 = pins.d3.into_output(&mut pins.ddr).into_pwm(&mut timer0); -/// -/// d3.set_duty(128); -/// d3.enable(); -/// ``` -/// -/// [ex-pwm]: https://github.com/Rahix/avr-hal/blob/master/boards/sparkfun-pro-micro/examples/pro-micro-pwm.rs -/// -/// Here is an overview of pins and which timer they work with: -/// -/// | Pin | Conversion Method | Alternate Conversion Method | -/// | --- | --- | --- | -/// | `pins.d3` | `.into_pwm(&mut timer0)` | | -/// | `pins.d5` | `.into_pwm(&mut timer3)` | | -/// | `pins.d6` | `.into_pwm(&mut timer4)` | | -/// | `pins.d9` | `.into_pwm(&mut timer1)` | | -/// | `pins.d10` | `.into_pwm(&mut timer1)` | `.into_pwm4(&mut timer4)` | -/// | `pins.d11` | `.into_pwm(&mut timer0)` | `.into_pwm1(&mut timer1)` | -/// | `pins.d13` | `.into_pwm(&mut timer4)` | | -pub mod pwm { - pub use atmega32u4_hal::pwm::*; -} - -/// Serial (UART) interface on pins `D0` (RX) and `D1` (TX) -/// -/// # Example -/// For a full example, see [`examples/pro-micro-serial.rs`][ex-serial]. In short: -/// ```no_run -/// let dp = sparkfun_pro_micro::Peripherals::take().unwrap(); -/// -/// let mut pins = sparkfun_pro_micro::Pins::new(dp.PORTB, dp.PORTC, dp.PORTD, dp.PORTE, dp.PORTF); -/// -/// let mut serial = sparkfun_pro_micro::Serial::new( -/// dp.USART1, -/// pins.d0, -/// pins.d1.into_output(&mut pins.ddr), -/// 57600.into_baudrate(), -/// ); -/// -/// ufmt::uwriteln!(&mut serial, "Hello from Arduino!\r").void_unwrap(); -/// ``` -/// -/// [ex-serial]: https://github.com/Rahix/avr-hal/blob/master/boards/sparkfun-pro-micro/examples/pro-micro-serial.rs -pub type Serial = hal::usart::Usart1; - -/// I2C Master on pins `D2` (SDA) and `D3` (SCL) -/// -/// # Example -/// For a full example, see [`examples/pro-micro-i2cdetect.rs`][ex-i2c]. In short: -/// ```no_run -/// let dp = sparkfun_pro_micro::Peripherals::take().unwrap(); -/// -/// let mut pins = sparkfun_pro_micro::Pins::new(dp.PORTB, dp.PORTC, dp.PORTD, dp.PORTE, dp.PORTF); -/// -/// let mut i2c = sparkfun_pro_micro::I2cMaster::new( -/// dp.TWI, -/// pins.d2.into_pull_up_input(&mut pins.ddr), -/// pins.d3.into_pull_up_input(&mut pins.ddr), -/// 50000, -/// ); -/// ``` -/// -/// [ex-i2c]: https://github.com/Rahix/avr-hal/blob/master/boards/sparkfun-pro-micro/examples/pro-micro-i2cdetect.rs -pub type I2cMaster = hal::i2c::I2cMaster; -#[doc(hidden)] -#[deprecated = "Please use `I2cMaster` instead of `I2c`"] -pub type I2c = I2cMaster; diff --git a/boards/sparkfun-pro-micro/src/pins.rs b/boards/sparkfun-pro-micro/src/pins.rs deleted file mode 100644 index 632bb7f09e..0000000000 --- a/boards/sparkfun-pro-micro/src/pins.rs +++ /dev/null @@ -1,108 +0,0 @@ -use crate::hal::port::PortExt; - -avr_hal_generic::impl_board_pins! { - #[port_defs] - use crate::hal::port; - - /// Generic DDR that works for all ports - pub struct DDR { - portb: crate::pac::PORTB, - portc: crate::pac::PORTC, - portd: crate::pac::PORTD, - porte: crate::pac::PORTE, - portf: crate::pac::PORTF, - } - - /// Reexport of the Pro Micro's pins, with the names they have on the board - pub struct Pins { - /// `D0` / `RX` - /// - /// * `RX` (UART) - /// * `INT2`: External Interrupt - pub d0: portd::pd2::PD2, - /// `D1` / `TX` - /// - /// * `TX` (UART) - /// * `INT3`: External Interrupt - pub d1: portd::pd3::PD3, - /// `D2` / `SDA` - /// - /// * `SDA`: i2c/twi data - /// * `INT1`: External Interrupt - pub d2: portd::pd1::PD1, - /// `D3` / `SCL` - /// - /// * **PWM**: [atmega32u4_hal::timer::Timer0Pwm] - /// * `SCL`: i2c/twi clock - /// * `INT0`: External Interrupt - /// * `OC0B`: Output Compare Channel `B` for Timer/Counter0 - pub d3: portd::pd0::PD0, - /// `D4` - pub d4: portd::pd4::PD4, - /// `D5` - /// - /// * **PWM**: [atmega32u4_hal::timer::Timer3Pwm] - /// * `OC3A`: Output Compare Channel `A` for Timer/Counter3 - /// * `#OC4A`: Inverted Output Compare Channel `A` for Timer/Counter4 (Not implemented) - pub d5: portc::pc6::PC6, - /// `D6` - /// - /// * **PWM**: [atmega32u4_hal::timer::Timer4Pwm] - /// * `OC4D`: Output Compare Channel `D` for Timer/Counter4 - pub d6: portd::pd7::PD7, - /// `D7` - /// - /// * `INT6`: External Interrupt - pub d7: porte::pe6::PE6, - /// `D8` - pub d8: portb::pb4::PB4, - /// `D9` - /// - /// * **PWM**: [atmega32u4_hal::timer::Timer1Pwm] - /// * `OC1A`: Output Compare Channel `A` for Timer/Counter1 - /// * `#OC4B`: Inverted Output Compare Channel `B` for Timer/Counter4 (Not implemented) - pub d9: portb::pb5::PB5, - /// `D10` - /// - /// * **PWM**: [atmega32u4_hal::timer::Timer1Pwm] - /// * `OC1B`: Output Compare Channel `B` for Timer/Counter1 - /// * `OC4B`: Output Compare Channel `B` for Timer/Counter4 (Not implemented) - pub d10: portb::pb6::PB6, - /// `RX` - /// - /// Led for indicating inbound data. Also the CS pin. - pub led_rx: portb::pb0::PB0, - /// `TX` - /// - /// Led for indicating outbound data - pub led_tx: portd::pd5::PD5, - /// `SCLK` - /// - /// ICSP SCLK pin - pub sck: portb::pb1::PB1, - /// `MOSI` - /// - /// ICSP MOSI pin - pub mosi: portb::pb2::PB2, - /// `MISO` - /// - /// ICSP MISO pin - pub miso: portb::pb3::PB3, - /// `A0` - /// - /// * `ADC7` channel - pub a0: portf::pf7::PF7, - /// `A1` - /// - /// * `ADC6` channel - pub a1: portf::pf6::PF6, - /// `A2` - /// - /// * `ADC5` channel - pub a2: portf::pf5::PF5, - /// `A3` - /// - /// * `ADC4` channel - pub a3: portf::pf4::PF4, - } -} diff --git a/boards/trinket/.cargo/config.toml b/boards/trinket/.cargo/config.toml deleted file mode 100644 index 2c263eb609..0000000000 --- a/boards/trinket/.cargo/config.toml +++ /dev/null @@ -1,5 +0,0 @@ -[build] -target = "../../avr-specs/avr-attiny85.json" - -[unstable] -build-std = ["core"] diff --git a/boards/trinket/Cargo.toml b/boards/trinket/Cargo.toml deleted file mode 100644 index 9466510c0b..0000000000 --- a/boards/trinket/Cargo.toml +++ /dev/null @@ -1,16 +0,0 @@ -[package] -name = "trinket" -version = "0.1.0" -authors = ["Rahix "] -edition = "2018" - -[features] -default = ["rt"] -rt = ["attiny85-hal/rt"] - -[dependencies] -avr-hal-generic = { path = "../../avr-hal-generic/" } -attiny85-hal = { path = "../../chips/attiny85-hal/" } - -[dev-dependencies] -panic-halt = "0.2.0" diff --git a/boards/trinket/examples/trinket-blink.rs b/boards/trinket/examples/trinket-blink.rs deleted file mode 100644 index 720affcc94..0000000000 --- a/boards/trinket/examples/trinket-blink.rs +++ /dev/null @@ -1,20 +0,0 @@ -#![no_std] -#![no_main] - -extern crate panic_halt; -use trinket::prelude::*; - -#[trinket::entry] -fn main() -> ! { - let dp = trinket::Peripherals::take().unwrap(); - - let mut delay = trinket::Delay::new(); - let mut pins = trinket::Pins::new(dp.PORTB); - - let mut led = pins.d1.into_output(&mut pins.ddr); - - loop { - led.toggle().void_unwrap(); - delay.delay_ms(500u16); - } -} diff --git a/boards/trinket/src/lib.rs b/boards/trinket/src/lib.rs deleted file mode 100644 index a16ced1edf..0000000000 --- a/boards/trinket/src/lib.rs +++ /dev/null @@ -1,43 +0,0 @@ -#![no_std] - -// Expose hal & pac crates -pub use attiny85_hal as hal; -pub use crate::hal::pac; - -/// See [`avr_device::entry`](https://docs.rs/avr-device/latest/avr_device/attr.entry.html). -#[cfg(feature = "rt")] -pub use crate::hal::entry; - -pub use crate::pac::Peripherals; -pub use crate::hal::prelude; - -pub type Delay = crate::hal::delay::Delay; - -pub use crate::pins::*; -mod pins { - use crate::hal::port::PortExt; - - avr_hal_generic::impl_board_pins! { - #[port_defs] - use crate::hal::port; - - /// Generic DDR (not strictly necessary for ATtiny85) - pub struct DDR { - portb: crate::pac::PORTB, - } - - /// Reexport of the pins with names as on the Trinket board - pub struct Pins { - /// `#0`: `PB0`, `DI`(SPI), `SDA`(I2C) - pub d0: portb::pb0::PB0, - /// `#1`: `PB1`, `DO`(SPI), Builtin LED - pub d1: portb::pb1::PB1, - /// `#2`: `PB2`, `SCK`(SPI), `SCL`(I2C) - pub d2: portb::pb2::PB2, - /// `#3`: `PB3` - pub d3: portb::pb3::PB3, - /// `#4`: `PB4` - pub d4: portb::pb4::PB4, - } - } -} diff --git a/chips/atmega1280-hal/.cargo/config.toml b/chips/atmega1280-hal/.cargo/config.toml deleted file mode 100644 index 7b7798dad7..0000000000 --- a/chips/atmega1280-hal/.cargo/config.toml +++ /dev/null @@ -1,5 +0,0 @@ -[build] -target = "../../avr-specs/avr-atmega1280.json" - -[unstable] -build-std = ["core"] diff --git a/chips/atmega1280-hal/Cargo.toml b/chips/atmega1280-hal/Cargo.toml deleted file mode 100644 index ee0adac2f4..0000000000 --- a/chips/atmega1280-hal/Cargo.toml +++ /dev/null @@ -1,15 +0,0 @@ -[package] -name = "atmega1280-hal" -version = "0.1.0" -authors = ["Gabriel Pickl "] -edition = "2018" - -[features] -rt = ["avr-device/rt"] - -[dependencies] -avr-hal-generic = { path = "../../avr-hal-generic/" } - -[dependencies.avr-device] -version = "0.3" -features = ["atmega1280"] diff --git a/chips/atmega1280-hal/src/lib.rs b/chips/atmega1280-hal/src/lib.rs deleted file mode 100644 index 72f5abe58d..0000000000 --- a/chips/atmega1280-hal/src/lib.rs +++ /dev/null @@ -1,34 +0,0 @@ -#![no_std] - -/// Reexport of `atemga1280` from `avr-device` -pub use avr_device::atmega1280 as pac; - -/// See [`avr_device::entry`](https://docs.rs/avr-device/latest/avr_device/attr.entry.html). -#[cfg(feature = "rt")] -pub use avr_device::entry; - -pub use avr_hal_generic::clock; -pub use avr_hal_generic::delay; - -pub mod port; -pub mod usart; - -pub mod prelude { - pub use avr_hal_generic::prelude::*; - pub use crate::port::PortExt as _; -} - -pub mod i2c { - use crate::port::portd; - pub use avr_hal_generic::i2c::*; - - avr_hal_generic::impl_twi_i2c! { - pub struct I2c { - peripheral: crate::pac::TWI, - pins: { - sda: portd::PD1, - scl: portd::PD0, - }, - } - } -} diff --git a/chips/atmega1280-hal/src/port.rs b/chips/atmega1280-hal/src/port.rs deleted file mode 100644 index 2160046ebe..0000000000 --- a/chips/atmega1280-hal/src/port.rs +++ /dev/null @@ -1,269 +0,0 @@ -//! Digital IO Implementations -//! -//! For a detailed explanation, refer to the [general Digital IO documentation][1]. -//! -//! [1]: ../../avr_hal_generic/port/index.html - -pub use avr_hal_generic::port::mode; - -pub trait PortExt { - type Parts; - - fn split(self) -> Self::Parts; -} - -avr_hal_generic::impl_generic_pin! { - pub enum Pin { - A(crate::pac::PORTA, porta, pina, ddra), - B(crate::pac::PORTB, portb, pinb, ddrb), - C(crate::pac::PORTC, portc, pinc, ddrc), - D(crate::pac::PORTD, portd, pind, ddrd), - E(crate::pac::PORTE, porte, pine, ddre), - F(crate::pac::PORTF, portf, pinf, ddrf), - G(crate::pac::PORTG, portg, ping, ddrg), - H(crate::pac::PORTH, porth, pinh, ddrh), - J(crate::pac::PORTJ, portj, pinj, ddrj), - K(crate::pac::PORTK, portk, pink, ddrk), - L(crate::pac::PORTL, portl, pinl, ddrl), - } -} - -avr_hal_generic::impl_port! { - pub mod porta { - #[port_ext] - use super::PortExt; - - #[generic_pin] - use Pin::A; - - impl PortExt for crate::pac::PORTA { - regs: (pina, ddra, porta), - pa0: (PA0, 0), - pa1: (PA1, 1), - pa2: (PA2, 2), - pa3: (PA3, 3), - pa4: (PA4, 4), - pa5: (PA5, 5), - pa6: (PA6, 6), - pa7: (PA7, 7), - } - } -} - -avr_hal_generic::impl_port! { - pub mod portb { - #[port_ext] - use super::PortExt; - - #[generic_pin] - use Pin::B; - - impl PortExt for crate::pac::PORTB { - regs: (pinb, ddrb, portb), - pb0: (PB0, 0), - pb1: (PB1, 1), - pb2: (PB2, 2), - pb3: (PB3, 3), - pb4: (PB4, 4), - pb5: (PB5, 5), - pb6: (PB6, 6), - pb7: (PB7, 7), - } - } -} - -avr_hal_generic::impl_port! { - pub mod portc { - #[port_ext] - use super::PortExt; - - #[generic_pin] - use Pin::C; - - impl PortExt for crate::pac::PORTC { - regs: (pinc, ddrc, portc), - pc0: (PC0, 0), - pc1: (PC1, 1), - pc2: (PC2, 2), - pc3: (PC3, 3), - pc4: (PC4, 4), - pc5: (PC5, 5), - pc6: (PC6, 6), - pc7: (PC7, 7), - } - } -} - -avr_hal_generic::impl_port! { - pub mod portd { - #[port_ext] - use super::PortExt; - - #[generic_pin] - use Pin::D; - - impl PortExt for crate::pac::PORTD { - regs: (pind, ddrd, portd), - pd0: (PD0, 0), - pd1: (PD1, 1), - pd2: (PD2, 2), - pd3: (PD3, 3), - pd4: (PD4, 4), - pd5: (PD5, 5), - pd6: (PD6, 6), - pd7: (PD7, 7), - } - } -} - -avr_hal_generic::impl_port! { - pub mod porte { - #[port_ext] - use super::PortExt; - - #[generic_pin] - use Pin::E; - - impl PortExt for crate::pac::PORTE { - regs: (pine, ddre, porte), - pe0: (PE0, 0), - pe1: (PE1, 1), - pe2: (PE2, 2), - pe3: (PE3, 3), - pe4: (PE4, 4), - pe5: (PE5, 5), - pe6: (PE6, 6), - pe7: (PE7, 7), - } - } -} - -avr_hal_generic::impl_port! { - pub mod portf { - #[port_ext] - use super::PortExt; - - #[generic_pin] - use Pin::F; - - impl PortExt for crate::pac::PORTF { - regs: (pinf, ddrf, portf), - pf0: (PF0, 0), - pf1: (PF1, 1), - pf2: (PF2, 2), - pf3: (PF3, 3), - pf4: (PF4, 4), - pf5: (PF5, 5), - pf6: (PF6, 6), - pf7: (PF7, 7), - } - } -} - -avr_hal_generic::impl_port! { - pub mod portg { - #[port_ext] - use super::PortExt; - - #[generic_pin] - use Pin::G; - - impl PortExt for crate::pac::PORTG { - regs: (ping, ddrg, portg), - pg0: (PG0, 0), - pg1: (PG1, 1), - pg2: (PG2, 2), - pg3: (PG3, 3), - pg4: (PG4, 4), - pg5: (PG5, 5), - } - } -} - -avr_hal_generic::impl_port! { - pub mod porth { - #[port_ext] - use super::PortExt; - - #[generic_pin] - use Pin::H; - - impl PortExt for crate::pac::PORTH { - regs: (pinh, ddrh, porth), - ph0: (PH0, 0), - ph1: (PH1, 1), - ph2: (PH2, 2), - ph3: (PH3, 3), - ph4: (PH4, 4), - ph5: (PH5, 5), - ph6: (PH6, 6), - ph7: (PH7, 7), - } - } -} - -avr_hal_generic::impl_port! { - pub mod portj { - #[port_ext] - use super::PortExt; - - #[generic_pin] - use Pin::J; - - impl PortExt for crate::pac::PORTJ { - regs: (pinj, ddrj, portj), - pj0: (PJ0, 0), - pj1: (PJ1, 1), - pj2: (PJ2, 2), - pj3: (PJ3, 3), - pj4: (PJ4, 4), - pj5: (PJ5, 5), - pj6: (PJ6, 6), - pj7: (PJ7, 7), - } - } -} - -avr_hal_generic::impl_port! { - pub mod portk { - #[port_ext] - use super::PortExt; - - #[generic_pin] - use Pin::K; - - impl PortExt for crate::pac::PORTK { - regs: (pink, ddrk, portk), - pk0: (PK0, 0), - pk1: (PK1, 1), - pk2: (PK2, 2), - pk3: (PK3, 3), - pk4: (PK4, 4), - pk5: (PK5, 5), - pk6: (PK6, 6), - pk7: (PK7, 7), - } - } -} - -avr_hal_generic::impl_port! { - pub mod portl { - #[port_ext] - use super::PortExt; - - #[generic_pin] - use Pin::L; - - impl PortExt for crate::pac::PORTL { - regs: (pinl, ddrl, portl), - pl0: (PL0, 0), - pl1: (PL1, 1), - pl2: (PL2, 2), - pl3: (PL3, 3), - pl4: (PL4, 4), - pl5: (PL5, 5), - pl6: (PL6, 6), - pl7: (PL7, 7), - } - } -} diff --git a/chips/atmega1280-hal/src/usart.rs b/chips/atmega1280-hal/src/usart.rs deleted file mode 100644 index e46bea87b8..0000000000 --- a/chips/atmega1280-hal/src/usart.rs +++ /dev/null @@ -1,55 +0,0 @@ -use crate::port::porte; -use crate::port::portd; -use crate::port::porth; -use crate::port::portj; -pub use avr_hal_generic::usart::*; - -pub type Usart0 = Usart< - crate::pac::USART0, - porte::PE0>, - porte::PE1, - CLOCK, ->; -pub type Usart1 = Usart< - crate::pac::USART1, - portd::PD2>, - portd::PD3, - CLOCK, ->; -pub type Usart2 = Usart< - crate::pac::USART2, - porth::PH0>, - porth::PH1, - CLOCK, ->; -pub type Usart3 = Usart< - crate::pac::USART3, - portj::PJ0>, - portj::PJ1, - CLOCK, ->; - -avr_hal_generic::impl_usart_traditional! { - peripheral: crate::pac::USART0, - register_suffix: 0, - rx: porte::PE0, - tx: porte::PE1, -} -avr_hal_generic::impl_usart_traditional! { - peripheral: crate::pac::USART1, - register_suffix: 1, - rx: portd::PD2, - tx: portd::PD3, -} -avr_hal_generic::impl_usart_traditional! { - peripheral: crate::pac::USART2, - register_suffix: 2, - rx: porth::PH0, - tx: porth::PH1, -} -avr_hal_generic::impl_usart_traditional! { - peripheral: crate::pac::USART3, - register_suffix: 3, - rx: portj::PJ0, - tx: portj::PJ1, -} diff --git a/chips/atmega168-hal/.cargo/config.toml b/chips/atmega168-hal/.cargo/config.toml deleted file mode 100644 index 7dd47dddac..0000000000 --- a/chips/atmega168-hal/.cargo/config.toml +++ /dev/null @@ -1,5 +0,0 @@ -[build] -target = "../../avr-specs/avr-atmega168.json" - -[unstable] -build-std = ["core"] diff --git a/chips/atmega168-hal/Cargo.toml b/chips/atmega168-hal/Cargo.toml deleted file mode 100644 index 8fddde91ab..0000000000 --- a/chips/atmega168-hal/Cargo.toml +++ /dev/null @@ -1,15 +0,0 @@ -[package] -name = "atmega168-hal" -version = "0.1.0" -authors = ["Karl Thorén "] -edition = "2018" - -[features] -rt = ["avr-device/rt"] - -[dependencies] -avr-hal-generic = { path = "../../avr-hal-generic/" } - -[dependencies.avr-device] -version = "0.3" -features = ["atmega168"] diff --git a/chips/atmega168-hal/src/adc.rs b/chips/atmega168-hal/src/adc.rs deleted file mode 100644 index 0bcbcd7df5..0000000000 --- a/chips/atmega168-hal/src/adc.rs +++ /dev/null @@ -1,45 +0,0 @@ -extern crate avr_hal_generic as avr_hal; - -use crate::port::portc::{PC0, PC1, PC2, PC3, PC4, PC5}; - -use crate::pac::adc::admux::MUX_A; - -avr_hal_generic::impl_adc! { - pub struct Adc { - type ChannelID = MUX_A; - peripheral: crate::pac::ADC, - set_mux: |peripheral, id| { - peripheral.admux.modify(|_, w| w.mux().variant(id)); - }, - pins: { - pc0: (PC0, MUX_A::ADC0, didr0::adc0d), - pc1: (PC1, MUX_A::ADC1, didr0::adc1d), - pc2: (PC2, MUX_A::ADC2, didr0::adc2d), - pc3: (PC3, MUX_A::ADC3, didr0::adc3d), - pc4: (PC4, MUX_A::ADC4, didr0::adc4d), - pc5: (PC5, MUX_A::ADC5, didr0::adc5d), - } - } -} - -/// Additional channels -/// -/// This module contains ADC channels, additional to the direct pin channels. -pub mod channel { - use avr_hal_generic::hal::adc::Channel; - use crate::pac::adc::admux::MUX_A; - - /// Channel for the _Bandgap Reference Voltage_ - pub struct Vbg; - impl Channel for Vbg { - type ID = MUX_A; - fn channel() -> Self::ID { MUX_A::ADC_VBG } - } - - /// Channel for _GND_ - pub struct Gnd; - impl Channel for Gnd { - type ID = MUX_A; - fn channel() -> Self::ID { MUX_A::ADC_GND } - } -} diff --git a/chips/atmega168-hal/src/lib.rs b/chips/atmega168-hal/src/lib.rs deleted file mode 100644 index a6558fee32..0000000000 --- a/chips/atmega168-hal/src/lib.rs +++ /dev/null @@ -1,102 +0,0 @@ -//! # Notes -//! The ATmega48/V/88/V/168/V is an older family that is replaced with the ATmega48A/PA/88A/PA/168A/PA/328/P family. -//! -//! Examples for [atmega328p-hal](../atmega328p_hal/index.html) can in most cases be used. -//! -#![no_std] - -pub use avr_device::atmega168 as pac; - -/// See [`avr_device::entry`](https://docs.rs/avr-device/latest/avr_device/attr.entry.html). -#[cfg(feature = "rt")] -pub use avr_device::entry; - -pub use avr_hal_generic::clock; -pub use avr_hal_generic::delay; - -pub mod adc; -pub mod port; -pub mod pwm; - -pub mod prelude { - pub use avr_hal_generic::prelude::*; - pub use crate::port::PortExt as _; -} - -/// I2C Bus -pub mod i2c { - use crate::port::portc; - pub use avr_hal_generic::i2c::*; - - avr_hal_generic::impl_twi_i2c! { - /// I2C based on ATmega168's TWI peripheral - pub struct I2c { - peripheral: crate::pac::TWI, - pins: { - sda: portc::PC4, - scl: portc::PC5, - }, - } - } -} - -pub mod spi { - //! Implementation of the Rust Embedded-HAL SPI FullDuplex trait for AVR. - //! - //! The interface can be instantiated with the `new` method, and used directly - //! or passed into a driver. Example usage: - //! - //! ``` - //! // create SPI interface - //! let (mut spi, mut cs) = Spi::new( - //! dp.SPI,// SPI peripheral - //! pins.d13.into_output(&mut pins.ddr),// SCLK - //! pins.d11.into_output(&mut pins.ddr),// MOSI output pin - //! pins.d12.into_pull_up_input(&mut pins.ddr),// MISO input pin - //! pins.d10.into_output(&mut pins.ddr),// CS pin - //! Settings::default(), - //! ); - //! - //! // Send a byte - //! let sent = 0b10101010; - //! spi.send(sent).unwrap(); - //! let response = spi.read().unwrap(); - //! ``` - //! In the example above, all of the settings are left at the default. You can - //! also instantiate a Settings object with the other options available. - - use crate::port::portb; - pub use avr_hal_generic::spi::*; - - avr_hal_generic::impl_spi! { - pub struct Spi { - peripheral: crate::pac::SPI, - pins: { - sclk: portb::PB5, - mosi: portb::PB3, - miso: portb::PB4, - cs: portb::PB2, - } - } - } -} - -/// Serial interface using USART -pub mod usart { - use crate::port::portd; - pub use avr_hal_generic::usart::*; - - pub type Usart0 = Usart< - crate::pac::USART0, - portd::PD0>, - portd::PD1, - CLOCK, - >; - - avr_hal_generic::impl_usart_traditional! { - peripheral: crate::pac::USART0, - register_suffix: 0, - rx: portd::PD0, - tx: portd::PD1, - } -} diff --git a/chips/atmega168-hal/src/port.rs b/chips/atmega168-hal/src/port.rs deleted file mode 100644 index 9fa65ca35c..0000000000 --- a/chips/atmega168-hal/src/port.rs +++ /dev/null @@ -1,82 +0,0 @@ -//! `PORTB` - `PORTD` digital IO -pub use avr_hal_generic::port::mode; - -pub trait PortExt { - type Parts; - - fn split(self) -> Self::Parts; -} - -avr_hal_generic::impl_generic_pin! { - pub enum Pin { - B(crate::pac::PORTB, portb, pinb, ddrb), - C(crate::pac::PORTC, portc, pinc, ddrc), - D(crate::pac::PORTD, portd, pind, ddrd), - } -} - -avr_hal_generic::impl_port! { - pub mod portb { - #[port_ext] - use super::PortExt; - - #[generic_pin] - use Pin::B; - - impl PortExt for crate::pac::PORTB { - regs: (pinb, ddrb, portb), - pb0: (PB0, 0), - pb1: (PB1, 1), - pb2: (PB2, 2), - pb3: (PB3, 3), - pb4: (PB4, 4), - pb5: (PB5, 5), - pb6: (PB6, 6), - pb7: (PB7, 7), - } - } -} - -avr_hal_generic::impl_port! { - pub mod portc { - #[port_ext] - use super::PortExt; - - #[generic_pin] - use Pin::C; - - impl PortExt for crate::pac::PORTC { - regs: (pinc, ddrc, portc), - pc0: (PC0, 0), - pc1: (PC1, 1), - pc2: (PC2, 2), - pc3: (PC3, 3), - pc4: (PC4, 4), - pc5: (PC5, 5), - pc6: (PC6, 6), - } - } -} - -avr_hal_generic::impl_port! { - pub mod portd { - #[port_ext] - use super::PortExt; - - #[generic_pin] - use Pin::D; - - impl PortExt for crate::pac::PORTD { - regs: (pind, ddrd, portd), - pd0: (PD0, 0), - pd1: (PD1, 1), - pd2: (PD2, 2), - pd3: (PD3, 3), - pd4: (PD4, 4), - pd5: (PD5, 5), - pd6: (PD6, 6), - pd7: (PD7, 7), - } - } -} - diff --git a/chips/atmega168-hal/src/pwm.rs b/chips/atmega168-hal/src/pwm.rs deleted file mode 100644 index e8fe106f8e..0000000000 --- a/chips/atmega168-hal/src/pwm.rs +++ /dev/null @@ -1,174 +0,0 @@ -//! Support for PWM pins -//! -//! The 3 timers of ATmega168 can be used for PWM on certain pins. -//! The PWM methods are from `embedded_hal::PwmPin`. -//! -//! # Example -//! ``` -//! let mut portb = dp.PORTB.split(); -//! let mut timer1 = Timer1Pwm::new(dp.TC1); -//! -//! let mut pb1 = portb.pb1.into_output(&mut portb.ddr).into_pwm(&mut timer1); -//! -//! pb1.set_duty(128); -//! pb1.enable(); -//! ``` -//! -//! Here is an overview of pins and which timer they work with: -//! -//! | Pin | Conversion Method | -//! | --- | --- | -//! | `PB1` | `.into_pwm(&mut timer1)` | -//! | `PB2` | `.into_pwm(&mut timer1)` | -//! | `PB3` | `.into_pwm(&mut timer2)` | -//! | `PD3` | `.into_pwm(&mut timer2)` | -//! | `PD5` | `.into_pwm(&mut timer0)` | -//! | `PD6` | `.into_pwm(&mut timer0)` | - -use crate::port::{portb, portd}; -pub use avr_hal_generic::pwm::*; - -avr_hal_generic::impl_pwm! { - /// Use `TC0` for PWM (pins `PD5`, `PD6`) - /// - /// # Example - /// ``` - /// let mut portd = dp.PORTD.split(); - /// let mut timer0 = Timer0Pwm::new(dp.TC0, pwm::Prescaler::Prescale64); - /// - /// let mut pd5 = portd.pd5.into_output(&mut portb.ddr).into_pwm(&mut timer0); - /// let mut pd6 = portd.pd6.into_output(&mut portd.ddr).into_pwm(&mut timer0); - /// - /// pd5.set_duty(128); - /// pd5.enable(); - /// ``` - pub struct Timer0Pwm { - timer: crate::pac::TC0, - init: |tim, prescaler| { - tim.tccr0a.modify(|_, w| w.wgm0().pwm_fast()); - tim.tccr0b.modify(|_, w| match prescaler { - Prescaler::Direct => w.cs0().direct(), - Prescaler::Prescale8 => w.cs0().prescale_8(), - Prescaler::Prescale64 => w.cs0().prescale_64(), - Prescaler::Prescale256 => w.cs0().prescale_256(), - Prescaler::Prescale1024 => w.cs0().prescale_1024(), - }); - }, - pins: { - portd::PD6: { - ocr: ocr0a, - into_pwm: |tim| if enable { - tim.tccr0a.modify(|_, w| w.com0a().match_clear()); - } else { - tim.tccr0a.modify(|_, w| w.com0a().disconnected()); - }, - }, - portd::PD5: { - ocr: ocr0b, - into_pwm: |tim| if enable { - tim.tccr0a.modify(|_, w| w.com0b().match_clear()); - } else { - tim.tccr0a.modify(|_, w| w.com0b().disconnected()); - }, - }, - }, - } -} - -avr_hal_generic::impl_pwm! { - /// Use `TC1` for PWM (pins `PB1`, `PB2`) - /// - /// # Example - /// ``` - /// let mut portb = dp.PORTB.split(); - /// let mut timer1 = Timer1Pwm::new(dp.TC1, pwm::Prescaler::Prescale64); - /// - /// let mut pb1 = portb.pb1.into_output(&mut portb.ddr).into_pwm(&mut timer1); - /// let mut pb2 = portb.pb2.into_output(&mut portb.ddr).into_pwm(&mut timer1); - /// - /// pb1.set_duty(128); - /// pb1.enable(); - /// ``` - pub struct Timer1Pwm { - timer: crate::pac::TC1, - init: |tim, prescaler| { - tim.tccr1a.modify(|_, w| w.wgm1().bits(0b01)); - tim.tccr1b.modify(|_, w| { - w.wgm1().bits(0b01); - match prescaler { - Prescaler::Direct => w.cs1().direct(), - Prescaler::Prescale8 => w.cs1().prescale_8(), - Prescaler::Prescale64 => w.cs1().prescale_64(), - Prescaler::Prescale256 => w.cs1().prescale_256(), - Prescaler::Prescale1024 => w.cs1().prescale_1024(), - } - }); - }, - pins: { - portb::PB1: { - ocr: ocr1a, - into_pwm: |tim| if enable { - tim.tccr1a.modify(|_, w| w.com1a().match_clear()); - } else { - tim.tccr1a.modify(|_, w| w.com1a().disconnected()); - }, - }, - portb::PB2: { - ocr: ocr1b, - into_pwm: |tim| if enable { - tim.tccr1a.modify(|_, w| w.com1b().match_clear()); - } else { - tim.tccr1a.modify(|_, w| w.com1b().disconnected()); - }, - }, - }, - } -} - -avr_hal_generic::impl_pwm! { - /// Use `TC2` for PWM (pins `PB3`, `PD3`) - /// - /// # Example - /// ``` - /// let mut portb = dp.PORTB.split(); - /// let mut portd = dp.PORTD.split(); - /// let mut timer2 = Timer2Pwm::new(dp.TC2, pwm::Prescaler::Prescale64); - /// - /// let mut pb3 = portb.pb3.into_output(&mut portb.ddr).into_pwm(&mut timer2); - /// let mut pd3 = portd.pd3.into_output(&mut portd.ddr).into_pwm(&mut timer2); - /// - /// pb3.set_duty(128); - /// pb3.enable(); - /// ``` - pub struct Timer2Pwm { - timer: crate::pac::TC2, - init: |tim, prescaler| { - tim.tccr2a.modify(|_, w| w.wgm2().pwm_fast()); - tim.tccr2b.modify(|_, w| match prescaler { - Prescaler::Direct => w.cs2().direct(), - Prescaler::Prescale8 => w.cs2().prescale_8(), - Prescaler::Prescale64 => w.cs2().prescale_64(), - Prescaler::Prescale256 => w.cs2().prescale_256(), - Prescaler::Prescale1024 => w.cs2().prescale_1024(), - }); - }, - pins: { - portb::PB3: { - ocr: ocr2a, - into_pwm: |tim| if enable { - tim.tccr2a.modify(|_, w| w.com2a().match_clear()); - } else { - tim.tccr2a.modify(|_, w| w.com2a().disconnected()); - }, - }, - portd::PD3: { - ocr: ocr2b, - into_pwm: |tim| if enable { - tim.tccr2a.modify(|_, w| w.com2b().match_clear()); - } else { - tim.tccr2a.modify(|_, w| w.com2b().disconnected()); - }, - }, - }, - } -} diff --git a/chips/atmega2560-hal/Cargo.toml b/chips/atmega2560-hal/Cargo.toml deleted file mode 100644 index 0423ac258f..0000000000 --- a/chips/atmega2560-hal/Cargo.toml +++ /dev/null @@ -1,15 +0,0 @@ -[package] -name = "atmega2560-hal" -version = "0.1.0" -authors = ["Andrew Dona-Couch "] -edition = "2018" - -[features] -rt = ["avr-device/rt"] - -[dependencies] -avr-hal-generic = { path = "../../avr-hal-generic/" } - -[dependencies.avr-device] -version = "0.3" -features = ["atmega2560"] diff --git a/chips/atmega2560-hal/src/adc.rs b/chips/atmega2560-hal/src/adc.rs deleted file mode 100644 index 76c1563791..0000000000 --- a/chips/atmega2560-hal/src/adc.rs +++ /dev/null @@ -1,87 +0,0 @@ -extern crate avr_hal_generic as avr_hal; - -use crate::port::portf::{PF0, PF1, PF2, PF3, PF4, PF5, PF6, PF7}; -use crate::port::portk::{PK0, PK1, PK2, PK3, PK4, PK5, PK6, PK7}; - -#[doc(hidden)] -#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)] -#[repr(u8)] -pub enum AdcMux { - Adc0 = 0b000000, - Adc1 = 0b000001, - Adc2 = 0b000010, - Adc3 = 0b000011, - Adc4 = 0b000100, - Adc5 = 0b000101, - Adc6 = 0b000110, - Adc7 = 0b000111, - - AdcVbg = 0b011110, - AdcGnd = 0b011111, - - Adc8 = 0b100000, - Adc9 = 0b100001, - Adc10 = 0b100010, - Adc11 = 0b100011, - Adc12 = 0b100100, - Adc13 = 0b100101, - Adc14 = 0b100110, - Adc15 = 0b100111, -} - -avr_hal_generic::impl_adc! { - pub struct Adc { - type ChannelID = AdcMux; - peripheral: crate::pac::ADC, - set_mux: |peripheral, id| { - let id = id as u8; - peripheral.admux.modify(|_, w| w.mux().bits(id & 0x1F)); - // n.b. the high bit of ADMUX[MUX] is in the ADCSRB register - peripheral.adcsrb.modify(|_, w| w.mux5().bit(id & 0x20 != 0)); - }, - pins: { - pf0: (PF0, AdcMux::Adc0, didr0::adc0d), - pf1: (PF1, AdcMux::Adc1, didr0::adc1d), - pf2: (PF2, AdcMux::Adc2, didr0::adc2d), - pf3: (PF3, AdcMux::Adc3, didr0::adc3d), - pf4: (PF4, AdcMux::Adc4, didr0::adc4d), - pf5: (PF5, AdcMux::Adc5, didr0::adc5d), - pf6: (PF6, AdcMux::Adc6, didr0::adc6d), - pf7: (PF7, AdcMux::Adc7, didr0::adc7d), - pk0: (PK0, AdcMux::Adc8, didr2::adc8d), - pk1: (PK1, AdcMux::Adc9, didr2::adc9d), - pk2: (PK2, AdcMux::Adc10, didr2::adc10d), - pk3: (PK3, AdcMux::Adc11, didr2::adc11d), - pk4: (PK4, AdcMux::Adc12, didr2::adc12d), - pk5: (PK5, AdcMux::Adc13, didr2::adc13d), - pk6: (PK6, AdcMux::Adc14, didr2::adc14d), - pk7: (PK7, AdcMux::Adc15, didr2::adc15d), - } - } -} - -/// Additional channels -/// -/// This module contains ADC channels, additional to the direct pin channels. -pub mod channel { - use super::AdcMux; - use avr_hal_generic::hal::adc::Channel; - - /// Channel for the _Bandgap Reference Voltage_ - pub struct Vbg; - impl Channel for Vbg { - type ID = AdcMux; - fn channel() -> Self::ID { - AdcMux::AdcVbg - } - } - - /// Channel for _GND_ - pub struct Gnd; - impl Channel for Gnd { - type ID = AdcMux; - fn channel() -> Self::ID { - AdcMux::AdcGnd - } - } -} diff --git a/chips/atmega2560-hal/src/lib.rs b/chips/atmega2560-hal/src/lib.rs deleted file mode 100644 index 72f175e2a5..0000000000 --- a/chips/atmega2560-hal/src/lib.rs +++ /dev/null @@ -1,37 +0,0 @@ -#![no_std] - -/// Reexport of `atmega2560` from `avr-device` -pub use avr_device::atmega2560 as pac; - -/// See [`avr_device::entry`](https://docs.rs/avr-device/latest/avr_device/attr.entry.html). -#[cfg(feature = "rt")] -pub use avr_device::entry; - -pub use avr_hal_generic::clock; -pub use avr_hal_generic::delay; - -pub mod adc; -pub mod port; -pub mod pwm; -pub mod spi; -pub mod usart; - -pub mod prelude { - pub use avr_hal_generic::prelude::*; - pub use crate::port::PortExt as _; -} - -pub mod i2c { - use crate::port::portd; - pub use avr_hal_generic::i2c::*; - - avr_hal_generic::impl_twi_i2c! { - pub struct I2c { - peripheral: crate::pac::TWI, - pins: { - sda: portd::PD1, - scl: portd::PD0, - }, - } - } -} diff --git a/chips/atmega2560-hal/src/port.rs b/chips/atmega2560-hal/src/port.rs deleted file mode 100644 index 2160046ebe..0000000000 --- a/chips/atmega2560-hal/src/port.rs +++ /dev/null @@ -1,269 +0,0 @@ -//! Digital IO Implementations -//! -//! For a detailed explanation, refer to the [general Digital IO documentation][1]. -//! -//! [1]: ../../avr_hal_generic/port/index.html - -pub use avr_hal_generic::port::mode; - -pub trait PortExt { - type Parts; - - fn split(self) -> Self::Parts; -} - -avr_hal_generic::impl_generic_pin! { - pub enum Pin { - A(crate::pac::PORTA, porta, pina, ddra), - B(crate::pac::PORTB, portb, pinb, ddrb), - C(crate::pac::PORTC, portc, pinc, ddrc), - D(crate::pac::PORTD, portd, pind, ddrd), - E(crate::pac::PORTE, porte, pine, ddre), - F(crate::pac::PORTF, portf, pinf, ddrf), - G(crate::pac::PORTG, portg, ping, ddrg), - H(crate::pac::PORTH, porth, pinh, ddrh), - J(crate::pac::PORTJ, portj, pinj, ddrj), - K(crate::pac::PORTK, portk, pink, ddrk), - L(crate::pac::PORTL, portl, pinl, ddrl), - } -} - -avr_hal_generic::impl_port! { - pub mod porta { - #[port_ext] - use super::PortExt; - - #[generic_pin] - use Pin::A; - - impl PortExt for crate::pac::PORTA { - regs: (pina, ddra, porta), - pa0: (PA0, 0), - pa1: (PA1, 1), - pa2: (PA2, 2), - pa3: (PA3, 3), - pa4: (PA4, 4), - pa5: (PA5, 5), - pa6: (PA6, 6), - pa7: (PA7, 7), - } - } -} - -avr_hal_generic::impl_port! { - pub mod portb { - #[port_ext] - use super::PortExt; - - #[generic_pin] - use Pin::B; - - impl PortExt for crate::pac::PORTB { - regs: (pinb, ddrb, portb), - pb0: (PB0, 0), - pb1: (PB1, 1), - pb2: (PB2, 2), - pb3: (PB3, 3), - pb4: (PB4, 4), - pb5: (PB5, 5), - pb6: (PB6, 6), - pb7: (PB7, 7), - } - } -} - -avr_hal_generic::impl_port! { - pub mod portc { - #[port_ext] - use super::PortExt; - - #[generic_pin] - use Pin::C; - - impl PortExt for crate::pac::PORTC { - regs: (pinc, ddrc, portc), - pc0: (PC0, 0), - pc1: (PC1, 1), - pc2: (PC2, 2), - pc3: (PC3, 3), - pc4: (PC4, 4), - pc5: (PC5, 5), - pc6: (PC6, 6), - pc7: (PC7, 7), - } - } -} - -avr_hal_generic::impl_port! { - pub mod portd { - #[port_ext] - use super::PortExt; - - #[generic_pin] - use Pin::D; - - impl PortExt for crate::pac::PORTD { - regs: (pind, ddrd, portd), - pd0: (PD0, 0), - pd1: (PD1, 1), - pd2: (PD2, 2), - pd3: (PD3, 3), - pd4: (PD4, 4), - pd5: (PD5, 5), - pd6: (PD6, 6), - pd7: (PD7, 7), - } - } -} - -avr_hal_generic::impl_port! { - pub mod porte { - #[port_ext] - use super::PortExt; - - #[generic_pin] - use Pin::E; - - impl PortExt for crate::pac::PORTE { - regs: (pine, ddre, porte), - pe0: (PE0, 0), - pe1: (PE1, 1), - pe2: (PE2, 2), - pe3: (PE3, 3), - pe4: (PE4, 4), - pe5: (PE5, 5), - pe6: (PE6, 6), - pe7: (PE7, 7), - } - } -} - -avr_hal_generic::impl_port! { - pub mod portf { - #[port_ext] - use super::PortExt; - - #[generic_pin] - use Pin::F; - - impl PortExt for crate::pac::PORTF { - regs: (pinf, ddrf, portf), - pf0: (PF0, 0), - pf1: (PF1, 1), - pf2: (PF2, 2), - pf3: (PF3, 3), - pf4: (PF4, 4), - pf5: (PF5, 5), - pf6: (PF6, 6), - pf7: (PF7, 7), - } - } -} - -avr_hal_generic::impl_port! { - pub mod portg { - #[port_ext] - use super::PortExt; - - #[generic_pin] - use Pin::G; - - impl PortExt for crate::pac::PORTG { - regs: (ping, ddrg, portg), - pg0: (PG0, 0), - pg1: (PG1, 1), - pg2: (PG2, 2), - pg3: (PG3, 3), - pg4: (PG4, 4), - pg5: (PG5, 5), - } - } -} - -avr_hal_generic::impl_port! { - pub mod porth { - #[port_ext] - use super::PortExt; - - #[generic_pin] - use Pin::H; - - impl PortExt for crate::pac::PORTH { - regs: (pinh, ddrh, porth), - ph0: (PH0, 0), - ph1: (PH1, 1), - ph2: (PH2, 2), - ph3: (PH3, 3), - ph4: (PH4, 4), - ph5: (PH5, 5), - ph6: (PH6, 6), - ph7: (PH7, 7), - } - } -} - -avr_hal_generic::impl_port! { - pub mod portj { - #[port_ext] - use super::PortExt; - - #[generic_pin] - use Pin::J; - - impl PortExt for crate::pac::PORTJ { - regs: (pinj, ddrj, portj), - pj0: (PJ0, 0), - pj1: (PJ1, 1), - pj2: (PJ2, 2), - pj3: (PJ3, 3), - pj4: (PJ4, 4), - pj5: (PJ5, 5), - pj6: (PJ6, 6), - pj7: (PJ7, 7), - } - } -} - -avr_hal_generic::impl_port! { - pub mod portk { - #[port_ext] - use super::PortExt; - - #[generic_pin] - use Pin::K; - - impl PortExt for crate::pac::PORTK { - regs: (pink, ddrk, portk), - pk0: (PK0, 0), - pk1: (PK1, 1), - pk2: (PK2, 2), - pk3: (PK3, 3), - pk4: (PK4, 4), - pk5: (PK5, 5), - pk6: (PK6, 6), - pk7: (PK7, 7), - } - } -} - -avr_hal_generic::impl_port! { - pub mod portl { - #[port_ext] - use super::PortExt; - - #[generic_pin] - use Pin::L; - - impl PortExt for crate::pac::PORTL { - regs: (pinl, ddrl, portl), - pl0: (PL0, 0), - pl1: (PL1, 1), - pl2: (PL2, 2), - pl3: (PL3, 3), - pl4: (PL4, 4), - pl5: (PL5, 5), - pl6: (PL6, 6), - pl7: (PL7, 7), - } - } -} diff --git a/chips/atmega2560-hal/src/pwm.rs b/chips/atmega2560-hal/src/pwm.rs deleted file mode 100644 index bd2ba27e4e..0000000000 --- a/chips/atmega2560-hal/src/pwm.rs +++ /dev/null @@ -1,375 +0,0 @@ -//! Support for PWM pins -//! -//! The 6 timers of ATmega2560 can be used for PWM on certain pins. -//! The PWM methods are from `embedded_hal::PwmPin`; -//! -//! # Example -//! ``` -//! let mut portd = dp.PORTD.split(); -//! let mut timer0 = Timer0Pwm::new(dp.TC0, pwm::Prescaler::Prescale64); -//! -//! let mut pb7 = portb.pb7.into_output(&mut portb.ddr).into_pwm(&mut timer0); -//! -//! pb7.set_duty(128); -//! pb7.enable(); -//! ``` -//! -//! Here is an overview of pins and which timer they work with: -//! -//! | Pin | Conversion Method | Alternate Conversion Method | -//! | --- | --- | --- | -//! | `PB4` | `.into_pwm(&mut timer2)` | | -//! | `PB5` | `.into_pwm(&mut timer1)` | | -//! | `PB6` | `.into_pwm(&mut timer1)` | | -//! | `PB7` | `.into_pwm(&mut timer0)` | `.into_pwm1(&mut timer1)` | -//! | `PE3` | `.into_pwm(&mut timer3)` | | -//! | `PE4` | `.into_pwm(&mut timer3)` | | -//! | `PE5` | `.into_pwm(&mut timer3)` | | -//! | `PG5` | `.into_pwm(&mut timer0)` | | -//! | `PH3` | `.into_pwm(&mut timer4)` | | -//! | `PH4` | `.into_pwm(&mut timer4)` | | -//! | `PH5` | `.into_pwm(&mut timer4)` | | -//! | `PH6` | `.into_pwm(&mut timer2)` | | -//! | `PL3` | `.into_pwm(&mut timer5)` | | -//! | `PL4` | `.into_pwm(&mut timer5)` | | -//! | `PL5` | `.into_pwm(&mut timer5)` | | - -use crate::port::{portb, porte, portg, porth, portl}; -pub use avr_hal_generic::pwm::*; - -avr_hal_generic::impl_pwm! { - /// Use `TC0` for PWM (pins `PB7`, `PG5`) - /// - /// # Example - /// ``` - /// let mut portb = dp.PORTB.split(); - /// let mut portg = dp.PORTG.split(); - /// let mut timer0 = Timer0Pwm::new(dp.TC0, pwm::Prescaler::Prescale64); - /// - /// let mut pb7 = portb.pb7.into_output(&mut portb.ddr).into_pwm(&mut timer0); - /// let mut pg5 = portg.pg5.into_output(&mut portg.ddr).into_pwm(&mut timer0); - /// - /// pb7.set_duty(128); - /// pb7.enable(); - /// ``` - pub struct Timer0Pwm { - timer: crate::pac::TC0, - init: |tim, prescaler| { - tim.tccr0a.modify(|_, w| w.wgm0().pwm_fast()); - tim.tccr0b.modify(|_, w| match prescaler { - Prescaler::Direct => w.cs0().direct(), - Prescaler::Prescale8 => w.cs0().prescale_8(), - Prescaler::Prescale64 => w.cs0().prescale_64(), - Prescaler::Prescale256 => w.cs0().prescale_256(), - Prescaler::Prescale1024 => w.cs0().prescale_1024(), - }); - }, - pins: { - portb::PB7: { - ocr: ocr0a, - into_pwm: |tim| if enable { - tim.tccr0a.modify(|_, w| w.com0a().match_clear()); - } else { - tim.tccr0a.modify(|_, w| w.com0a().disconnected()); - }, - }, - portg::PG5: { - ocr: ocr0b, - into_pwm: |tim| if enable { - tim.tccr0a.modify(|_, w| w.com0b().match_clear()); - } else { - tim.tccr0a.modify(|_, w| w.com0b().disconnected()); - }, - }, - }, - } -} - -avr_hal_generic::impl_pwm! { - /// Use `TC1` for PWM (pins `PB5`, `PB6`, `PB7`) - /// - /// # Example - /// ``` - /// let mut portb = dp.PORTB.split(); - /// let mut timer1 = Timer1Pwm::new(dp.TC1, pwm::Prescaler::Prescale64); - /// - /// let mut pb5 = portb.pb5.into_output(&mut portb.ddr).into_pwm(&mut timer1); - /// let mut pb6 = portb.pb6.into_output(&mut portb.ddr).into_pwm(&mut timer1); - /// let mut pb7 = portb.pb7.into_output(&mut portb.ddr).into_pwm1(&mut timer1); - /// - /// pb5.set_duty(128); - /// pb5.enable(); - /// ``` - /// - /// **Note**: For `PB7` the method is called `into_pwm1()`! - pub struct Timer1Pwm { - timer: crate::pac::TC1, - init: |tim, prescaler| { - tim.tccr1a.modify(|_, w| w.wgm1().bits(0b01)); - tim.tccr1b.modify(|_, w| { - w.wgm1().bits(0b01); - match prescaler { - Prescaler::Direct => w.cs1().direct(), - Prescaler::Prescale8 => w.cs1().prescale_8(), - Prescaler::Prescale64 => w.cs1().prescale_64(), - Prescaler::Prescale256 => w.cs1().prescale_256(), - Prescaler::Prescale1024 => w.cs1().prescale_1024(), - } - }); - }, - pins: { - portb::PB5: { - ocr: ocr1a, - into_pwm: |tim| if enable { - tim.tccr1a.modify(|_, w| w.com1a().match_clear()); - } else { - tim.tccr1a.modify(|_, w| w.com1a().disconnected()); - }, - }, - portb::PB6: { - ocr: ocr1b, - into_pwm: |tim| if enable { - tim.tccr1a.modify(|_, w| w.com1b().match_clear()); - } else { - tim.tccr1a.modify(|_, w| w.com1b().disconnected()); - }, - }, - portb::PB7: { - ocr: ocr1c, - into_pwm1: |tim| if enable { - tim.tccr1a.modify(|_, w| w.com1c().match_clear()); - } else { - tim.tccr1a.modify(|_, w| w.com1c().disconnected()); - }, - }, - }, - } -} - -avr_hal_generic::impl_pwm! { - /// Use `TC2` for PWM (pins `PB4`, `PH6`) - /// - /// # Example - /// ``` - /// let mut portb = dp.PORTB.split(); - /// let mut porth = dp.PORTH.split(); - /// let mut timer2 = Timer2Pwm::new(dp.TC2, pwm::Prescaler::Prescale64); - /// - /// let mut pb4 = portb.into_output(&mut portb.ddr).into_pwm(&mut timer2); - /// let mut ph6 = porth.into_output(&mut porth.ddr).into_pwm(&mut timer2); - /// - /// pb4.set_duty(128); - /// pb4.enable(); - /// ``` - pub struct Timer2Pwm { - timer: crate::pac::TC2, - init: |tim, prescaler| { - tim.tccr2a.modify(|_, w| w.wgm2().bits(0b01)); - tim.tccr2b.modify(|_, w| { - w.wgm22().clear_bit(); - match prescaler { - Prescaler::Direct => w.cs2().direct(), - Prescaler::Prescale8 => w.cs2().prescale_8(), - Prescaler::Prescale64 => w.cs2().prescale_64(), - Prescaler::Prescale256 => w.cs2().prescale_256(), - Prescaler::Prescale1024 => w.cs2().prescale_1024(), - } - }); - }, - pins: { - portb::PB4: { - ocr: ocr2a, - into_pwm: |tim| if enable { - tim.tccr2a.modify(|_, w| w.com2a().match_clear()); - } else { - tim.tccr2a.modify(|_, w| w.com2a().disconnected()); - }, - }, - porth::PH6: { - ocr: ocr2b, - into_pwm: |tim| if enable { - tim.tccr2a.modify(|_, w| w.com2b().match_clear()); - } else { - tim.tccr2a.modify(|_, w| w.com2b().disconnected()); - }, - }, - }, - } -} - -avr_hal_generic::impl_pwm! { - /// Use `TC3` for PWM (pins `PE3`, `PE4`, `PE5`) - /// - /// # Example - /// ``` - /// let mut porte = dp.PORTE.split(); - /// let mut timer3 = Timer3Pwm::new(dp.TC3, pwm::Prescaler::Prescale64); - /// - /// let mut pe3 = porte.pe3.into_output(&mut porte.ddr).into_pwm(&mut timer3); - /// let mut pe4 = porte.pe4.into_output(&mut porte.ddr).into_pwm(&mut timer3); - /// let mut pe5 = porte.pe5.into_output(&mut porte.ddr).into_pwm(&mut timer3); - /// - /// pe3.set_duty(128); - /// pe3.enable(); - /// ``` - pub struct Timer3Pwm { - timer: crate::pac::TC3, - init: |tim, prescaler| { - tim.tccr3a.modify(|_, w| w.wgm3().bits(0b01)); - tim.tccr3b.modify(|_, w| { - w.wgm3().bits(0b01); - match prescaler { - Prescaler::Direct => w.cs3().direct(), - Prescaler::Prescale8 => w.cs3().prescale_8(), - Prescaler::Prescale64 => w.cs3().prescale_64(), - Prescaler::Prescale256 => w.cs3().prescale_256(), - Prescaler::Prescale1024 => w.cs3().prescale_1024(), - } - }); - }, - pins: { - porte::PE3: { - ocr: ocr3a, - into_pwm: |tim| if enable { - tim.tccr3a.modify(|_, w| w.com3a().match_clear()); - } else { - tim.tccr3a.modify(|_, w| w.com3a().disconnected()); - }, - }, - porte::PE4: { - ocr: ocr3b, - into_pwm: |tim| if enable { - tim.tccr3a.modify(|_, w| w.com3b().match_clear()); - } else { - tim.tccr3a.modify(|_, w| w.com3b().disconnected()); - }, - }, - porte::PE5: { - ocr: ocr3c, - into_pwm: |tim| if enable { - tim.tccr3a.modify(|_, w| w.com3c().match_clear()); - } else { - tim.tccr3a.modify(|_, w| w.com3c().disconnected()); - }, - }, - }, - } -} - -avr_hal_generic::impl_pwm! { - /// Use `TC4` for PWM (pins `PH3`, `PH4`, `PH5`) - /// - /// # Example - /// ``` - /// let mut porth = dp.PORTH.split(); - /// let mut timer4 = Timer4Pwm::new(dp.TC4, pwm::Prescaler::Prescale64); - /// - /// let mut ph3 = porth.ph3.into_output(&mut porth.ddr).into_pwm(&mut timer4); - /// let mut ph4 = porth.ph4.into_output(&mut porth.ddr).into_pwm(&mut timer4); - /// let mut ph5 = porth.ph5.into_output(&mut porth.ddr).into_pwm(&mut timer4); - /// - /// ph3.set_duty(128); - /// ph3.enable(); - /// ``` - pub struct Timer4Pwm { - timer: crate::pac::TC4, - init: |tim, prescaler| { - tim.tccr4a.modify(|_, w| w.wgm4().bits(0b01)); - tim.tccr4b.modify(|_, w| { - w.wgm4().bits(0b01); - match prescaler { - Prescaler::Direct => w.cs4().direct(), - Prescaler::Prescale8 => w.cs4().prescale_8(), - Prescaler::Prescale64 => w.cs4().prescale_64(), - Prescaler::Prescale256 => w.cs4().prescale_256(), - Prescaler::Prescale1024 => w.cs4().prescale_1024(), - } - }); - }, - pins: { - porth::PH3: { - ocr: ocr4a, - into_pwm: |tim| if enable { - tim.tccr4a.modify(|_, w| w.com4a().match_clear()); - } else { - tim.tccr4a.modify(|_, w| w.com4a().disconnected()); - }, - }, - porth::PH4: { - ocr: ocr4b, - into_pwm: |tim| if enable { - tim.tccr4a.modify(|_, w| w.com4b().match_clear()); - } else { - tim.tccr4a.modify(|_, w| w.com4b().disconnected()); - }, - }, - porth::PH5: { - ocr: ocr4c, - into_pwm: |tim| if enable { - tim.tccr4a.modify(|_, w| w.com4c().match_clear()); - } else { - tim.tccr4a.modify(|_, w| w.com4c().disconnected()); - }, - }, - }, - } -} - -avr_hal_generic::impl_pwm! { - /// Use `TC5` for PWM (pins `PL3`, `PL4`, `PL5`) - /// - /// # Example - /// ``` - /// let mut portl = dp.PORTL.split(); - /// let mut timer5 = Timer5Pwm::new(dp.TC5, pwm::Prescaler::Prescale64); - /// - /// let mut pl3 = portl.pl3.into_output(&mut portl.ddr).into_pwm(&mut timer5); - /// let mut pl4 = portl.pl4.into_output(&mut portl.ddr).into_pwm(&mut timer5); - /// let mut pl5 = portl.pl5.into_output(&mut portl.ddr).into_pwm(&mut timer5); - /// - /// pl3.set_duty(128); - /// pl3.enable(); - /// ``` - pub struct Timer5Pwm { - timer: crate::pac::TC5, - init: |tim, prescaler| { - tim.tccr5a.modify(|_, w| w.wgm5().bits(0b01)); - tim.tccr5b.modify(|_, w| { - w.wgm5().bits(0b01); - match prescaler { - Prescaler::Direct => w.cs5().direct(), - Prescaler::Prescale8 => w.cs5().prescale_8(), - Prescaler::Prescale64 => w.cs5().prescale_64(), - Prescaler::Prescale256 => w.cs5().prescale_256(), - Prescaler::Prescale1024 => w.cs5().prescale_1024(), - } - }); - }, - pins: { - portl::PL3: { - ocr: ocr5a, - into_pwm: |tim| if enable { - tim.tccr5a.modify(|_, w| w.com5a().match_clear()); - } else { - tim.tccr5a.modify(|_, w| w.com5a().disconnected()); - }, - }, - portl::PL4: { - ocr: ocr5b, - into_pwm: |tim| if enable { - tim.tccr5a.modify(|_, w| w.com5b().match_clear()); - } else { - tim.tccr5a.modify(|_, w| w.com5b().disconnected()); - }, - }, - portl::PL5: { - ocr: ocr5c, - into_pwm: |tim| if enable { - tim.tccr5a.modify(|_, w| w.com5c().match_clear()); - } else { - tim.tccr5a.modify(|_, w| w.com5c().disconnected()); - }, - }, - }, - } -} diff --git a/chips/atmega2560-hal/src/spi.rs b/chips/atmega2560-hal/src/spi.rs deleted file mode 100644 index 63d0d7bbf9..0000000000 --- a/chips/atmega2560-hal/src/spi.rs +++ /dev/null @@ -1,41 +0,0 @@ -//! Implementation of the Rust Embedded-HAL SPI FullDuplex trait for AVR. -//! -//! The interface can be instantiated with the `new` method, and used directly -//! or passed into a driver. Example usage: -//! -//! ``` -//! // create SPI interface -//! let (mut spi, mut cs) = Spi::new( -//! dp.SPI,// SPI peripheral -//! pins.d52.into_output(&mut pins.ddr),// SCLK -//! pins.d51.into_output(&mut pins.ddr),// MOSI output pin -//! pins.d50.into_pull_up_input(&mut pins.ddr),// MISO input pin -//! pins.d53.into_output(&mut pins.ddr),// CS pin -//! Settings::default(), -//! ); -//! -//! // Send a byte -//! let sent = 0b10101010; -//! spi.send(sent).unwrap(); -//! let response = spi.read().unwrap(); -//! ``` -//! In the example above, all of the settings are left at the default. You can -//! also instantiate a Settings object with the other options available. - -extern crate avr_hal_generic as avr_hal; - -pub use avr_hal_generic::spi::*; -use crate::port::portb; - - -avr_hal_generic::impl_spi! { - pub struct Spi { - peripheral: crate::pac::SPI, - pins: { - sclk: portb::PB1, - mosi: portb::PB2, - miso: portb::PB3, - cs: portb::PB0, - } - } -} diff --git a/chips/atmega2560-hal/src/usart.rs b/chips/atmega2560-hal/src/usart.rs deleted file mode 100644 index e46bea87b8..0000000000 --- a/chips/atmega2560-hal/src/usart.rs +++ /dev/null @@ -1,55 +0,0 @@ -use crate::port::porte; -use crate::port::portd; -use crate::port::porth; -use crate::port::portj; -pub use avr_hal_generic::usart::*; - -pub type Usart0 = Usart< - crate::pac::USART0, - porte::PE0>, - porte::PE1, - CLOCK, ->; -pub type Usart1 = Usart< - crate::pac::USART1, - portd::PD2>, - portd::PD3, - CLOCK, ->; -pub type Usart2 = Usart< - crate::pac::USART2, - porth::PH0>, - porth::PH1, - CLOCK, ->; -pub type Usart3 = Usart< - crate::pac::USART3, - portj::PJ0>, - portj::PJ1, - CLOCK, ->; - -avr_hal_generic::impl_usart_traditional! { - peripheral: crate::pac::USART0, - register_suffix: 0, - rx: porte::PE0, - tx: porte::PE1, -} -avr_hal_generic::impl_usart_traditional! { - peripheral: crate::pac::USART1, - register_suffix: 1, - rx: portd::PD2, - tx: portd::PD3, -} -avr_hal_generic::impl_usart_traditional! { - peripheral: crate::pac::USART2, - register_suffix: 2, - rx: porth::PH0, - tx: porth::PH1, -} -avr_hal_generic::impl_usart_traditional! { - peripheral: crate::pac::USART3, - register_suffix: 3, - rx: portj::PJ0, - tx: portj::PJ1, -} diff --git a/chips/atmega328p-hal/Cargo.toml b/chips/atmega328p-hal/Cargo.toml deleted file mode 100644 index cff267139f..0000000000 --- a/chips/atmega328p-hal/Cargo.toml +++ /dev/null @@ -1,19 +0,0 @@ -[package] -name = "atmega328p-hal" -version = "0.1.0" -authors = ["Jonah Dahlquist "] -edition = "2018" - -[features] -rt = ["avr-device/rt"] -# Package exposes the ADC6 and ADC7 pins (only 32TQFP, 32MLF, 32UFBGA) -adc-pins = [] -device-selected = [] -atmega328p = ["avr-device/atmega328p", "device-selected"] -atmega328pb = ["avr-device/atmega328pb", "device-selected"] - -[dependencies] -avr-hal-generic = { path = "../../avr-hal-generic/" } - -[dependencies.avr-device] -version = "0.3" diff --git a/chips/atmega328p-hal/src/adc.rs b/chips/atmega328p-hal/src/adc.rs deleted file mode 100644 index 080ae6e0c2..0000000000 --- a/chips/atmega328p-hal/src/adc.rs +++ /dev/null @@ -1,76 +0,0 @@ -extern crate avr_hal_generic as avr_hal; - -use crate::port::portc::{PC0, PC1, PC2, PC3, PC4, PC5}; - -use crate::pac::adc::admux::MUX_A; - -avr_hal_generic::impl_adc! { - pub struct Adc { - type ChannelID = MUX_A; - peripheral: crate::pac::ADC, - set_mux: |peripheral, id| { - peripheral.admux.modify(|_, w| w.mux().variant(id)); - }, - pins: { - pc0: (PC0, MUX_A::ADC0, didr0::adc0d), - pc1: (PC1, MUX_A::ADC1, didr0::adc1d), - pc2: (PC2, MUX_A::ADC2, didr0::adc2d), - pc3: (PC3, MUX_A::ADC3, didr0::adc3d), - pc4: (PC4, MUX_A::ADC4, didr0::adc4d), - pc5: (PC5, MUX_A::ADC5, didr0::adc5d), - } - } -} - -/// Additional channels -/// -/// This module contains ADC channels, additional to the direct pin channels. -pub mod channel { - use avr_hal_generic::hal::adc::Channel; - use crate::pac::adc::admux::MUX_A; - - /// Channel for `ADC6` pin. - /// - /// This pin is not available in all ATmega328P packages (only 32TQFP, 32MLF, 32UFBGA). If you - /// are using one of them, enable the `adc-pins` feature to make them available. - #[cfg(feature = "adc-pins")] - pub struct ADC6; - #[cfg(feature = "adc-pins")] - impl Channel for ADC6 { - type ID = MUX_A; - fn channel() -> Self::ID { MUX_A::ADC6 } - } - - /// Channel for `ADC7` pin. - /// - /// This pin is not available in all ATmega328P packages (only 32TQFP, 32MLF, 32UFBGA). If you - /// are using one of them, enable the `adc-pins` feature to make them available. - #[cfg(feature = "adc-pins")] - pub struct ADC7; - #[cfg(feature = "adc-pins")] - impl Channel for ADC7 { - type ID = MUX_A; - fn channel() -> Self::ID { MUX_A::ADC7 } - } - - /// Channel for the _Bandgap Reference Voltage_ - pub struct Vbg; - impl Channel for Vbg { - type ID = MUX_A; - fn channel() -> Self::ID { MUX_A::ADC_VBG } - } - - /// Channel for _GND_ - pub struct Gnd; - impl Channel for Gnd { - type ID = MUX_A; - fn channel() -> Self::ID { MUX_A::ADC_GND } - } - - /// Channel for the built-in _Temperature Sensor_ - pub struct Temperature; - impl Channel for Temperature { - type ID = MUX_A; - fn channel() -> Self::ID { MUX_A::TEMPSENS } - } -} diff --git a/chips/atmega328p-hal/src/lib.rs b/chips/atmega328p-hal/src/lib.rs deleted file mode 100644 index 5535999658..0000000000 --- a/chips/atmega328p-hal/src/lib.rs +++ /dev/null @@ -1,223 +0,0 @@ -#![no_std] - -#[cfg(not(feature = "device-selected"))] -compile_error!( - "This crate requires you to specify your target chip as a feature. - - Please select one of the following - - * atmega328p - * atmega328pb - " -); - - -/// Reexport of `atmega328p` from `avr-device` -#[cfg(feature = "atmega328p")] -pub use avr_device::atmega328p as pac; -/// Reexport of `atmega328pb` from `avr-device` -#[cfg(feature = "atmega328pb")] -pub use avr_device::atmega328pb as pac; - -/// See [`avr_device::entry`](https://docs.rs/avr-device/latest/avr_device/attr.entry.html). -#[cfg(feature = "rt")] -pub use avr_device::entry; - -pub use avr_hal_generic::clock; -pub use avr_hal_generic::delay; - -#[cfg(feature = "device-selected")] -pub mod port; -#[cfg(feature = "device-selected")] -pub mod adc; -#[cfg(feature = "device-selected")] -pub mod pwm; -#[cfg(feature = "device-selected")] -pub mod wdt; - -#[cfg(feature = "device-selected")] -pub mod prelude { - pub use avr_hal_generic::prelude::*; - pub use crate::port::PortExt as _; -} - -#[cfg(feature = "atmega328p")] -/// I2C Bus -pub mod i2c { - use crate::port::portc; - pub use avr_hal_generic::i2c::*; - - avr_hal_generic::impl_twi_i2c! { - /// I2C based on ATmega328P's TWI peripheral - pub struct I2c { - peripheral: crate::pac::TWI, - pins: { - sda: portc::PC4, - scl: portc::PC5, - }, - } - } -} - -#[cfg(feature = "atmega328pb")] -/// I2C Bus -pub mod i2c { - use crate::port::{portc, porte}; - pub use avr_hal_generic::i2c::*; - - avr_hal_generic::impl_twi_i2c! { - /// I2C based on ATmega328P's TWI peripheral - pub struct I2c0 { - peripheral: crate::pac::TWI0, - pins: { - sda: portc::PC4, - scl: portc::PC5, - }, - } - } - - avr_hal_generic::impl_twi_i2c! { - /// I2C based on ATmega328P's TWI peripheral - pub struct I2c1 { - peripheral: crate::pac::TWI1, - pins: { - sda: porte::PE0, - scl: porte::PE1, - }, - } - } -} - -#[cfg(feature = "atmega328p")] -pub mod spi { - //! Implementation of the Rust Embedded-HAL SPI FullDuplex trait for AVR. - //! - //! The interface can be instantiated with the `new` method, and used directly - //! or passed into a driver. Example usage: - //! - //! ``` - //! // create SPI interface - //! let (mut spi, mut cs) = Spi::new( - //! dp.SPI,// SPI peripheral - //! pins.d13.into_output(&mut pins.ddr),// SCLK - //! pins.d11.into_output(&mut pins.ddr),// MOSI output pin - //! pins.d12.into_pull_up_input(&mut pins.ddr),// MISO input pin - //! pins.d10.into_output(&mut pins.ddr),// CS pin - //! Settings::default(), - //! ); - //! - //! // Send a byte - //! let sent = 0b10101010; - //! spi.send(sent).unwrap(); - //! let response = spi.read().unwrap(); - //! ``` - //! In the example above, all of the settings are left at the default. You can - //! also instantiate a Settings object with the other options available. - - use crate::port::portb; - pub use avr_hal_generic::spi::*; - - avr_hal_generic::impl_spi! { - pub struct Spi { - peripheral: crate::pac::SPI, - pins: { - sclk: portb::PB5, - mosi: portb::PB3, - miso: portb::PB4, - cs: portb::PB2, - } - } - } -} - -#[cfg(feature = "atmega328pb")] -pub mod spi { - //! Implementation of the Rust Embedded-HAL SPI FullDuplex trait for AVR. - //! - //! The interface can be instantiated with the `new` method, and used directly - //! or passed into a driver. Example usage: - //! - //! ``` - //! // create SPI interface - //! let (mut spi, mut cs) = Spi0::new( - //! dp.SPI,// SPI peripheral - //! pins.d13.into_output(&mut pins.ddr),// SCLK - //! pins.d11.into_output(&mut pins.ddr),// MOSI output pin - //! pins.d12.into_pull_up_input(&mut pins.ddr),// MISO input pin - //! pins.d10.into_output(&mut pins.ddr),// CS pin - //! Settings::default(), - //! ); - //! - //! // Send a byte - //! let sent = 0b10101010; - //! spi.send(sent).unwrap(); - //! let response = spi.read().unwrap(); - //! ``` - //! In the example above, all of the settings are left at the default. You can - //! also instantiate a Settings object with the other options available. - - use crate::port::{portb, portc, porte}; - pub use avr_hal_generic::spi::*; - - avr_hal_generic::impl_spi! { - pub struct Spi0 { - peripheral: crate::pac::SPI0, - pins: { - sclk: portb::PB5, - mosi: portb::PB3, - miso: portb::PB4, - cs: portb::PB2, - } - } - pub struct ChipSelectSpi0; - } - - avr_hal_generic::impl_spi! { - pub struct Spi1 { - peripheral: crate::pac::SPI1, - pins: { - sclk: portc::PC1, - mosi: porte::PE3, - miso: portc::PC0, - cs: porte::PE2, - } - } - pub struct ChipSelectSpi1; - } -} - -/// Serial interface using USART -#[cfg(feature = "device-selected")] -pub mod usart { - #[allow(unused_imports)] - use crate::port::{portb, portd}; - pub use avr_hal_generic::usart::*; - - pub type Usart0 = Usart< - crate::pac::USART0, - portd::PD0>, - portd::PD1, - CLOCK, - >; - #[cfg(feature = "atmega328pb")] - pub type Usart1 = Usart< - crate::pac::USART1, - portb::PB4>, - portb::PB3, - CLOCK, - >; - - avr_hal_generic::impl_usart_traditional! { - peripheral: crate::pac::USART0, - register_suffix: 0, - rx: portd::PD0, - tx: portd::PD1, - } - #[cfg(feature = "atmega328pb")] - avr_hal_generic::impl_usart_traditional! { - peripheral: crate::pac::USART1, - register_suffix: 1, - rx: portb::PB4, - tx: portb::PB3, - } -} diff --git a/chips/atmega328p-hal/src/port.rs b/chips/atmega328p-hal/src/port.rs deleted file mode 100644 index 8b3117ffed..0000000000 --- a/chips/atmega328p-hal/src/port.rs +++ /dev/null @@ -1,117 +0,0 @@ -//! Digital IO Implementations -//! -//! For a detailed explanation, refer to the [general Digital IO documentation][1]. -//! -//! [1]: ../../avr_hal_generic/port/index.html - -pub use avr_hal_generic::port::mode; - -pub trait PortExt { - type Parts; - - fn split(self) -> Self::Parts; -} - -#[cfg(feature = "atmega328p")] -avr_hal_generic::impl_generic_pin! { - pub enum Pin { - B(crate::pac::PORTB, portb, pinb, ddrb), - C(crate::pac::PORTC, portc, pinc, ddrc), - D(crate::pac::PORTD, portd, pind, ddrd), - } -} - -#[cfg(feature = "atmega328pb")] -avr_hal_generic::impl_generic_pin! { - pub enum Pin { - B(crate::pac::PORTB, portb, pinb, ddrb), - C(crate::pac::PORTC, portc, pinc, ddrc), - D(crate::pac::PORTD, portd, pind, ddrd), - E(crate::pac::PORTE, porte, pine, ddre), - } -} - - -avr_hal_generic::impl_port! { - pub mod portb { - #[port_ext] - use super::PortExt; - - #[generic_pin] - use Pin::B; - - impl PortExt for crate::pac::PORTB { - regs: (pinb, ddrb, portb), - pb0: (PB0, 0), - pb1: (PB1, 1), - pb2: (PB2, 2), - pb3: (PB3, 3), - pb4: (PB4, 4), - pb5: (PB5, 5), - pb6: (PB6, 6), - pb7: (PB7, 7), - } - } -} - -avr_hal_generic::impl_port! { - pub mod portc { - #[port_ext] - use super::PortExt; - - #[generic_pin] - use Pin::C; - - impl PortExt for crate::pac::PORTC { - regs: (pinc, ddrc, portc), - pc0: (PC0, 0), - pc1: (PC1, 1), - pc2: (PC2, 2), - pc3: (PC3, 3), - pc4: (PC4, 4), - pc5: (PC5, 5), - pc6: (PC6, 6), - } - } -} - -avr_hal_generic::impl_port! { - pub mod portd { - #[port_ext] - use super::PortExt; - - #[generic_pin] - use Pin::D; - - impl PortExt for crate::pac::PORTD { - regs: (pind, ddrd, portd), - pd0: (PD0, 0), - pd1: (PD1, 1), - pd2: (PD2, 2), - pd3: (PD3, 3), - pd4: (PD4, 4), - pd5: (PD5, 5), - pd6: (PD6, 6), - pd7: (PD7, 7), - } - } -} - -#[cfg(feature = "atmega328pb")] -avr_hal_generic::impl_port! { - pub mod porte { - #[port_ext] - use super::PortExt; - - #[generic_pin] - use Pin::E; - - impl PortExt for crate::pac::PORTE { - regs: (pine, ddre, porte), - pe0: (PE0, 0), - pe1: (PE1, 1), - pe2: (PE2, 2), - pe3: (PE3, 3), - } - } -} diff --git a/chips/atmega328p-hal/src/pwm.rs b/chips/atmega328p-hal/src/pwm.rs deleted file mode 100644 index 938b76f3cc..0000000000 --- a/chips/atmega328p-hal/src/pwm.rs +++ /dev/null @@ -1,278 +0,0 @@ -//! Support for PWM pins -//! -//! The 3 timers of ATmega328P can be used for PWM on certain pins. -//! The PWM methods are from `embedded_hal::PwmPin`. -//! -//! # Example -//! ``` -//! let mut portd = dp.PORTD.split(); -//! let mut timer0 = Timer0Pwm::new(dp.TC0, pwm::Prescaler::Prescale64); -//! -//! let mut pd5 = portd.pd5.into_output(&mut portd.ddr).into_pwm(&mut timer0); -//! -//! pd5.set_duty(128); -//! pd5.enable(); -//! ``` -//! -//! Here is an overview of pins and which timer they work with: -//! -//! | Pin | Conversion Method | -//! | --- | --- | -//! | `PB1` | `.into_pwm(&mut timer1)` | -//! | `PB2` | `.into_pwm(&mut timer1)` | -//! | `PB3` | `.into_pwm(&mut timer2)` | -//! | `PD3` | `.into_pwm(&mut timer2)` | -//! | `PD5` | `.into_pwm(&mut timer0)` | -//! | `PD6` | `.into_pwm(&mut timer0)` | - -use crate::port::{portb, portd}; -pub use avr_hal_generic::pwm::*; - -avr_hal_generic::impl_pwm! { - /// Use `TC0` for PWM (pins `PD5`, `PD6`) - /// - /// # Example - /// ``` - /// let mut portd = dp.PORTD.split(); - /// let mut timer0 = Timer0Pwm::new(dp.TC0, pwm::Prescaler::Prescale64); - /// - /// let mut pd5 = portd.pd5.into_output(&mut portd.ddr).into_pwm(&mut timer0); - /// let mut pd6 = portd.pd6.into_output(&mut portd.ddr).into_pwm(&mut timer0); - /// - /// pd5.set_duty(128); - /// pd5.enable(); - /// ``` - pub struct Timer0Pwm { - timer: crate::pac::TC0, - init: |tim, prescaler| { - tim.tccr0a.modify(|_, w| w.wgm0().pwm_fast()); - tim.tccr0b.modify(|_, w| match prescaler { - Prescaler::Direct => w.cs0().direct(), - Prescaler::Prescale8 => w.cs0().prescale_8(), - Prescaler::Prescale64 => w.cs0().prescale_64(), - Prescaler::Prescale256 => w.cs0().prescale_256(), - Prescaler::Prescale1024 => w.cs0().prescale_1024(), - }); - }, - pins: { - portd::PD6: { - ocr: ocr0a, - into_pwm: |tim| if enable { - tim.tccr0a.modify(|_, w| w.com0a().match_clear()); - } else { - tim.tccr0a.modify(|_, w| w.com0a().disconnected()); - }, - }, - portd::PD5: { - ocr: ocr0b, - into_pwm: |tim| if enable { - tim.tccr0a.modify(|_, w| w.com0b().match_clear()); - } else { - tim.tccr0a.modify(|_, w| w.com0b().disconnected()); - }, - }, - }, - } -} - -avr_hal_generic::impl_pwm! { - /// Use `TC1` for PWM (pins `PB1`, `PB2`) - /// - /// # Example - /// ``` - /// let mut portb = dp.PORTB.split(); - /// let mut timer1 = Timer1Pwm::new(dp.TC1, pwm::Prescaler::Prescale64); - /// - /// let mut pb1 = portb.pb1.into_output(&mut portb.ddr).into_pwm(&mut timer1); - /// let mut pb2 = portb.pb2.into_output(&mut portb.ddr).into_pwm(&mut timer1); - /// - /// pb1.set_duty(128); - /// pb1.enable(); - /// ``` - pub struct Timer1Pwm { - timer: crate::pac::TC1, - init: |tim, prescaler| { - tim.tccr1a.modify(|_, w| w.wgm1().bits(0b01)); - tim.tccr1b.modify(|_, w| { - w.wgm1().bits(0b01); - match prescaler { - Prescaler::Direct => w.cs1().direct(), - Prescaler::Prescale8 => w.cs1().prescale_8(), - Prescaler::Prescale64 => w.cs1().prescale_64(), - Prescaler::Prescale256 => w.cs1().prescale_256(), - Prescaler::Prescale1024 => w.cs1().prescale_1024(), - } - }); - }, - pins: { - portb::PB1: { - ocr: ocr1a, - into_pwm: |tim| if enable { - tim.tccr1a.modify(|_, w| w.com1a().match_clear()); - } else { - tim.tccr1a.modify(|_, w| w.com1a().disconnected()); - }, - }, - portb::PB2: { - ocr: ocr1b, - into_pwm: |tim| if enable { - tim.tccr1a.modify(|_, w| w.com1b().match_clear()); - } else { - tim.tccr1a.modify(|_, w| w.com1b().disconnected()); - }, - }, - }, - } -} - -avr_hal_generic::impl_pwm! { - /// Use `TC2` for PWM (pins `PB3`, `PD3`) - /// - /// # Example - /// ``` - /// let mut portb = dp.PORTB.split(); - /// let mut portd = dp.PORTD.split(); - /// let mut timer2 = Timer2Pwm::new(dp.TC2, pwm::Prescaler::Prescale64); - /// - /// let mut pb3 = portb.pb3.into_output(&mut portb.ddr).into_pwm(&mut timer2); - /// let mut pd3 = portd.pd3.into_output(&mut portd.ddr).into_pwm(&mut timer2); - /// - /// pb3.set_duty(128); - /// pb3.enable(); - /// ``` - pub struct Timer2Pwm { - timer: crate::pac::TC2, - init: |tim, prescaler| { - tim.tccr2a.modify(|_, w| w.wgm2().pwm_fast()); - tim.tccr2b.modify(|_, w| match prescaler { - Prescaler::Direct => w.cs2().direct(), - Prescaler::Prescale8 => w.cs2().prescale_8(), - Prescaler::Prescale64 => w.cs2().prescale_64(), - Prescaler::Prescale256 => w.cs2().prescale_256(), - Prescaler::Prescale1024 => w.cs2().prescale_1024(), - }); - }, - pins: { - portb::PB3: { - ocr: ocr2a, - into_pwm: |tim| if enable { - tim.tccr2a.modify(|_, w| w.com2a().match_clear()); - } else { - tim.tccr2a.modify(|_, w| w.com2a().disconnected()); - }, - }, - portd::PD3: { - ocr: ocr2b, - into_pwm: |tim| if enable { - tim.tccr2a.modify(|_, w| w.com2b().match_clear()); - } else { - tim.tccr2a.modify(|_, w| w.com2b().disconnected()); - }, - }, - }, - } -} - -#[cfg(feature = "atmega328pb")] -avr_hal_generic::impl_pwm! { - /// Use `TC3` for PWM (pins `PD0`, `PD2`) - /// - /// # Example - /// ``` - /// let mut portd = dp.PORTD.split(); - /// let mut timer3 = Timer3Pwm::new(dp.TC3, pwm::Prescaler::Prescale64); - /// - /// let mut pb1 = portd.pd1.into_output(&mut portd.ddr).into_pwm(&mut timer3); - /// let mut pb2 = portd.pd2.into_output(&mut portd.ddr).into_pwm(&mut timer3); - /// - /// pd1.set_duty(128); - /// pd1.enable(); - /// ``` - pub struct Timer3Pwm { - timer: crate::pac::TC3, - init: |tim, prescaler| { - tim.tccr3a.modify(|_, w| w.wgm3().bits(0b01)); - tim.tccr3b.modify(|_, w| { - //TODO: Figure out if svdtool can mark this as safe (as for Tc1) - unsafe { w.wgm3().bits(0b01) }; - match prescaler { - Prescaler::Direct => w.cs3().direct(), - Prescaler::Prescale8 => w.cs3().prescale_8(), - Prescaler::Prescale64 => w.cs3().prescale_64(), - Prescaler::Prescale256 => w.cs3().prescale_256(), - Prescaler::Prescale1024 => w.cs3().prescale_1024(), - } - }); - }, - pins: { - portd::PD0: { - ocr: ocr3a, - into_pwm: |tim| if enable { - tim.tccr3a.modify(|_, w| w.com3a().match_clear()); - } else { - tim.tccr3a.modify(|_, w| w.com3a().disconnected()); - }, - }, - portd::PD2: { - ocr: ocr3b, - into_pwm3: |tim| if enable { - tim.tccr3a.modify(|_, w| w.com3b().match_clear()); - } else { - tim.tccr3a.modify(|_, w| w.com3b().disconnected()); - }, - }, - }, - } -} - -#[cfg(feature = "atmega328pb")] -avr_hal_generic::impl_pwm! { - /// Use `TC4` for PWM (pins `PD1`, `PD2`) - /// - /// # Example - /// ``` - /// let mut portd = dp.PORTD.split(); - /// let mut timer4 = Timer4Pwm::new(dp.TC4, pwm::Prescaler::Prescale64); - /// - /// let mut pd1 = portd.pd1.into_output(&mut portd.ddr).into_pwm(&mut timer4); - /// let mut pd2 = portd.pd2.into_output(&mut portd.ddr).into_pwm(&mut timer4); - /// - /// pd1.set_duty(128); - /// pd1.enable(); - /// ``` - pub struct Timer4Pwm { - timer: crate::pac::TC4, - init: |tim, prescaler| { - tim.tccr4a.modify(|_, w| w.wgm4().bits(0b01)); - tim.tccr4b.modify(|_, w| { - //TODO: Figure out if svdtool can mark this as safe (as for Tc1) - unsafe { w.wgm4().bits(0b01) }; - match prescaler { - Prescaler::Direct => w.cs4().direct(), - Prescaler::Prescale8 => w.cs4().prescale_8(), - Prescaler::Prescale64 => w.cs4().prescale_64(), - Prescaler::Prescale256 => w.cs4().prescale_256(), - Prescaler::Prescale1024 => w.cs4().prescale_1024(), - } - }); - }, - pins: { - portd::PD1: { - ocr: ocr4a, - into_pwm: |tim| if enable { - tim.tccr4a.modify(|_, w| w.com4a().match_clear()); - } else { - tim.tccr4a.modify(|_, w| w.com4a().disconnected()); - }, - }, - portd::PD2: { - ocr: ocr4b, - into_pwm4: |tim| if enable { - tim.tccr4a.modify(|_, w| w.com4b().match_clear()); - } else { - tim.tccr4a.modify(|_, w| w.com4b().disconnected()); - }, - }, - }, - } -} diff --git a/chips/atmega328p-hal/src/wdt.rs b/chips/atmega328p-hal/src/wdt.rs deleted file mode 100644 index 4cc928c105..0000000000 --- a/chips/atmega328p-hal/src/wdt.rs +++ /dev/null @@ -1,33 +0,0 @@ -//! WatchDog Timer Implementation - -pub use avr_hal_generic::wdt::*; - -avr_hal_generic::impl_wdt! { - pub enum Timeout { - /// 16 milliseconds - Ms16 { wdpl().cycles_2k_512k() }, - /// 32 milliseconds - Ms32 { wdpl().cycles_4k_1024k() }, - /// 64 milliseconds - Ms64 { wdpl().cycles_8k() }, - /// 125 milliseconds - Ms125 { wdpl().cycles_16k() }, - /// 250 milliseconds - Ms250 { wdpl().cycles_32k() }, - /// 500 milliseconds - Ms500 { wdpl().cycles_64k() }, - /// 1 second - Ms1000 { wdpl().cycles_128k() }, - /// 2 seconds - Ms2000 { wdpl().cycles_256k() }, - /// 4 seconds - Ms4000 { wdph().set_bit().wdpl().cycles_2k_512k() }, - /// 8 seconds - Ms8000 { wdph().set_bit().wdpl().cycles_4k_1024k() }, - } - - pub struct Wdt { - mcu_status_register: crate::pac::cpu::MCUSR, - peripheral: crate::pac::WDT, - } -} diff --git a/chips/atmega32u4-hal/.cargo/config.toml b/chips/atmega32u4-hal/.cargo/config.toml deleted file mode 100644 index 8af9492377..0000000000 --- a/chips/atmega32u4-hal/.cargo/config.toml +++ /dev/null @@ -1,5 +0,0 @@ -[build] -target = "../../avr-specs/avr-atmega32u4.json" - -[unstable] -build-std = ["core"] diff --git a/chips/atmega32u4-hal/Cargo.toml b/chips/atmega32u4-hal/Cargo.toml deleted file mode 100644 index c59040592f..0000000000 --- a/chips/atmega32u4-hal/Cargo.toml +++ /dev/null @@ -1,15 +0,0 @@ -[package] -name = "atmega32u4-hal" -version = "0.1.0" -authors = ["Rahix "] -edition = "2018" - -[features] -rt = ["avr-device/rt"] - -[dependencies] -avr-hal-generic = { path = "../../avr-hal-generic/" } - -[dependencies.avr-device] -version = "0.3" -features = ["atmega32u4"] diff --git a/chips/atmega32u4-hal/src/adc.rs b/chips/atmega32u4-hal/src/adc.rs deleted file mode 100644 index b5f1823434..0000000000 --- a/chips/atmega32u4-hal/src/adc.rs +++ /dev/null @@ -1,84 +0,0 @@ -use crate::port::portb::{PB4, PB5, PB6}; -use crate::port::portd::{PD4, PD6, PD7}; -use crate::port::portf::{PF0, PF1, PF4, PF5, PF6, PF7}; - -pub use avr_hal_generic::adc::*; - -#[doc(hidden)] -#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)] -#[repr(u8)] -pub enum AdcMux { - Adc0 = 0b000000, - Adc1 = 0b000001, - Adc4 = 0b000100, - Adc5 = 0b000101, - Adc6 = 0b000110, - Adc7 = 0b000111, - - AdcVbg = 0b011110, - AdcGnd = 0b011111, - - Adc8 = 0b100000, - Adc9 = 0b100001, - Adc10 = 0b100010, - Adc11 = 0b100011, - Adc12 = 0b100100, - Adc13 = 0b100101, - - AdcTemp = 0b100111, -} - -avr_hal_generic::impl_adc! { - pub struct Adc { - type ChannelID = AdcMux; - peripheral: crate::pac::ADC, - set_mux: |peripheral, id| { - let id = id as u8; - peripheral.admux.modify(|_, w| w.mux().bits(id & 0x1f)); - peripheral.adcsrb.modify(|_, w| w.mux5().bit(id & 0x20 != 0)); - }, - pins: { - pf0: (PF0, AdcMux::Adc0, didr0::adc0d), - pf1: (PF1, AdcMux::Adc1, didr0::adc1d), - pf4: (PF4, AdcMux::Adc4, didr0::adc4d), - pf5: (PF5, AdcMux::Adc5, didr0::adc5d), - pf6: (PF6, AdcMux::Adc6, didr0::adc6d), - pf7: (PF7, AdcMux::Adc7, didr0::adc7d), - pd4: (PD4, AdcMux::Adc8, didr2::adc8d), - pd6: (PD6, AdcMux::Adc9, didr2::adc9d), - pd7: (PD7, AdcMux::Adc10, didr2::adc10d), - pb4: (PB4, AdcMux::Adc11, didr2::adc11d), - pb5: (PB5, AdcMux::Adc12, didr2::adc12d), - pb6: (PB6, AdcMux::Adc13, didr2::adc13d), - } - } -} - -/// Additional channels -/// -/// This module contains ADC channels, additional to the direct pin channels. -pub mod channel { - use avr_hal_generic::hal::adc::Channel; - use super::AdcMux; - - /// Channel for the _Bandgap Reference Voltage_ - pub struct Vbg; - impl Channel for Vbg { - type ID = AdcMux; - fn channel() -> Self::ID { AdcMux::AdcVbg } - } - - /// Channel for _GND_ - pub struct Gnd; - impl Channel for Gnd { - type ID = AdcMux; - fn channel() -> Self::ID { AdcMux::AdcGnd } - } - - /// Channel for the built-in _Temperature Sensor_ - pub struct Temperature; - impl Channel for Temperature { - type ID = AdcMux; - fn channel() -> Self::ID { AdcMux::AdcTemp } - } -} diff --git a/chips/atmega32u4-hal/src/lib.rs b/chips/atmega32u4-hal/src/lib.rs deleted file mode 100644 index f63e90bb39..0000000000 --- a/chips/atmega32u4-hal/src/lib.rs +++ /dev/null @@ -1,99 +0,0 @@ -#![no_std] - -/// Reexport of `atmega32u4` from `avr-device` -pub use avr_device::atmega32u4 as pac; - -/// See [`avr_device::entry`](https://docs.rs/avr-device/latest/avr_device/attr.entry.html). -#[cfg(feature = "rt")] -pub use avr_device::entry; - -pub use avr_hal_generic::clock; -pub use avr_hal_generic::delay; - -pub mod adc; -pub mod port; -pub mod pwm; -pub mod wdt; - -pub mod prelude { - pub use avr_hal_generic::prelude::*; - pub use crate::port::PortExt as _; -} - -/// I2C Bus -pub mod i2c { - use crate::port::portd; - pub use avr_hal_generic::i2c::*; - - avr_hal_generic::impl_twi_i2c! { - /// I2C based on ATmega32U4's TWI peripheral - pub struct I2c { - peripheral: crate::pac::TWI, - pins: { - sda: portd::PD1, - scl: portd::PD0, - }, - } - } -} - -pub mod spi { - //! Implementation of the Rust Embedded-HAL SPI FullDuplex trait for AVR. - //! - //! The interface can be instantiated with the `new` method, and used directly - //! or passed into a driver. Example usage: - //! - //! ``` - //! // create SPI interface - //! let (mut spi, mut cs) = Spi::new( - //! dp.SPI,// SPI peripheral - //! pins.d11.into_output(&mut pins.ddr),// MOSI output pin - //! pins.d12.into_pull_up_input(&mut pins.ddr),// MISO input pin - //! pins.d10.into_output(&mut pins.ddr),// CS pin - //! Settings::default(), - //! ); - //! - //! // Send a byte - //! let sent = 0b10101010; - //! spi.send(sent).unwrap(); - //! let response = spi.read().unwrap(); - //! ``` - //! In the example above, all of the settings are left at the default. You can - //! also instantiate a Settings object with the other options available. - - pub use avr_hal_generic::spi::*; - use crate::port::portb; - - avr_hal_generic::impl_spi! { - pub struct Spi { - peripheral: crate::pac::SPI, - pins: { - sclk: portb::PB1, - mosi: portb::PB2, - miso: portb::PB3, - cs: portb::PB0, - } - } - } -} - -/// Serial interface using USART -pub mod usart { - use crate::port::portd; - pub use avr_hal_generic::usart::*; - - /// Serial interface based on ATmega32U4's USART1 peripheral - pub type Usart1 = Usart< - crate::pac::USART1, - portd::PD2>, - portd::PD3, - CLOCK, - >; - - avr_hal_generic::impl_usart_traditional! { - peripheral: crate::pac::USART1, - register_suffix: 1, - rx: portd::PD2, - tx: portd::PD3, - } -} diff --git a/chips/atmega32u4-hal/src/port.rs b/chips/atmega32u4-hal/src/port.rs deleted file mode 100644 index acc6d1557c..0000000000 --- a/chips/atmega32u4-hal/src/port.rs +++ /dev/null @@ -1,119 +0,0 @@ -//! Digital IO Implementations -//! -//! For a detailed explanation, refer to the [general Digital IO documentation][1]. -//! -//! [1]: ../../avr_hal_generic/port/index.html - -pub use avr_hal_generic::port::mode; - -pub trait PortExt { - type Parts; - - fn split(self) -> Self::Parts; -} - -avr_hal_generic::impl_generic_pin! { - pub enum Pin { - B(crate::pac::PORTB, portb, pinb, ddrb), - C(crate::pac::PORTC, portc, pinc, ddrc), - D(crate::pac::PORTD, portd, pind, ddrd), - E(crate::pac::PORTE, porte, pine, ddre), - F(crate::pac::PORTF, portf, pinf, ddrf), - } -} - -avr_hal_generic::impl_port! { - pub mod portb { - #[port_ext] - use super::PortExt; - - #[generic_pin] - use Pin::B; - - impl PortExt for crate::pac::PORTB { - regs: (pinb, ddrb, portb), - pb0: (PB0, 0), - pb1: (PB1, 1), - pb2: (PB2, 2), - pb3: (PB3, 3), - pb4: (PB4, 4), - pb5: (PB5, 5), - pb6: (PB6, 6), - pb7: (PB7, 7), - } - } -} - -avr_hal_generic::impl_port! { - pub mod portc { - #[port_ext] - use super::PortExt; - - #[generic_pin] - use Pin::C; - - impl PortExt for crate::pac::PORTC { - regs: (pinc, ddrc, portc), - pc6: (PC6, 6), - pc7: (PC7, 7), - } - } -} - -avr_hal_generic::impl_port! { - pub mod portd { - #[port_ext] - use super::PortExt; - - #[generic_pin] - use Pin::D; - - impl PortExt for crate::pac::PORTD { - regs: (pind, ddrd, portd), - pd0: (PD0, 0), - pd1: (PD1, 1), - pd2: (PD2, 2), - pd3: (PD3, 3), - pd4: (PD4, 4), - pd5: (PD5, 5), - pd6: (PD6, 6), - pd7: (PD7, 7), - } - } -} - -avr_hal_generic::impl_port! { - pub mod porte { - #[port_ext] - use super::PortExt; - - #[generic_pin] - use Pin::E; - - impl PortExt for crate::pac::PORTE { - regs: (pine, ddre, porte), - pe2: (PE2, 2), - pe6: (PE6, 6), - } - } -} - -avr_hal_generic::impl_port! { - pub mod portf { - #[port_ext] - use super::PortExt; - - #[generic_pin] - use Pin::F; - - impl PortExt for crate::pac::PORTF { - regs: (pinf, ddrf, portf), - pf0: (PF0, 0), - pf1: (PF1, 1), - pf4: (PF4, 4), - pf5: (PF5, 5), - pf6: (PF6, 6), - pf7: (PF7, 7), - } - } -} diff --git a/chips/atmega32u4-hal/src/pwm.rs b/chips/atmega32u4-hal/src/pwm.rs deleted file mode 100644 index 76f4cc2e6c..0000000000 --- a/chips/atmega32u4-hal/src/pwm.rs +++ /dev/null @@ -1,240 +0,0 @@ -//! Support for PWM pins -//! -//! The 4 timers of ATmega32U4 can be used for PWM on certain pins. -//! The PWM methods are from `embedded_hal::PwmPin`. -//! -//! # Example -//! ``` -//! let mut portb = dp.PORTB.split(); -//! let mut timer1 = Timer1Pwm::new(dp.TC1, pwm::Prescaler::Prescale64); -//! -//! let mut pb5 = portb.pb5.into_output(&mut portb.ddr).into_pwm(&mut timer1); -//! -//! pb5.set_duty(128); -//! pb5.enable(); -//! ``` -//! -//! Here is an overview of pins and which timer they work with: -//! -//! | Pin | Conversion Method | Alternate Conversion Method | -//! | --- | --- | --- | -//! | `PB5` | `.into_pwm(&mut timer1)` | | -//! | `PB6` | `.into_pwm(&mut timer1)` | `.into_pwm4(&mut timer4)` | -//! | `PB7` | `.into_pwm(&mut timer0)` | `.into_pwm1(&mut timer1)` | -//! | `PC6` | `.into_pwm(&mut timer3)` | | -//! | `PC7` | `.into_pwm(&mut timer4)` | | -//! | `PD0` | `.into_pwm(&mut timer0)` | | -//! | `PD7` | `.into_pwm(&mut timer4)` | | - -use crate::port::{portb, portc, portd}; -pub use avr_hal_generic::pwm::*; - -avr_hal_generic::impl_pwm! { - /// Use `TC0` for PWM (pins `PB7`, `PD0`) - /// - /// # Example - /// ``` - /// let mut portb = dp.PORTB.split(); - /// let mut portd = dp.PORTD.split(); - /// let mut timer0 = Timer0Pwm::new(dp.TC0, pwm::Prescaler::Prescale64); - /// - /// let mut pb7 = portb.pb7.into_output(&mut portb.ddr).into_pwm(&mut timer0); - /// let mut pd0 = portd.pd0.into_output(&mut portd.ddr).into_pwm(&mut timer0); - /// - /// pb7.set_duty(128); - /// pb7.enable(); - /// ``` - pub struct Timer0Pwm { - timer: crate::pac::TC0, - init: |tim, prescaler| { - tim.tccr0a.modify(|_, w| w.wgm0().pwm_fast()); - tim.tccr0b.modify(|_, w| match prescaler { - Prescaler::Direct => w.cs0().direct(), - Prescaler::Prescale8 => w.cs0().prescale_8(), - Prescaler::Prescale64 => w.cs0().prescale_64(), - Prescaler::Prescale256 => w.cs0().prescale_256(), - Prescaler::Prescale1024 => w.cs0().prescale_1024(), - }); - }, - pins: { - portb::PB7: { - ocr: ocr0a, - into_pwm: |tim| if enable { - tim.tccr0a.modify(|_, w| w.com0a().match_clear()); - } else { - tim.tccr0a.modify(|_, w| w.com0a().disconnected()); - }, - }, - portd::PD0: { - ocr: ocr0b, - into_pwm: |tim| if enable { - tim.tccr0a.modify(|_, w| w.com0b().match_clear()); - } else { - tim.tccr0a.modify(|_, w| w.com0b().disconnected()); - }, - }, - }, - } -} - -avr_hal_generic::impl_pwm! { - /// Use `TC1` for PWM (pins `PB5`, `PB6`, `PB7`) - /// - /// # Example - /// ``` - /// let mut portb = dp.PORTB.split(); - /// let mut timer1 = Timer1Pwm::new(dp.TC1, pwm::Prescaler::Prescale64); - /// - /// let mut pb5 = portb.pb5.into_output(&mut portb.ddr).into_pwm(&mut timer1); - /// let mut pb6 = portb.pb6.into_output(&mut portb.ddr).into_pwm(&mut timer1); - /// let mut pb7 = portb.pb7.into_output(&mut portb.ddr).into_pwm1(&mut timer1); - /// - /// pb5.set_duty(128); - /// pb5.enable(); - /// ``` - /// - /// **Note**: For `PB7` the method is called `into_pwm1()`! - pub struct Timer1Pwm { - timer: crate::pac::TC1, - init: |tim, prescaler| { - tim.tccr1a.modify(|_, w| w.wgm1().bits(0b01)); - tim.tccr1b.modify(|_, w| { - w.wgm1().bits(0b01); - match prescaler { - Prescaler::Direct => w.cs1().direct(), - Prescaler::Prescale8 => w.cs1().prescale_8(), - Prescaler::Prescale64 => w.cs1().prescale_64(), - Prescaler::Prescale256 => w.cs1().prescale_256(), - Prescaler::Prescale1024 => w.cs1().prescale_1024(), - } - }); - }, - pins: { - portb::PB5: { - ocr: ocr1a, - into_pwm: |tim| if enable { - tim.tccr1a.modify(|_, w| w.com1a().match_clear()); - } else { - tim.tccr1a.modify(|_, w| w.com1a().disconnected()); - }, - }, - portb::PB6: { - ocr: ocr1b, - into_pwm: |tim| if enable { - tim.tccr1a.modify(|_, w| w.com1b().match_clear()); - } else { - tim.tccr1a.modify(|_, w| w.com1b().disconnected()); - }, - }, - portb::PB7: { - ocr: ocr1c, - into_pwm1: |tim| if enable { - tim.tccr1a.modify(|_, w| w.com1c().match_clear()); - } else { - tim.tccr1a.modify(|_, w| w.com1c().disconnected()); - }, - }, - }, - } -} - -avr_hal_generic::impl_pwm! { - /// Use `TC3` for PWM (pin `PC6`) - /// - /// # Example - /// ``` - /// let mut portc = dp.PORTC.split(); - /// let mut timer3 = Timer3Pwm::new(dp.TC3, pwm::Prescaler::Prescale64); - /// - /// let mut pc6 = portc.pc6.into_output(&mut portc.ddr).into_pwm(&mut timer3); - /// - /// pc6.set_duty(128); - /// pc6.enable(); - /// ``` - pub struct Timer3Pwm { - timer: crate::pac::TC3, - init: |tim, prescaler| { - tim.tccr3a.modify(|_, w| w.wgm3().bits(0b01)); - tim.tccr3b.modify(|_, w| { - w.wgm3().bits(0b01); - match prescaler { - Prescaler::Direct => w.cs3().direct(), - Prescaler::Prescale8 => w.cs3().prescale_8(), - Prescaler::Prescale64 => w.cs3().prescale_64(), - Prescaler::Prescale256 => w.cs3().prescale_256(), - Prescaler::Prescale1024 => w.cs3().prescale_1024(), - } - }); - }, - pins: { - portc::PC6: { - ocr: ocr3a, - into_pwm: |tim| if enable { - tim.tccr3a.modify(|_, w| w.com3a().match_clear()); - } else { - tim.tccr3a.modify(|_, w| w.com3a().disconnected()); - }, - }, - }, - } -} - -avr_hal_generic::impl_pwm! { - /// Use `TC4` for PWM (pins `PB6`, `PC7`, `PD7`) - /// - /// # Example - /// ``` - /// let mut portb = dp.PORTB.split(); - /// let mut portc = dp.PORTC.split(); - /// let mut portd = dp.PORTD.split(); - /// let mut timer4 = Timer4Pwm::new(dp.TC4, pwm::Prescaler::Prescale64); - /// - /// let pb6 = portb.pb6.into_output(&mut portb.ddr).into_pwm4(&mut timer4); - /// let pc7 = portc.pc7.into_output(&mut portc.ddr).into_pwm(&mut timer4); - /// let pd7 = portd.pd7.into_output(&mut portd.ddr).into_pwm(&mut timer4); - /// - /// pb6.set_duty(128); - /// pb6.enable(); - /// ``` - /// - /// **Note**: For `PB6` the method is called `into_pwm6()`! - pub struct Timer4Pwm { - timer: crate::pac::TC4, - init: |tim, prescaler| { - tim.tccr4b.modify(|_, w| match prescaler { - Prescaler::Direct => w.cs4().direct(), - Prescaler::Prescale8 => w.cs4().prescale_8(), - Prescaler::Prescale64 => w.cs4().prescale_64(), - Prescaler::Prescale256 => w.cs4().prescale_256(), - Prescaler::Prescale1024 => w.cs4().prescale_1024(), - }); - tim.tccr4d.modify(|_, w| w.wgm4().pwm_fast()); - }, - pins: { - portc::PC7: { - ocr: ocr4a, - into_pwm: |tim| if enable { - tim.tccr4a.modify(|_, w| w.com4a().match_clear().pwm4a().set_bit()); - } else { - tim.tccr4a.modify(|_, w| w.com4a().disconnected().pwm4a().clear_bit()); - }, - }, - portb::PB6: { - ocr: ocr4b, - into_pwm4: |tim| if enable { - tim.tccr4a.modify(|_, w| w.com4b().match_clear().pwm4b().set_bit()); - } else { - tim.tccr4a.modify(|_, w| w.com4b().disconnected().pwm4b().clear_bit()); - }, - }, - portd::PD7: { - ocr: ocr4d, - into_pwm: |tim| if enable { - tim.tccr4c.modify(|_, w| w.com4d().match_clear().pwm4d().set_bit()); - } else { - tim.tccr4c.modify(|_, w| w.com4d().disconnected().pwm4d().clear_bit()); - }, - }, - }, - } -} diff --git a/chips/atmega32u4-hal/src/wdt.rs b/chips/atmega32u4-hal/src/wdt.rs deleted file mode 100644 index 9893ad56da..0000000000 --- a/chips/atmega32u4-hal/src/wdt.rs +++ /dev/null @@ -1,33 +0,0 @@ -//! Watchdog Implementation - -pub use avr_hal_generic::wdt::*; - -avr_hal_generic::impl_wdt! { - pub enum Timeout { - /// 16 milliseconds - Ms16 { wdpl().cycles_2k_512k() }, - /// 32 milliseconds - Ms32 { wdpl().cycles_4k_1024k() }, - /// 64 milliseconds - Ms64 { wdpl().cycles_8k() }, - /// 125 milliseconds - Ms125 { wdpl().cycles_16k() }, - /// 250 milliseconds - Ms250 { wdpl().cycles_32k() }, - /// 500 milliseconds - Ms500 { wdpl().cycles_64k() }, - /// 1 second - Ms1000 { wdpl().cycles_128k() }, - /// 2 seconds - Ms2000 { wdpl().cycles_256k() }, - /// 4 seconds - Ms4000 { wdph().set_bit().wdpl().cycles_2k_512k() }, - /// 8 seconds - Ms8000 { wdph().set_bit().wdpl().cycles_4k_1024k() }, - } - - pub struct Wdt { - mcu_status_register: crate::pac::cpu::MCUSR, - peripheral: crate::pac::WDT, - } -} diff --git a/chips/atmega48p-hal/.cargo/config.toml b/chips/atmega48p-hal/.cargo/config.toml deleted file mode 100644 index ac2d93baa8..0000000000 --- a/chips/atmega48p-hal/.cargo/config.toml +++ /dev/null @@ -1,5 +0,0 @@ -[build] -target = "../../avr-specs/avr-atmega48p.json" - -[unstable] -build-std = ["core"] diff --git a/chips/atmega48p-hal/Cargo.toml b/chips/atmega48p-hal/Cargo.toml deleted file mode 100644 index 66e31b5d1c..0000000000 --- a/chips/atmega48p-hal/Cargo.toml +++ /dev/null @@ -1,15 +0,0 @@ -[package] -name = "atmega48p-hal" -version = "0.1.0" -authors = ["Boris Vinogradov "] -edition = "2018" - -[features] -rt = ["avr-device/rt"] - -[dependencies] -avr-hal-generic = { path = "../../avr-hal-generic/" } - -[dependencies.avr-device] -version = "0.3" -features = ["atmega48p"] diff --git a/chips/atmega48p-hal/src/adc.rs b/chips/atmega48p-hal/src/adc.rs deleted file mode 100644 index fb4b10585c..0000000000 --- a/chips/atmega48p-hal/src/adc.rs +++ /dev/null @@ -1,58 +0,0 @@ -extern crate avr_hal_generic as avr_hal; - -use crate::port::portc::{PC0, PC1, PC2, PC3, PC4, PC5}; - -use crate::pac::adc::admux::MUX_A; - -avr_hal_generic::impl_adc! { - pub struct Adc { - type ChannelID = MUX_A; - peripheral: crate::pac::ADC, - set_mux: |peripheral, id| { - peripheral.admux.modify(|_, w| w.mux().variant(id)); - }, - pins: { - pc0: (PC0, MUX_A::ADC0, didr0::adc0d), - pc1: (PC1, MUX_A::ADC1, didr0::adc1d), - pc2: (PC2, MUX_A::ADC2, didr0::adc2d), - pc3: (PC3, MUX_A::ADC3, didr0::adc3d), - pc4: (PC4, MUX_A::ADC4, didr0::adc4d), - pc5: (PC5, MUX_A::ADC5, didr0::adc5d), - } - } -} - -/// Additional channels -/// -/// This module contains ADC channels, additional to the direct pin channels. -pub mod channel { - use crate::pac::adc::admux::MUX_A; - use avr_hal_generic::hal::adc::Channel; - - /// Channel for the _Bandgap Reference Voltage_ - pub struct Vbg; - impl Channel for Vbg { - type ID = MUX_A; - fn channel() -> Self::ID { - MUX_A::ADC_VBG - } - } - - /// Channel for _GND_ - pub struct Gnd; - impl Channel for Gnd { - type ID = MUX_A; - fn channel() -> Self::ID { - MUX_A::ADC_GND - } - } - - /// Channel for the built-in _Temperature Sensor_ - pub struct Temperature; - impl Channel for Temperature { - type ID = MUX_A; - fn channel() -> Self::ID { - MUX_A::TEMPSENS - } - } -} diff --git a/chips/atmega48p-hal/src/lib.rs b/chips/atmega48p-hal/src/lib.rs deleted file mode 100644 index f2d67c4aef..0000000000 --- a/chips/atmega48p-hal/src/lib.rs +++ /dev/null @@ -1,60 +0,0 @@ -#![no_std] - -/// Reexport of `atmega48p` from `avr-device` -pub use avr_device::atmega48p as pac; - -/// See [`avr_device::entry`](https://docs.rs/avr-device/latest/avr_device/attr.entry.html). -#[cfg(feature = "rt")] -pub use avr_device::entry; - -pub use avr_hal_generic::clock; -pub use avr_hal_generic::delay; - -pub mod port; - -pub mod adc; -pub mod pwm; - -pub mod spi; - -pub mod prelude { - pub use avr_hal_generic::prelude::*; - pub use crate::port::PortExt as _; -} - -/// I2C Bus -pub mod i2c { - use crate::port::portc; - pub use avr_hal_generic::i2c::*; - - avr_hal_generic::impl_twi_i2c! { - /// I2C based on ATmega328P's TWI peripheral - pub struct I2c { - peripheral: crate::pac::TWI, - pins: { - sda: portc::PC4, - scl: portc::PC5, - }, - } - } -} - -/// Serial interface using USART -pub mod usart { - use crate::port::portd; - pub use avr_hal_generic::usart::*; - - pub type Usart0 = Usart< - crate::pac::USART0, - portd::PD0>, - portd::PD1, - CLOCK, - >; - - avr_hal_generic::impl_usart_traditional! { - peripheral: crate::pac::USART0, - register_suffix: 0, - rx: portd::PD0, - tx: portd::PD1, - } -} diff --git a/chips/atmega48p-hal/src/port.rs b/chips/atmega48p-hal/src/port.rs deleted file mode 100644 index 18a7b3b06f..0000000000 --- a/chips/atmega48p-hal/src/port.rs +++ /dev/null @@ -1,86 +0,0 @@ -//! Digital IO Implementations -//! -//! For a detailed explanation, refer to the [general Digital IO documentation][1]. -//! -//! [1]: ../../avr_hal_generic/port/index.html - -pub use avr_hal_generic::port::mode; - -pub trait PortExt { - type Parts; - - fn split(self) -> Self::Parts; -} - -avr_hal_generic::impl_generic_pin! { - pub enum Pin { - B(crate::pac::PORTB, portb, pinb, ddrb), - C(crate::pac::PORTC, portc, pinc, ddrc), - D(crate::pac::PORTD, portd, pind, ddrd), - } -} - -avr_hal_generic::impl_port! { - pub mod portb { - #[port_ext] - use super::PortExt; - - #[generic_pin] - use Pin::B; - - impl PortExt for crate::pac::PORTB { - regs: (pinb, ddrb, portb), - pb0: (PB0, 0), - pb1: (PB1, 1), - pb2: (PB2, 2), - pb3: (PB3, 3), - pb4: (PB4, 4), - pb5: (PB5, 5), - pb6: (PB6, 6), - pb7: (PB7, 7), - } - } -} - -avr_hal_generic::impl_port! { - pub mod portc { - #[port_ext] - use super::PortExt; - - #[generic_pin] - use Pin::C; - - impl PortExt for crate::pac::PORTC { - regs: (pinc, ddrc, portc), - pc0: (PC0, 0), - pc1: (PC1, 1), - pc2: (PC2, 2), - pc3: (PC3, 3), - pc4: (PC4, 4), - pc5: (PC5, 5), - pc6: (PC6, 6), - } - } -} - -avr_hal_generic::impl_port! { - pub mod portd { - #[port_ext] - use super::PortExt; - - #[generic_pin] - use Pin::D; - - impl PortExt for crate::pac::PORTD { - regs: (pind, ddrd, portd), - pd0: (PD0, 0), - pd1: (PD1, 1), - pd2: (PD2, 2), - pd3: (PD3, 3), - pd4: (PD4, 4), - pd5: (PD5, 5), - pd6: (PD6, 6), - pd7: (PD7, 7), - } - } -} diff --git a/chips/atmega48p-hal/src/pwm.rs b/chips/atmega48p-hal/src/pwm.rs deleted file mode 100644 index 389acdba80..0000000000 --- a/chips/atmega48p-hal/src/pwm.rs +++ /dev/null @@ -1,174 +0,0 @@ -//! Support for PWM pins -//! -//! The 3 timers of ATmega48P can be used for PWM on certain pins. -//! The PWM methods are from `embedded_hal::PwmPin`. -//! -//! # Example -//! ``` -//! let mut portd = dp.PORTD.split(); -//! let mut timer0 = Timer0Pwm::new(dp.TC0, pwm::Prescaler::Prescale64); -//! -//! let mut pd5 = portd.pd5.into_output(&mut portd.ddr).into_pwm(&mut timer0); -//! -//! pd5.set_duty(128); -//! pd5.enable(); -//! ``` -//! -//! Here is an overview of pins and which timer they work with: -//! -//! | Pin | Conversion Method | -//! | --- | --- | -//! | `PB1` | `.into_pwm(&mut timer1)` | -//! | `PB2` | `.into_pwm(&mut timer1)` | -//! | `PB3` | `.into_pwm(&mut timer2)` | -//! | `PD3` | `.into_pwm(&mut timer2)` | -//! | `PD5` | `.into_pwm(&mut timer0)` | -//! | `PD6` | `.into_pwm(&mut timer0)` | - -use crate::port::{portb, portd}; -pub use avr_hal_generic::pwm::*; - -avr_hal_generic::impl_pwm! { - /// Use `TC0` for PWM (pins `PD5`, `PD6`) - /// - /// # Example - /// ``` - /// let mut portd = dp.PORTD.split(); - /// let mut timer0 = Timer0Pwm::new(dp.TC0, pwm::Prescaler::Prescale64); - /// - /// let mut pd5 = portd.pd5.into_output(&mut portd.ddr).into_pwm(&mut timer0); - /// let mut pd6 = portd.pd6.into_output(&mut portd.ddr).into_pwm(&mut timer0); - /// - /// pd5.set_duty(128); - /// pd5.enable(); - /// ``` - pub struct Timer0Pwm { - timer: crate::pac::TC0, - init: |tim, prescaler| { - tim.tccr0a.modify(|_, w| w.wgm0().pwm_fast()); - tim.tccr0b.modify(|_, w| match prescaler { - Prescaler::Direct => w.cs0().direct(), - Prescaler::Prescale8 => w.cs0().prescale_8(), - Prescaler::Prescale64 => w.cs0().prescale_64(), - Prescaler::Prescale256 => w.cs0().prescale_256(), - Prescaler::Prescale1024 => w.cs0().prescale_1024(), - }); - }, - pins: { - portd::PD6: { - ocr: ocr0a, - into_pwm: |tim| if enable { - tim.tccr0a.modify(|_, w| w.com0a().match_clear()); - } else { - tim.tccr0a.modify(|_, w| w.com0a().disconnected()); - }, - }, - portd::PD5: { - ocr: ocr0b, - into_pwm: |tim| if enable { - tim.tccr0a.modify(|_, w| w.com0b().match_clear()); - } else { - tim.tccr0a.modify(|_, w| w.com0b().disconnected()); - }, - }, - }, - } -} - -avr_hal_generic::impl_pwm! { - /// Use `TC1` for PWM (pins `PB1`, `PB2`) - /// - /// # Example - /// ``` - /// let mut portb = dp.PORTB.split(); - /// let mut timer1 = Timer1Pwm::new(dp.TC1, pwm::Prescaler::Prescale64); - /// - /// let mut pb1 = portb.pb1.into_output(&mut portb.ddr).into_pwm(&mut timer1); - /// let mut pb2 = portb.pb2.into_output(&mut portb.ddr).into_pwm(&mut timer1); - /// - /// pb1.set_duty(128); - /// pb1.enable(); - /// ``` - pub struct Timer1Pwm { - timer: crate::pac::TC1, - init: |tim, prescaler| { - tim.tccr1a.modify(|_, w| w.wgm1().bits(0b01)); - tim.tccr1b.modify(|_, w| { - w.wgm1().bits(0b01); - match prescaler { - Prescaler::Direct => w.cs1().direct(), - Prescaler::Prescale8 => w.cs1().prescale_8(), - Prescaler::Prescale64 => w.cs1().prescale_64(), - Prescaler::Prescale256 => w.cs1().prescale_256(), - Prescaler::Prescale1024 => w.cs1().prescale_1024(), - } - }); - }, - pins: { - portb::PB1: { - ocr: ocr1a, - into_pwm: |tim| if enable { - tim.tccr1a.modify(|_, w| w.com1a().match_clear()); - } else { - tim.tccr1a.modify(|_, w| w.com1a().disconnected()); - }, - }, - portb::PB2: { - ocr: ocr1b, - into_pwm: |tim| if enable { - tim.tccr1a.modify(|_, w| w.com1b().match_clear()); - } else { - tim.tccr1a.modify(|_, w| w.com1b().disconnected()); - }, - }, - }, - } -} - -avr_hal_generic::impl_pwm! { - /// Use `TC2` for PWM (pins `PB3`, `PD3`) - /// - /// # Example - /// ``` - /// let mut portb = dp.PORTB.split(); - /// let mut portd = dp.PORTD.split(); - /// let mut timer2 = Timer2Pwm::new(dp.TC2, pwm::Prescaler::Prescale64); - /// - /// let mut pb3 = portb.pb3.into_output(&mut portb.ddr).into_pwm(&mut timer2); - /// let mut pd3 = portd.pd3.into_output(&mut portd.ddr).into_pwm(&mut timer2); - /// - /// pb3.set_duty(128); - /// pb3.enable(); - /// ``` - pub struct Timer2Pwm { - timer: crate::pac::TC2, - init: |tim, prescaler| { - tim.tccr2a.modify(|_, w| w.wgm2().pwm_fast()); - tim.tccr2b.modify(|_, w| match prescaler { - Prescaler::Direct => w.cs2().direct(), - Prescaler::Prescale8 => w.cs2().prescale_8(), - Prescaler::Prescale64 => w.cs2().prescale_64(), - Prescaler::Prescale256 => w.cs2().prescale_256(), - Prescaler::Prescale1024 => w.cs2().prescale_1024(), - }); - }, - pins: { - portb::PB3: { - ocr: ocr2a, - into_pwm: |tim| if enable { - tim.tccr2a.modify(|_, w| w.com2a().match_clear()); - } else { - tim.tccr2a.modify(|_, w| w.com2a().disconnected()); - }, - }, - portd::PD3: { - ocr: ocr2b, - into_pwm: |tim| if enable { - tim.tccr2a.modify(|_, w| w.com2b().match_clear()); - } else { - tim.tccr2a.modify(|_, w| w.com2b().disconnected()); - }, - }, - }, - } -} diff --git a/chips/atmega48p-hal/src/spi.rs b/chips/atmega48p-hal/src/spi.rs deleted file mode 100644 index 7c30521672..0000000000 --- a/chips/atmega48p-hal/src/spi.rs +++ /dev/null @@ -1,38 +0,0 @@ -//! Implementation of the Rust Embedded-HAL SPI FullDuplex trait for AVR. -//! -//! The interface can be instantiated with the `new` method, and used directly -//! or passed into a driver. Example usage: -//! -//! ``` -//! // create SPI interface -//! let (mut spi, mut cs) = Spi::new( -//! dp.SPI,// SPI peripheral -//! pins.d13.into_output(&mut pins.ddr),// SCLK -//! pins.d11.into_output(&mut pins.ddr),// MOSI output pin -//! pins.d12.into_pull_up_input(&mut pins.ddr),// MISO input pin -//! pins.d10.into_output(&mut pins.ddr),// CS pin -//! Settings::default(), -//! ); -//! -//! // Send a byte -//! let sent = 0b10101010; -//! spi.send(sent).unwrap(); -//! let response = spi.read().unwrap(); -//! ``` -//! In the example above, all of the settings are left at the default. You can -//! also instantiate a Settings object with the other options available. - -use crate::port::portb; -pub use avr_hal_generic::spi::*; - -avr_hal_generic::impl_spi! { - pub struct Spi { - peripheral: crate::pac::SPI, - pins: { - sclk: portb::PB5, - mosi: portb::PB3, - miso: portb::PB4, - cs: portb::PB2, - } - } -} diff --git a/chips/attiny85-hal/.cargo/config.toml b/chips/attiny85-hal/.cargo/config.toml deleted file mode 100644 index 2c263eb609..0000000000 --- a/chips/attiny85-hal/.cargo/config.toml +++ /dev/null @@ -1,5 +0,0 @@ -[build] -target = "../../avr-specs/avr-attiny85.json" - -[unstable] -build-std = ["core"] diff --git a/chips/attiny85-hal/Cargo.toml b/chips/attiny85-hal/Cargo.toml deleted file mode 100644 index 00838d748e..0000000000 --- a/chips/attiny85-hal/Cargo.toml +++ /dev/null @@ -1,15 +0,0 @@ -[package] -name = "attiny85-hal" -version = "0.1.0" -authors = ["Rahix "] -edition = "2018" - -[features] -rt = ["avr-device/rt"] - -[dependencies] -avr-hal-generic = { path = "../../avr-hal-generic/" } - -[dependencies.avr-device] -version = "0.3" -features = ["attiny85"] diff --git a/chips/attiny85-hal/src/lib.rs b/chips/attiny85-hal/src/lib.rs deleted file mode 100644 index 962479c33c..0000000000 --- a/chips/attiny85-hal/src/lib.rs +++ /dev/null @@ -1,18 +0,0 @@ -#![no_std] - -/// Reexport of `attiny85` from `avr-device` -pub use avr_device::attiny85 as pac; - -/// See [`avr_device::entry`](https://docs.rs/avr-device/latest/avr_device/attr.entry.html). -#[cfg(feature = "rt")] -pub use avr_device::entry; - -pub use avr_hal_generic::clock; -pub use avr_hal_generic::delay; - -pub mod port; - -pub mod prelude { - pub use avr_hal_generic::prelude::*; - pub use crate::port::PortExt as _; -} diff --git a/chips/attiny85-hal/src/port.rs b/chips/attiny85-hal/src/port.rs deleted file mode 100644 index f33fb995f0..0000000000 --- a/chips/attiny85-hal/src/port.rs +++ /dev/null @@ -1,30 +0,0 @@ -//! Digital IO Implementations -//! -//! For a detailed explanation, refer to the [general Digital IO documentation][1]. -//! -//! [1]: ../../avr_hal_generic/port/index.html - -pub use avr_hal_generic::port::mode; - -pub trait PortExt { - type Parts; - - fn split(self) -> Self::Parts; -} - -avr_hal_generic::impl_port! { - pub mod portb { - #[port_ext] - use super::PortExt; - - impl PortExt for crate::pac::PORTB { - regs: (pinb, ddrb, portb), - pb0: (PB0, 0), - pb1: (PB1, 1), - pb2: (PB2, 2), - pb3: (PB3, 3), - pb4: (PB4, 4), - pb5: (PB5, 5), - } - } -} diff --git a/chips/attiny88-hal/.cargo/config.toml b/chips/attiny88-hal/.cargo/config.toml deleted file mode 100644 index cde74612f4..0000000000 --- a/chips/attiny88-hal/.cargo/config.toml +++ /dev/null @@ -1,5 +0,0 @@ -[build] -target = "../../avr-specs/avr-attiny88.json" - -[unstable] -build-std = ["core"] diff --git a/chips/attiny88-hal/Cargo.toml b/chips/attiny88-hal/Cargo.toml deleted file mode 100644 index 5e129d4661..0000000000 --- a/chips/attiny88-hal/Cargo.toml +++ /dev/null @@ -1,15 +0,0 @@ -[package] -name = "attiny88-hal" -version = "0.1.0" -authors = ["Andrew Dona-Couch "] -edition = "2018" - -[features] -rt = ["avr-device/rt"] - -[dependencies] -avr-hal-generic = { path = "../../avr-hal-generic/" } - -[dependencies.avr-device] -version = "0.3" -features = ["attiny88"] diff --git a/chips/attiny88-hal/src/lib.rs b/chips/attiny88-hal/src/lib.rs deleted file mode 100644 index 1f416a47c7..0000000000 --- a/chips/attiny88-hal/src/lib.rs +++ /dev/null @@ -1,37 +0,0 @@ -#![no_std] - -/// Reexport of `attiny88` from `avr-device` -pub use avr_device::attiny88 as pac; - -/// See [`avr_device::entry`](https://docs.rs/avr-device/latest/avr_device/attr.entry.html). -#[cfg(feature = "rt")] -pub use avr_device::entry; - -pub use avr_hal_generic::clock; -pub use avr_hal_generic::delay; - -pub mod port; - -pub mod spi; - -pub mod prelude { - pub use avr_hal_generic::prelude::*; - pub use crate::port::PortExt as _; -} - -/// I2C Bus -pub mod i2c { - use crate::port::portc; - pub use avr_hal_generic::i2c::*; - - avr_hal_generic::impl_twi_i2c! { - /// I2C based on ATtiny88's TWI peripheral - pub struct I2c { - peripheral: crate::pac::TWI, - pins: { - sda: portc::PC4, - scl: portc::PC5, - }, - } - } -} diff --git a/chips/attiny88-hal/src/port.rs b/chips/attiny88-hal/src/port.rs deleted file mode 100644 index 66133c81e0..0000000000 --- a/chips/attiny88-hal/src/port.rs +++ /dev/null @@ -1,106 +0,0 @@ -//! Digital IO Implementations -//! -//! For a detailed explanation, refer to the [general Digital IO documentation][1]. -//! -//! [1]: ../../avr_hal_generic/port/index.html - -pub use avr_hal_generic::port::mode; - -pub trait PortExt { - type Parts; - - fn split(self) -> Self::Parts; -} - -avr_hal_generic::impl_generic_pin! { - pub enum Pin { - A(crate::pac::PORTA, porta, pina, ddra), - B(crate::pac::PORTB, portb, pinb, ddrb), - C(crate::pac::PORTC, portc, pinc, ddrc), - D(crate::pac::PORTD, portd, pind, ddrd), - } -} - -avr_hal_generic::impl_port! { - pub mod porta { - #[port_ext] - use super::PortExt; - - #[generic_pin] - use Pin::A; - - impl PortExt for crate::pac::PORTA { - regs: (pina, ddra, porta), - pa0: (PA0, 0), - pa1: (PA1, 1), - pa2: (PA2, 2), - pa3: (PA3, 3), - } - } -} - -avr_hal_generic::impl_port! { - pub mod portb { - #[port_ext] - use super::PortExt; - - #[generic_pin] - use Pin::B; - - impl PortExt for crate::pac::PORTB { - regs: (pinb, ddrb, portb), - pb0: (PB0, 0), - pb1: (PB1, 1), - pb2: (PB2, 2), - pb3: (PB3, 3), - pb4: (PB4, 4), - pb5: (PB5, 5), - pb6: (PB6, 6), - pb7: (PB7, 7), - } - } -} - -avr_hal_generic::impl_port! { - pub mod portc { - #[port_ext] - use super::PortExt; - - #[generic_pin] - use Pin::C; - - impl PortExt for crate::pac::PORTC { - regs: (pinc, ddrc, portc), - pc0: (PC0, 0), - pc1: (PC1, 1), - pc2: (PC2, 2), - pc3: (PC3, 3), - pc4: (PC4, 4), - pc5: (PC5, 5), - pc6: (PC6, 6), - pc7: (PC7, 7), - } - } -} - -avr_hal_generic::impl_port! { - pub mod portd { - #[port_ext] - use super::PortExt; - - #[generic_pin] - use Pin::D; - - impl PortExt for crate::pac::PORTD { - regs: (pind, ddrd, portd), - pd0: (PD0, 0), - pd1: (PD1, 1), - pd2: (PD2, 2), - pd3: (PD3, 3), - pd4: (PD4, 4), - pd5: (PD5, 5), - pd6: (PD6, 6), - pd7: (PD7, 7), - } - } -} diff --git a/chips/attiny88-hal/src/spi.rs b/chips/attiny88-hal/src/spi.rs deleted file mode 100644 index 9c79b8d7e0..0000000000 --- a/chips/attiny88-hal/src/spi.rs +++ /dev/null @@ -1,38 +0,0 @@ -//! Implementation of the Rust Embedded-HAL SPI FullDuplex trait for AVR. -//! -//! The interface can be instantiated with the `new` method, and used directly -//! or passed into a driver. Example usage: -//! -//! ``` -//! // create SPI interface -//! let (mut spi, mut cs) = Spi::new( -//! dp.SPI,// SPI peripheral -//! portb::PB5.into_output(&mut pins.ddr),// SCLK -//! portb::PB3.into_output(&mut pins.ddr),// MOSI output pin -//! portb::PB4.into_pull_up_input(&mut pins.ddr),// MISO input pin -//! portb::PB2.into_output(&mut pins.ddr),// CS pin -//! Settings::default(), -//! ); -//! -//! // Send a byte -//! let sent = 0b10101010; -//! spi.send(sent).unwrap(); -//! let response = spi.read().unwrap(); -//! ``` -//! In the example above, all of the settings are left at the default. You can -//! also instantiate a Settings object with the other options available. - -use crate::port::portb; -pub use avr_hal_generic::spi::*; - -avr_hal_generic::impl_spi! { - pub struct Spi { - peripheral: crate::pac::SPI, - pins: { - sclk: portb::PB5, - mosi: portb::PB3, - miso: portb::PB4, - cs: portb::PB2, - } - } -} diff --git a/examples/README.md b/examples/README.md new file mode 100644 index 0000000000..c5ece42db1 --- /dev/null +++ b/examples/README.md @@ -0,0 +1,19 @@ +`avr-hal` examples +================== +The subdirectories here contain various examples which demonstrate how to write +firmware using `avr-hal`. Please note that often examples for a different +board can be easily ported to other hardware, so if you can't find something +for your board, look for examples with other hardware as well. + +All examples are ready to use if you have the respective board available. Just +switch to the subdirectory and run an example via cargo. For example: + +```bash +cd examples/arduino-uno + +# Build and run it on a connected board +cargo run --bin uno-blink +``` + +You need to install [`ravedude`](https://crates.io/crates/ravedude) to make +this work. diff --git a/boards/arduino-diecimila/.cargo/config.toml b/examples/arduino-diecimila/.cargo/config.toml similarity index 56% rename from boards/arduino-diecimila/.cargo/config.toml rename to examples/arduino-diecimila/.cargo/config.toml index 7dd47dddac..1b37bfb826 100644 --- a/boards/arduino-diecimila/.cargo/config.toml +++ b/examples/arduino-diecimila/.cargo/config.toml @@ -1,5 +1,8 @@ [build] target = "../../avr-specs/avr-atmega168.json" +[target.'cfg(target_arch = "avr")'] +runner = "ravedude diecimila" + [unstable] build-std = ["core"] diff --git a/examples/arduino-diecimila/Cargo.toml b/examples/arduino-diecimila/Cargo.toml new file mode 100644 index 0000000000..23fdd68316 --- /dev/null +++ b/examples/arduino-diecimila/Cargo.toml @@ -0,0 +1,16 @@ +[package] +name = "arduino-diecimila-examples" +version = "0.0.0" +authors = ["Rahix "] +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-diecimila"] diff --git a/examples/arduino-diecimila/src/bin/diecimila-adc.rs b/examples/arduino-diecimila/src/bin/diecimila-adc.rs new file mode 100644 index 0000000000..46981db87f --- /dev/null +++ b/examples/arduino-diecimila/src/bin/diecimila-adc.rs @@ -0,0 +1,43 @@ +#![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; 6] = [ + 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(), + ]; + + 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); + } +} diff --git a/examples/arduino-diecimila/src/bin/diecimila-blink.rs b/examples/arduino-diecimila/src/bin/diecimila-blink.rs new file mode 100644 index 0000000000..3dac392b1f --- /dev/null +++ b/examples/arduino-diecimila/src/bin/diecimila-blink.rs @@ -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); + } +} diff --git a/examples/arduino-diecimila/src/bin/diecimila-i2cdetect.rs b/examples/arduino-diecimila/src/bin/diecimila-i2cdetect.rs new file mode 100644 index 0000000000..3817016415 --- /dev/null +++ b/examples/arduino-diecimila/src/bin/diecimila-i2cdetect.rs @@ -0,0 +1,28 @@ +#![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.a4.into_pull_up_input(), + pins.a5.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 {} +} diff --git a/examples/arduino-diecimila/src/bin/diecimila-spi-feedback.rs b/examples/arduino-diecimila/src/bin/diecimila-spi-feedback.rs new file mode 100644 index 0000000000..3355684c46 --- /dev/null +++ b/examples/arduino-diecimila/src/bin/diecimila-spi-feedback.rs @@ -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 `~11` to pin `~12`. +//! +//! 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.d13.into_output(), + pins.d11.into_output(), + pins.d12.into_pull_up_input(), + pins.d10.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); + } +} diff --git a/examples/arduino-diecimila/src/bin/diecimila-usart.rs b/examples/arduino-diecimila/src/bin/diecimila-usart.rs new file mode 100644 index 0000000000..aecdd2b8a1 --- /dev/null +++ b/examples/arduino-diecimila/src/bin/diecimila-usart.rs @@ -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 default + let b = nb::block!(serial.read()).void_unwrap(); + + // Answer + ufmt::uwriteln!(&mut serial, "Got {}!\r", b).void_unwrap(); + } +} diff --git a/boards/arduino-leonardo/.cargo/config.toml b/examples/arduino-leonardo/.cargo/config.toml similarity index 79% rename from boards/arduino-leonardo/.cargo/config.toml rename to examples/arduino-leonardo/.cargo/config.toml index c2c7b54e4f..e11a01e9e3 100644 --- a/boards/arduino-leonardo/.cargo/config.toml +++ b/examples/arduino-leonardo/.cargo/config.toml @@ -2,7 +2,7 @@ target = "../../avr-specs/avr-atmega32u4.json" [target.'cfg(target_arch = "avr")'] -runner = "./leonardo-runner.sh" +runner = "ravedude leonardo" [unstable] build-std = ["core"] diff --git a/examples/arduino-leonardo/Cargo.toml b/examples/arduino-leonardo/Cargo.toml new file mode 100644 index 0000000000..72f03c64e7 --- /dev/null +++ b/examples/arduino-leonardo/Cargo.toml @@ -0,0 +1,16 @@ +[package] +name = "arduino-leonardo-examples" +version = "0.0.0" +authors = ["Rahix "] +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-leonardo"] diff --git a/examples/arduino-leonardo/src/bin/leonardo-adc.rs b/examples/arduino-leonardo/src/bin/leonardo-adc.rs new file mode 100644 index 0000000000..3f2344cdfc --- /dev/null +++ b/examples/arduino-leonardo/src/bin/leonardo-adc.rs @@ -0,0 +1,50 @@ +#![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, tmp) = ( + adc.read_blocking(&adc::channel::Vbg), + adc.read_blocking(&adc::channel::Gnd), + adc.read_blocking(&adc::channel::Temperature), + ); + ufmt::uwriteln!(&mut serial, "Vbandgap: {}", vbg).void_unwrap(); + ufmt::uwriteln!(&mut serial, "Ground: {}", gnd).void_unwrap(); + ufmt::uwriteln!(&mut serial, "Temperature: {}", tmp).void_unwrap(); + + let a0 = pins.a0.into_analog_input(&mut adc); + let a1 = pins.a1.into_analog_input(&mut adc); + let a2 = pins.a2.into_analog_input(&mut adc); + let a3 = pins.a3.into_analog_input(&mut adc); + let a4 = pins.a4.into_analog_input(&mut adc); + let a5 = pins.a5.into_analog_input(&mut adc); + + loop { + let values = [ + a0.analog_read(&mut adc), + a1.analog_read(&mut adc), + a2.analog_read(&mut adc), + a3.analog_read(&mut adc), + a4.analog_read(&mut adc), + a5.analog_read(&mut adc), + ]; + + for (i, v) in values.iter().enumerate() { + ufmt::uwrite!(&mut serial, "A{}: {} ", i, v).void_unwrap(); + } + + ufmt::uwriteln!(&mut serial, "").void_unwrap(); + arduino_hal::delay_ms(1000); + } +} diff --git a/examples/arduino-leonardo/src/bin/leonardo-blink.rs b/examples/arduino-leonardo/src/bin/leonardo-blink.rs new file mode 100644 index 0000000000..43c5862e58 --- /dev/null +++ b/examples/arduino-leonardo/src/bin/leonardo-blink.rs @@ -0,0 +1,30 @@ +#![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 leds = [ + pins.led_rx.into_output().downgrade(), + pins.led_tx.into_output().downgrade(), + pins.d13.into_output().downgrade(), + ]; + + // RX & TX LEDs are active low and the LED on D13 is active high. Thus invert LED13 here so + // they are all in the same "state": + leds[0].set_high(); + leds[1].set_high(); + leds[2].set_low(); + + loop { + for i in 0..3 { + leds[i].toggle(); + arduino_hal::delay_ms(100); + leds[i].toggle(); + } + } +} diff --git a/examples/arduino-leonardo/src/bin/leonardo-i2cdetect.rs b/examples/arduino-leonardo/src/bin/leonardo-i2cdetect.rs new file mode 100644 index 0000000000..141e726664 --- /dev/null +++ b/examples/arduino-leonardo/src/bin/leonardo-i2cdetect.rs @@ -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.d2.into_pull_up_input(), + pins.d3.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 {} +} diff --git a/examples/arduino-leonardo/src/bin/leonardo-spi-feedback.rs b/examples/arduino-leonardo/src/bin/leonardo-spi-feedback.rs new file mode 100644 index 0000000000..19b332bdd0 --- /dev/null +++ b/examples/arduino-leonardo/src/bin/leonardo-spi-feedback.rs @@ -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 `~11` to pin `~12`. +//! +//! 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.sck.into_output(), + pins.mosi.into_output(), + pins.miso.into_pull_up_input(), + pins.led_rx.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); + } +} diff --git a/examples/arduino-leonardo/src/bin/leonardo-usart.rs b/examples/arduino-leonardo/src/bin/leonardo-usart.rs new file mode 100644 index 0000000000..9add152c06 --- /dev/null +++ b/examples/arduino-leonardo/src/bin/leonardo-usart.rs @@ -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(); + } +} diff --git a/chips/atmega2560-hal/.cargo/config.toml b/examples/arduino-mega2560/.cargo/config.toml similarity index 53% rename from chips/atmega2560-hal/.cargo/config.toml rename to examples/arduino-mega2560/.cargo/config.toml index 0f2cde0270..b5ee8592cf 100644 --- a/chips/atmega2560-hal/.cargo/config.toml +++ b/examples/arduino-mega2560/.cargo/config.toml @@ -1,5 +1,8 @@ [build] target = "../../avr-specs/avr-atmega2560.json" +[target.'cfg(target_arch = "avr")'] +runner = "ravedude -cb 57600 mega2560" + [unstable] build-std = ["core"] diff --git a/examples/arduino-mega2560/Cargo.toml b/examples/arduino-mega2560/Cargo.toml new file mode 100644 index 0000000000..21b25b0437 --- /dev/null +++ b/examples/arduino-mega2560/Cargo.toml @@ -0,0 +1,16 @@ +[package] +name = "arduino-mega2560-examples" +version = "0.0.0" +authors = ["Rahix "] +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-mega2560"] \ No newline at end of file diff --git a/examples/arduino-mega2560/src/bin/mega2560-adc.rs b/examples/arduino-mega2560/src/bin/mega2560-adc.rs new file mode 100644 index 0000000000..7c9edecd6e --- /dev/null +++ b/examples/arduino-mega2560/src/bin/mega2560-adc.rs @@ -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); + } +} diff --git a/examples/arduino-mega2560/src/bin/mega2560-blink.rs b/examples/arduino-mega2560/src/bin/mega2560-blink.rs new file mode 100644 index 0000000000..3dac392b1f --- /dev/null +++ b/examples/arduino-mega2560/src/bin/mega2560-blink.rs @@ -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); + } +} diff --git a/examples/arduino-mega2560/src/bin/mega2560-i2cdetect.rs b/examples/arduino-mega2560/src/bin/mega2560-i2cdetect.rs new file mode 100644 index 0000000000..a46c95656b --- /dev/null +++ b/examples/arduino-mega2560/src/bin/mega2560-i2cdetect.rs @@ -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 {} +} diff --git a/examples/arduino-mega2560/src/bin/mega2560-spi-feedback.rs b/examples/arduino-mega2560/src/bin/mega2560-spi-feedback.rs new file mode 100644 index 0000000000..197adab9cd --- /dev/null +++ b/examples/arduino-mega2560/src/bin/mega2560-spi-feedback.rs @@ -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 `~11` to pin `~12`. +//! +//! 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); + } +} diff --git a/examples/arduino-mega2560/src/bin/mega2560-usart.rs b/examples/arduino-mega2560/src/bin/mega2560-usart.rs new file mode 100644 index 0000000000..9add152c06 --- /dev/null +++ b/examples/arduino-mega2560/src/bin/mega2560-usart.rs @@ -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(); + } +} diff --git a/examples/arduino-nano/.cargo/config.toml b/examples/arduino-nano/.cargo/config.toml new file mode 100644 index 0000000000..244bf7ba63 --- /dev/null +++ b/examples/arduino-nano/.cargo/config.toml @@ -0,0 +1,8 @@ +[build] +target = "../../avr-specs/avr-atmega328p.json" + +[target.'cfg(target_arch = "avr")'] +runner = "ravedude nano -cb 57600" + +[unstable] +build-std = ["core"] diff --git a/examples/arduino-nano/Cargo.toml b/examples/arduino-nano/Cargo.toml new file mode 100644 index 0000000000..20549a7bba --- /dev/null +++ b/examples/arduino-nano/Cargo.toml @@ -0,0 +1,16 @@ +[package] +name = "arduino-nano-examples" +version = "0.0.0" +authors = ["David R. Morrison "] +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-nano"] diff --git a/examples/arduino-nano/src/bin/nano-adc.rs b/examples/arduino-nano/src/bin/nano-adc.rs new file mode 100644 index 0000000000..36e9a77e5c --- /dev/null +++ b/examples/arduino-nano/src/bin/nano-adc.rs @@ -0,0 +1,58 @@ +#![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, tmp) = ( + adc.read_blocking(&adc::channel::Vbg), + adc.read_blocking(&adc::channel::Gnd), + adc.read_blocking(&adc::channel::Temperature), + ); + ufmt::uwriteln!(&mut serial, "Vbandgap: {}", vbg).void_unwrap(); + ufmt::uwriteln!(&mut serial, "Ground: {}", gnd).void_unwrap(); + ufmt::uwriteln!(&mut serial, "Temperature: {}", tmp).void_unwrap(); + + let a0 = pins.a0.into_analog_input(&mut adc); + let a1 = pins.a1.into_analog_input(&mut adc); + let a2 = pins.a2.into_analog_input(&mut adc); + let a3 = pins.a3.into_analog_input(&mut adc); + let a4 = pins.a4.into_analog_input(&mut adc); + let a5 = pins.a5.into_analog_input(&mut adc); + + loop { + let values = [ + a0.analog_read(&mut adc), + a1.analog_read(&mut adc), + a2.analog_read(&mut adc), + a3.analog_read(&mut adc), + a4.analog_read(&mut adc), + a5.analog_read(&mut adc), + ]; + + for (i, v) in values.iter().enumerate() { + ufmt::uwrite!(&mut serial, "A{}: {} ", i, v).void_unwrap(); + } + + // Arduino Nano has two more ADC pins A6 and A7. Accessing them works a bit different from + // the other pins as they are not normal IO pins. The code below shows how it works. + let (a6, a7) = ( + adc.read_blocking(&adc::channel::ADC6), + adc.read_blocking(&adc::channel::ADC7), + ); + ufmt::uwrite!(&mut serial, "A6: {} A7: {}", a6, a7).void_unwrap(); + + ufmt::uwriteln!(&mut serial, "").void_unwrap(); + arduino_hal::delay_ms(1000); + } +} diff --git a/examples/arduino-nano/src/bin/nano-blink.rs b/examples/arduino-nano/src/bin/nano-blink.rs new file mode 100644 index 0000000000..8650f1274d --- /dev/null +++ b/examples/arduino-nano/src/bin/nano-blink.rs @@ -0,0 +1,25 @@ +#![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); + + // Digital pin 13 is also connected to an onboard LED marked "L" + let mut led = pins.d13.into_output(); + led.set_high(); + + loop { + led.toggle(); + arduino_hal::delay_ms(100); + led.toggle(); + arduino_hal::delay_ms(100); + led.toggle(); + arduino_hal::delay_ms(100); + led.toggle(); + arduino_hal::delay_ms(800); + } +} diff --git a/chips/atmega328p-hal/.cargo/config.toml b/examples/arduino-uno/.cargo/config.toml similarity index 55% rename from chips/atmega328p-hal/.cargo/config.toml rename to examples/arduino-uno/.cargo/config.toml index 6fe8cd07b9..e7a5f7c442 100644 --- a/chips/atmega328p-hal/.cargo/config.toml +++ b/examples/arduino-uno/.cargo/config.toml @@ -1,5 +1,8 @@ [build] target = "../../avr-specs/avr-atmega328p.json" +[target.'cfg(target_arch = "avr")'] +runner = "ravedude uno -cb 57600" + [unstable] build-std = ["core"] diff --git a/examples/arduino-uno/Cargo.toml b/examples/arduino-uno/Cargo.toml new file mode 100644 index 0000000000..864b870e03 --- /dev/null +++ b/examples/arduino-uno/Cargo.toml @@ -0,0 +1,19 @@ +[package] +name = "arduino-uno-examples" +version = "0.0.0" +authors = ["Rahix "] +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-uno"] + +[dependencies.avr-device] +version = "0.3" diff --git a/examples/arduino-uno/src/bin/uno-adc.rs b/examples/arduino-uno/src/bin/uno-adc.rs new file mode 100644 index 0000000000..3f2344cdfc --- /dev/null +++ b/examples/arduino-uno/src/bin/uno-adc.rs @@ -0,0 +1,50 @@ +#![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, tmp) = ( + adc.read_blocking(&adc::channel::Vbg), + adc.read_blocking(&adc::channel::Gnd), + adc.read_blocking(&adc::channel::Temperature), + ); + ufmt::uwriteln!(&mut serial, "Vbandgap: {}", vbg).void_unwrap(); + ufmt::uwriteln!(&mut serial, "Ground: {}", gnd).void_unwrap(); + ufmt::uwriteln!(&mut serial, "Temperature: {}", tmp).void_unwrap(); + + let a0 = pins.a0.into_analog_input(&mut adc); + let a1 = pins.a1.into_analog_input(&mut adc); + let a2 = pins.a2.into_analog_input(&mut adc); + let a3 = pins.a3.into_analog_input(&mut adc); + let a4 = pins.a4.into_analog_input(&mut adc); + let a5 = pins.a5.into_analog_input(&mut adc); + + loop { + let values = [ + a0.analog_read(&mut adc), + a1.analog_read(&mut adc), + a2.analog_read(&mut adc), + a3.analog_read(&mut adc), + a4.analog_read(&mut adc), + a5.analog_read(&mut adc), + ]; + + for (i, v) in values.iter().enumerate() { + ufmt::uwrite!(&mut serial, "A{}: {} ", i, v).void_unwrap(); + } + + ufmt::uwriteln!(&mut serial, "").void_unwrap(); + arduino_hal::delay_ms(1000); + } +} diff --git a/examples/arduino-uno/src/bin/uno-blink.rs b/examples/arduino-uno/src/bin/uno-blink.rs new file mode 100644 index 0000000000..8650f1274d --- /dev/null +++ b/examples/arduino-uno/src/bin/uno-blink.rs @@ -0,0 +1,25 @@ +#![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); + + // Digital pin 13 is also connected to an onboard LED marked "L" + let mut led = pins.d13.into_output(); + led.set_high(); + + loop { + led.toggle(); + arduino_hal::delay_ms(100); + led.toggle(); + arduino_hal::delay_ms(100); + led.toggle(); + arduino_hal::delay_ms(100); + led.toggle(); + arduino_hal::delay_ms(800); + } +} diff --git a/boards/arduino-uno/examples/uno-hc-sr04.rs b/examples/arduino-uno/src/bin/uno-hc-sr04.rs similarity index 67% rename from boards/arduino-uno/examples/uno-hc-sr04.rs rename to examples/arduino-uno/src/bin/uno-hc-sr04.rs index 1f4360a3fa..b0a64491c3 100644 --- a/boards/arduino-uno/examples/uno-hc-sr04.rs +++ b/examples/arduino-uno/src/bin/uno-hc-sr04.rs @@ -1,46 +1,42 @@ +//! Example for using the HC-SR04 ultrasonic distance sensor +//! +//! Sensor Datasheet: https://www.electroschematics.com/hc-sr04-datasheet/ +//! +//! Connections: +//! - TRIG <- D2 +//! - ECHO -> D3 #![no_std] #![no_main] -use arduino_uno::prelude::*; +use arduino_hal::prelude::*; use panic_halt as _; -#[arduino_uno::entry] +#[arduino_hal::entry] fn main() -> ! { - let dp = arduino_uno::Peripherals::take().unwrap(); + 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 delay = arduino_uno::Delay::new(); + let mut trig = pins.d2.into_output(); + let echo = pins.d3; // pin is input by default - let mut pins = arduino_uno::Pins::new(dp.PORTB, dp.PORTC, dp.PORTD); - - let mut serial = arduino_uno::Serial::new( - dp.USART0, - pins.d0, - pins.d1.into_output(&mut pins.ddr), - 57600.into_baudrate(), - ); - - let timer1 = dp.TC1; // Starting and initializing the timer with prescaling 64. // it gives one clock count every 4 µs. // since the clock register size is 16 bits, the timer is full every // 1/(16e6/64)*2^16 ≈ 260 ms + let timer1 = dp.TC1; timer1.tccr1b.write(|w| w.cs1().prescale_64()); - // Sensor used in this example: https://www.electroschematics.com/hc-sr04-datasheet/ - let mut trig = pins.d2.into_output(&mut pins.ddr); - // Pins are floating input by default. - let echo = pins.d3; - 'outer: loop { // the timer is reinitialized with value 0. timer1.tcnt1.write(|w| unsafe { w.bits(0) }); // the trigger must be set to high under 10 µs as per the HC-SR04 datasheet - trig.set_high().void_unwrap(); - delay.delay_us(10u16); - trig.set_low().void_unwrap(); + trig.set_high(); + arduino_hal::delay_us(10); + trig.set_low(); - while echo.is_low().void_unwrap() { + while echo.is_low() { // exiting the loop if the timer has reached 200 ms. // 0.2s/4µs = 50000 if timer1.tcnt1.read().bits() >= 50000 { @@ -57,7 +53,7 @@ fn main() -> ! { timer1.tcnt1.write(|w| unsafe { w.bits(0) }); // Wait for the echo to get low again - while echo.is_high().void_unwrap() {} + while echo.is_high() {} // 1 count == 4 us, so the value is multiplied by 4. // 1/58 ≈ (34000 ms/2)* 1µs diff --git a/examples/arduino-uno/src/bin/uno-i2cdetect.rs b/examples/arduino-uno/src/bin/uno-i2cdetect.rs new file mode 100644 index 0000000000..1184a4b01c --- /dev/null +++ b/examples/arduino-uno/src/bin/uno-i2cdetect.rs @@ -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.a4.into_pull_up_input(), + pins.a5.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 {} +} diff --git a/boards/arduino-uno/examples/uno-millis.rs b/examples/arduino-uno/src/bin/uno-millis.rs similarity index 88% rename from boards/arduino-uno/examples/uno-millis.rs rename to examples/arduino-uno/src/bin/uno-millis.rs index 8274d3ad8c..bc288aba48 100644 --- a/boards/arduino-uno/examples/uno-millis.rs +++ b/examples/arduino-uno/src/bin/uno-millis.rs @@ -10,10 +10,12 @@ #![no_main] #![feature(abi_avr_interrupt)] -use arduino_uno::prelude::*; +use arduino_hal::prelude::*; use core::cell; use panic_halt as _; +use embedded_hal::serial::Read; + // Possible Values: // // ╔═══════════╦══════════════╦═══════════════════╗ @@ -33,7 +35,7 @@ const MILLIS_INCREMENT: u32 = PRESCALER * TIMER_COUNTS / 16000; static MILLIS_COUNTER: avr_device::interrupt::Mutex> = avr_device::interrupt::Mutex::new(cell::Cell::new(0)); -fn millis_init(tc0: arduino_uno::pac::TC0) { +fn millis_init(tc0: arduino_hal::pac::TC0) { // Configure the timer for the above interval (in CTC mode) // and enable its interrupt. tc0.tccr0a.write(|w| w.wgm0().ctc()); @@ -68,18 +70,11 @@ fn millis() -> u32 { // ---------------------------------------------------------------------------- -#[arduino_uno::entry] +#[arduino_hal::entry] fn main() -> ! { - let dp = arduino_uno::Peripherals::take().unwrap(); - - let mut pins = arduino_uno::Pins::new(dp.PORTB, dp.PORTC, dp.PORTD); - - let mut serial = arduino_uno::Serial::new( - dp.USART0, - pins.d0, - pins.d1.into_output(&mut pins.ddr), - 57600.into_baudrate(), - ); + let dp = arduino_hal::Peripherals::take().unwrap(); + let pins = arduino_hal::pins!(dp); + let mut serial = arduino_hal::default_serial!(dp, pins, 57600); millis_init(dp.TC0); @@ -94,3 +89,4 @@ fn main() -> ! { ufmt::uwriteln!(&mut serial, "Got {} after {} ms!\r", b, time).void_unwrap(); } } + diff --git a/examples/arduino-uno/src/bin/uno-panic.rs b/examples/arduino-uno/src/bin/uno-panic.rs new file mode 100644 index 0000000000..3967dec24f --- /dev/null +++ b/examples/arduino-uno/src/bin/uno-panic.rs @@ -0,0 +1,59 @@ +//! Example of a custom panic handler. +//! +//! The panic handler will print out where the panic occurred and then blink the oboard LED rapidly +//! to make the user aware of the problem. +#![no_std] +#![no_main] + +use arduino_hal::prelude::*; + +#[panic_handler] +fn panic(info: &core::panic::PanicInfo) -> ! { + // disable interrupts - firmware has panicked so no ISRs should continue running + avr_device::interrupt::disable(); + + // get the peripherals so we can access serial and the LED. + // + // 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 { arduino_hal::Peripherals::steal() }; + let pins = arduino_hal::pins!(dp); + let mut serial = arduino_hal::default_serial!(dp, pins, 57600); + + // Print out panic location + ufmt::uwriteln!(&mut serial, "Firmware panic!\r").void_unwrap(); + if let Some(loc) = info.location() { + ufmt::uwriteln!( + &mut serial, + " At {}:{}:{}\r", + loc.file(), + loc.line(), + loc.column(), + ) + .void_unwrap(); + } + + // Blink LED rapidly + let mut led = pins.d13.into_output(); + loop { + led.toggle(); + arduino_hal::delay_ms(100); + } +} + +#[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(); + ufmt::uwriteln!(&mut serial, "Panic in 5 seconds!\r").void_unwrap(); + + arduino_hal::delay_ms(5000); + + // Panic messages cannot yet be captured because they rely on core::fmt + // which is way too big for AVR + panic!(); +} diff --git a/boards/arduino-uno/examples/uno-spi-feedback.rs b/examples/arduino-uno/src/bin/uno-spi-feedback.rs similarity index 61% rename from boards/arduino-uno/examples/uno-spi-feedback.rs rename to examples/arduino-uno/src/bin/uno-spi-feedback.rs index a8565c66c0..3355684c46 100644 --- a/boards/arduino-uno/examples/uno-spi-feedback.rs +++ b/examples/arduino-uno/src/bin/uno-spi-feedback.rs @@ -15,30 +15,26 @@ #![no_std] #![no_main] -use arduino_uno::prelude::*; -use arduino_uno::spi; +use arduino_hal::prelude::*; +use arduino_hal::spi; +use embedded_hal::spi::FullDuplex; use panic_halt as _; -#[arduino_uno::entry] +#[arduino_hal::entry] fn main() -> ! { - let dp = arduino_uno::Peripherals::take().unwrap(); + let dp = arduino_hal::Peripherals::take().unwrap(); + let pins = arduino_hal::pins!(dp); - let mut pins = arduino_uno::Pins::new(dp.PORTB, dp.PORTC, dp.PORTD); // set up serial interface for text output - let mut serial = arduino_uno::Serial::new( - dp.USART0, - pins.d0, - pins.d1.into_output(&mut pins.ddr), - 57600.into_baudrate(), - ); + let mut serial = arduino_hal::default_serial!(dp, pins, 57600); // Create SPI interface. - let (mut spi, _) = spi::Spi::new( + let (mut spi, _) = arduino_hal::Spi::new( dp.SPI, - pins.d13.into_output(&mut pins.ddr), - pins.d11.into_output(&mut pins.ddr), - pins.d12.into_pull_up_input(&mut pins.ddr), - pins.d10.into_output(&mut pins.ddr), + pins.d13.into_output(), + pins.d11.into_output(), + pins.d12.into_pull_up_input(), + pins.d10.into_output(), spi::Settings::default(), ); @@ -49,6 +45,6 @@ fn main() -> ! { let data = nb::block!(spi.read()).void_unwrap(); ufmt::uwriteln!(&mut serial, "data: {}\r", data).void_unwrap(); - arduino_uno::delay_ms(1000); + arduino_hal::delay_ms(1000); } } diff --git a/examples/arduino-uno/src/bin/uno-usart.rs b/examples/arduino-uno/src/bin/uno-usart.rs new file mode 100644 index 0000000000..9add152c06 --- /dev/null +++ b/examples/arduino-uno/src/bin/uno-usart.rs @@ -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(); + } +} diff --git a/boards/sparkfun-pro-micro/.cargo/config.toml b/examples/sparkfun-promicro/.cargo/config.toml similarity index 79% rename from boards/sparkfun-pro-micro/.cargo/config.toml rename to examples/sparkfun-promicro/.cargo/config.toml index d3f1f603a7..4c5d2b5453 100644 --- a/boards/sparkfun-pro-micro/.cargo/config.toml +++ b/examples/sparkfun-promicro/.cargo/config.toml @@ -2,7 +2,7 @@ target = "../../avr-specs/avr-atmega32u4.json" [target.'cfg(target_arch = "avr")'] -runner = "./pro-micro-runner.sh" +runner = "ravedude promicro" [unstable] build-std = ["core"] diff --git a/examples/sparkfun-promicro/Cargo.toml b/examples/sparkfun-promicro/Cargo.toml new file mode 100644 index 0000000000..25ec3ae55d --- /dev/null +++ b/examples/sparkfun-promicro/Cargo.toml @@ -0,0 +1,16 @@ +[package] +name = "sparkfun-promicro-examples" +version = "0.0.0" +authors = ["Rahix "] +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 = ["sparkfun-promicro"] diff --git a/examples/sparkfun-promicro/src/bin/promicro-adc.rs b/examples/sparkfun-promicro/src/bin/promicro-adc.rs new file mode 100644 index 0000000000..53d917259a --- /dev/null +++ b/examples/sparkfun-promicro/src/bin/promicro-adc.rs @@ -0,0 +1,46 @@ +#![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, tmp) = ( + adc.read_blocking(&adc::channel::Vbg), + adc.read_blocking(&adc::channel::Gnd), + adc.read_blocking(&adc::channel::Temperature), + ); + ufmt::uwriteln!(&mut serial, "Vbandgap: {}", vbg).void_unwrap(); + ufmt::uwriteln!(&mut serial, "Ground: {}", gnd).void_unwrap(); + ufmt::uwriteln!(&mut serial, "Temperature: {}", tmp).void_unwrap(); + + let a0 = pins.a0.into_analog_input(&mut adc); + let a1 = pins.a1.into_analog_input(&mut adc); + let a2 = pins.a2.into_analog_input(&mut adc); + let a3 = pins.a3.into_analog_input(&mut adc); + + loop { + let values = [ + a0.analog_read(&mut adc), + a1.analog_read(&mut adc), + a2.analog_read(&mut adc), + a3.analog_read(&mut adc), + ]; + + for (i, v) in values.iter().enumerate() { + ufmt::uwrite!(&mut serial, "A{}: {} ", i, v).void_unwrap(); + } + + ufmt::uwriteln!(&mut serial, "").void_unwrap(); + arduino_hal::delay_ms(1000); + } +} diff --git a/examples/sparkfun-promicro/src/bin/promicro-blink.rs b/examples/sparkfun-promicro/src/bin/promicro-blink.rs new file mode 100644 index 0000000000..4ab740c232 --- /dev/null +++ b/examples/sparkfun-promicro/src/bin/promicro-blink.rs @@ -0,0 +1,22 @@ +#![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 led1 = pins.led_rx.into_output(); + let mut led2 = pins.led_tx.into_output(); + + loop { + led1.set_high(); + led2.set_low(); + arduino_hal::delay_ms(300); + led1.set_low(); + led2.set_high(); + arduino_hal::delay_ms(300); + } +} diff --git a/examples/sparkfun-promicro/src/bin/promicro-i2cdetect.rs b/examples/sparkfun-promicro/src/bin/promicro-i2cdetect.rs new file mode 100644 index 0000000000..141e726664 --- /dev/null +++ b/examples/sparkfun-promicro/src/bin/promicro-i2cdetect.rs @@ -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.d2.into_pull_up_input(), + pins.d3.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 {} +} diff --git a/examples/sparkfun-promicro/src/bin/promicro-spi-feedback.rs b/examples/sparkfun-promicro/src/bin/promicro-spi-feedback.rs new file mode 100644 index 0000000000..690e12fa73 --- /dev/null +++ b/examples/sparkfun-promicro/src/bin/promicro-spi-feedback.rs @@ -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 `~14` to pin `~16`. +//! +//! 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.d15.into_output(), + pins.d14.into_output(), + pins.d16.into_pull_up_input(), + pins.led_rx.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); + } +} diff --git a/examples/sparkfun-promicro/src/bin/promicro-usart.rs b/examples/sparkfun-promicro/src/bin/promicro-usart.rs new file mode 100644 index 0000000000..9add152c06 --- /dev/null +++ b/examples/sparkfun-promicro/src/bin/promicro-usart.rs @@ -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(); + } +} diff --git a/boards/arduino-uno/.cargo/config.toml b/examples/trinket-pro/.cargo/config.toml similarity index 79% rename from boards/arduino-uno/.cargo/config.toml rename to examples/trinket-pro/.cargo/config.toml index 39e545baaf..75e8e82883 100644 --- a/boards/arduino-uno/.cargo/config.toml +++ b/examples/trinket-pro/.cargo/config.toml @@ -2,7 +2,7 @@ target = "../../avr-specs/avr-atmega328p.json" [target.'cfg(target_arch = "avr")'] -runner = "./uno-runner.sh" +runner = "ravedude trinket-pro" [unstable] build-std = ["core"] diff --git a/examples/trinket-pro/Cargo.toml b/examples/trinket-pro/Cargo.toml new file mode 100644 index 0000000000..4c160904a5 --- /dev/null +++ b/examples/trinket-pro/Cargo.toml @@ -0,0 +1,14 @@ +[package] +name = "trinket-pro-examples" +version = "0.0.0" +authors = ["Gaute Hope "] +edition = "2018" +publish = false + +[dependencies] +panic-halt = "0.2.0" +embedded-hal = "0.2.3" + +[dependencies.arduino-hal] +path = "../../arduino-hal/" +features = ["trinket-pro"] diff --git a/examples/trinket-pro/src/bin/trinket-pro-blink.rs b/examples/trinket-pro/src/bin/trinket-pro-blink.rs new file mode 100644 index 0000000000..8650f1274d --- /dev/null +++ b/examples/trinket-pro/src/bin/trinket-pro-blink.rs @@ -0,0 +1,25 @@ +#![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); + + // Digital pin 13 is also connected to an onboard LED marked "L" + let mut led = pins.d13.into_output(); + led.set_high(); + + loop { + led.toggle(); + arduino_hal::delay_ms(100); + led.toggle(); + arduino_hal::delay_ms(100); + led.toggle(); + arduino_hal::delay_ms(100); + led.toggle(); + arduino_hal::delay_ms(800); + } +} diff --git a/mcu/atmega-hal/Cargo.toml b/mcu/atmega-hal/Cargo.toml new file mode 100644 index 0000000000..594221c3b8 --- /dev/null +++ b/mcu/atmega-hal/Cargo.toml @@ -0,0 +1,34 @@ +[package] +name = "atmega-hal" +version = "0.1.0" +authors = ["Rahix "] +edition = "2018" + +[features] +rt = ["avr-device/rt"] +device-selected = [] +enable-extra-adc = [] +atmega48p = ["avr-device/atmega48p", "device-selected"] +atmega168 = ["avr-device/atmega168", "device-selected"] +atmega328p = ["avr-device/atmega328p", "device-selected"] +atmega328pb = ["avr-device/atmega328pb", "device-selected"] +atmega32u4 = ["avr-device/atmega32u4", "device-selected"] +atmega2560 = ["avr-device/atmega2560", "device-selected"] +atmega1280 = ["avr-device/atmega1280", "device-selected"] + +# Allow certain downstream crates to overwrite the device selection error by themselves. +disable-device-selection-error = [] + +[dependencies] +avr-hal-generic = { path = "../../avr-hal-generic/" } + +[dependencies.avr-device] +version = "0.3" + +# Because this crate has its own check that at least one device is selected, we +# can safely "circumvent" the check in `avr-device`. +# +# Why would we want that? Otherwise, as `avr-device` is compiled first, its +# error will be shown and ours won't which leads to a degraded user experience +# as the displayed error message does not really tell what needs to be done... +features = ["device-selected"] diff --git a/mcu/atmega-hal/src/adc.rs b/mcu/atmega-hal/src/adc.rs new file mode 100644 index 0000000000..d089b9ab0a --- /dev/null +++ b/mcu/atmega-hal/src/adc.rs @@ -0,0 +1,168 @@ +//! Analog-to-Digital Converter + +use crate::port; +pub use avr_hal_generic::adc::{AdcChannel, AdcOps, AdcSettings, ClockDivider, ReferenceVoltage}; + +/// Check the [`avr_hal_generic::adc::Adc`] documentation. +pub type Adc = avr_hal_generic::adc::Adc; + +/// Check the [`avr_hal_generic::adc::Channel`] documentation. +pub type Channel = avr_hal_generic::adc::Channel; + +/// Additional channels +/// +/// Some channels are not directly connected to pins. This module provides types which can be used +/// to access them. +/// +/// # Example +/// ``` +/// let dp = atmega_hal::Peripherals::take().unwrap(); +/// let mut adc = atmega_hal::Adc::new(dp.ADC, Default::default()); +/// +/// let value = adc.read_blocking(&channel::Vbg); +/// ``` +pub mod channel { + #[cfg(all( + any( + feature = "atmega168", + feature = "atmega328p", + feature = "atmega328pb", + feature = "atmega48p", + ), + feature = "enable-extra-adc", + ))] + pub struct ADC6; + #[cfg(all( + any( + feature = "atmega168", + feature = "atmega328p", + feature = "atmega328pb", + feature = "atmega48p" + ), + feature = "enable-extra-adc", + ))] + pub struct ADC7; + #[cfg(any( + feature = "atmega1280", + feature = "atmega168", + feature = "atmega2560", + feature = "atmega328p", + feature = "atmega328pb", + feature = "atmega32u4", + feature = "atmega48p", + ))] + pub struct Vbg; + #[cfg(any( + feature = "atmega1280", + feature = "atmega168", + feature = "atmega2560", + feature = "atmega328p", + feature = "atmega328pb", + feature = "atmega32u4", + feature = "atmega48p", + ))] + pub struct Gnd; + #[cfg(any( + feature = "atmega328p", + feature = "atmega328pb", + feature = "atmega32u4", + feature = "atmega48p", + ))] + pub struct Temperature; +} + +#[cfg(any( + feature = "atmega168", + feature = "atmega328p", + feature = "atmega328pb", + feature = "atmega48p", +))] +avr_hal_generic::impl_adc! { + hal: crate::Atmega, + peripheral: crate::pac::ADC, + channel_id: crate::pac::adc::admux::MUX_A, + set_channel: |peripheral, id| { + peripheral.admux.modify(|_, w| w.mux().variant(id)); + }, + pins: { + port::PC0: (crate::pac::adc::admux::MUX_A::ADC0, didr0::adc0d), + port::PC1: (crate::pac::adc::admux::MUX_A::ADC1, didr0::adc1d), + port::PC2: (crate::pac::adc::admux::MUX_A::ADC2, didr0::adc2d), + port::PC3: (crate::pac::adc::admux::MUX_A::ADC3, didr0::adc3d), + port::PC4: (crate::pac::adc::admux::MUX_A::ADC4, didr0::adc4d), + port::PC5: (crate::pac::adc::admux::MUX_A::ADC5, didr0::adc5d), + }, + channels: { + #[cfg(feature = "enable-extra-adc")] + channel::ADC6: crate::pac::adc::admux::MUX_A::ADC6, + #[cfg(feature = "enable-extra-adc")] + channel::ADC7: crate::pac::adc::admux::MUX_A::ADC7, + channel::Vbg: crate::pac::adc::admux::MUX_A::ADC_VBG, + channel::Gnd: crate::pac::adc::admux::MUX_A::ADC_GND, + #[cfg(any(feature = "atmega328p", feature = "atmega328pb", feature = "atmega48p"))] + channel::Temperature: crate::pac::adc::admux::MUX_A::TEMPSENS, + }, +} + +#[cfg(feature = "atmega32u4")] +avr_hal_generic::impl_adc! { + hal: crate::Atmega, + peripheral: crate::pac::ADC, + channel_id: u8, + set_channel: |peripheral, id| { + peripheral.admux.modify(|_, w| w.mux().bits(id & 0x1f)); + peripheral.adcsrb.modify(|_, w| w.mux5().bit(id & 0x20 != 0)); + }, + pins: { + port::PF0: (0b000000, didr0::adc0d), + port::PF1: (0b000001, didr0::adc1d), + port::PF4: (0b000100, didr0::adc4d), + port::PF5: (0b000101, didr0::adc5d), + port::PF6: (0b000110, didr0::adc6d), + port::PF7: (0b000111, didr0::adc7d), + port::PD4: (0b100000, didr2::adc8d), + port::PD6: (0b100001, didr2::adc9d), + port::PD7: (0b100010, didr2::adc10d), + port::PB4: (0b100011, didr2::adc11d), + port::PB5: (0b100100, didr2::adc12d), + port::PB6: (0b100101, didr2::adc13d), + }, + channels: { + channel::Vbg: 0b011110, + channel::Gnd: 0b011111, + channel::Temperature: 0b100111, + }, +} + +#[cfg(any(feature = "atmega2560", feature = "atmega1280"))] +avr_hal_generic::impl_adc! { + hal: crate::Atmega, + peripheral: crate::pac::ADC, + channel_id: u8, + set_channel: |peripheral, id| { + peripheral.admux.modify(|_, w| w.mux().bits(id & 0x1f)); + peripheral.adcsrb.modify(|_, w| w.mux5().bit(id & 0x20 != 0)); + }, + pins: { + port::PF0: (0b000000, didr0::adc0d), + port::PF1: (0b000001, didr0::adc1d), + port::PF2: (0b000010, didr0::adc2d), + port::PF3: (0b000011, didr0::adc3d), + port::PF4: (0b000100, didr0::adc4d), + port::PF5: (0b000101, didr0::adc5d), + port::PF6: (0b000110, didr0::adc6d), + port::PF7: (0b000111, didr0::adc7d), + port::PK0: (0b100000, didr2::adc8d), + port::PK1: (0b100001, didr2::adc9d), + port::PK2: (0b100010, didr2::adc10d), + port::PK3: (0b100011, didr2::adc11d), + port::PK4: (0b100100, didr2::adc12d), + port::PK5: (0b100101, didr2::adc13d), + port::PK6: (0b100110, didr2::adc14d), + port::PK7: (0b100111, didr2::adc15d), + }, + channels: { + channel::Vbg: 0b011110, + channel::Gnd: 0b011111, + }, +} diff --git a/mcu/atmega-hal/src/i2c.rs b/mcu/atmega-hal/src/i2c.rs new file mode 100644 index 0000000000..d10394220f --- /dev/null +++ b/mcu/atmega-hal/src/i2c.rs @@ -0,0 +1,66 @@ +#[allow(unused_imports)] +use crate::port; +pub use avr_hal_generic::i2c::*; + +#[cfg(any(feature = "atmega1280", feature = "atmega2560", feature = "atmega32u4"))] +pub type I2c = avr_hal_generic::i2c::I2c< + crate::Atmega, + crate::pac::TWI, + port::Pin, + port::Pin, + CLOCK, +>; +#[cfg(any(feature = "atmega1280", feature = "atmega2560", feature = "atmega32u4"))] +avr_hal_generic::impl_i2c_twi! { + hal: crate::Atmega, + peripheral: crate::pac::TWI, + sda: port::PD1, + scl: port::PD0, +} + +#[cfg(any(feature = "atmega328p", feature = "atmega168", feature = "atmega48p"))] +pub type I2c = avr_hal_generic::i2c::I2c< + crate::Atmega, + crate::pac::TWI, + port::Pin, + port::Pin, + CLOCK, +>; +#[cfg(any(feature = "atmega328p", feature = "atmega168", feature = "atmega48p"))] +avr_hal_generic::impl_i2c_twi! { + hal: crate::Atmega, + peripheral: crate::pac::TWI, + sda: port::PC4, + scl: port::PC5, +} + +#[cfg(any(feature = "atmega328pb"))] +pub type I2c0 = avr_hal_generic::i2c::I2c< + crate::Atmega, + crate::pac::TWI0, + port::Pin, + port::Pin, + CLOCK, +>; +#[cfg(any(feature = "atmega328pb"))] +avr_hal_generic::impl_i2c_twi! { + hal: crate::Atmega, + peripheral: crate::pac::TWI0, + sda: port::PC4, + scl: port::PC5, +} +#[cfg(any(feature = "atmega328pb"))] +pub type I2c1 = avr_hal_generic::i2c::I2c< + crate::Atmega, + crate::pac::TWI1, + port::Pin, + port::Pin, + CLOCK, +>; +#[cfg(any(feature = "atmega328pb"))] +avr_hal_generic::impl_i2c_twi! { + hal: crate::Atmega, + peripheral: crate::pac::TWI1, + sda: port::PE0, + scl: port::PE1, +} diff --git a/mcu/atmega-hal/src/lib.rs b/mcu/atmega-hal/src/lib.rs new file mode 100644 index 0000000000..6a4645f673 --- /dev/null +++ b/mcu/atmega-hal/src/lib.rs @@ -0,0 +1,130 @@ +#![no_std] + +//! `atmega-hal` +//! ============= +//! Common HAL (hardware abstraction layer) for ATmega* microcontrollers. +//! +//! **Note**: This version of the documentation was built for +#![cfg_attr(feature = "atmega48p", doc = "**ATmega48P**.")] +#![cfg_attr(feature = "atmega168", doc = "**ATmega168**.")] +#![cfg_attr(feature = "atmega328p", doc = "**ATmega328P**.")] +#![cfg_attr(feature = "atmega328pb", doc = "**ATmega328PB**.")] +#![cfg_attr(feature = "atmega32u4", doc = "**ATmega32U4**.")] +#![cfg_attr(feature = "atmega2560", doc = "**ATmega2560**.")] +#![cfg_attr(feature = "atmega1280", doc = "**ATmega1280**.")] +//! This means that only items which are available for this MCU are visible. If you are using +//! a different chip, try building the documentation locally with: +//! +//! ```text +//! cargo doc --features --open +//! ``` + +#[cfg(all( + not(feature = "device-selected"), + not(feature = "disable-device-selection-error") +))] +compile_error!( + "This crate requires you to specify your target chip as a feature. + + Please select one of the following + + * atmega48p + * atmega168 + * atmega328p + * atmega328pb + * atmega32u4 + * atmega1280 + * atmega2560 + " +); + +/// Reexport of `atmega1280` from `avr-device` +#[cfg(feature = "atmega1280")] +pub use avr_device::atmega1280 as pac; +/// Reexport of `atmega168` from `avr-device` +#[cfg(feature = "atmega168")] +pub use avr_device::atmega168 as pac; +/// Reexport of `atmega2560` from `avr-device` +#[cfg(feature = "atmega2560")] +pub use avr_device::atmega2560 as pac; +/// Reexport of `atmega328p` from `avr-device` +#[cfg(feature = "atmega328p")] +pub use avr_device::atmega328p as pac; +/// Reexport of `atmega328pb` from `avr-device` +#[cfg(feature = "atmega328pb")] +pub use avr_device::atmega328pb as pac; +/// Reexport of `atmega32u4` from `avr-device` +#[cfg(feature = "atmega32u4")] +pub use avr_device::atmega32u4 as pac; +/// Reexport of `atmega48p` from `avr-device` +#[cfg(feature = "atmega48p")] +pub use avr_device::atmega48p as pac; + +/// See [`avr_device::entry`](https://docs.rs/avr-device/latest/avr_device/attr.entry.html). +#[cfg(feature = "rt")] +pub use avr_device::entry; + +#[cfg(feature = "device-selected")] +pub use pac::Peripherals; + +pub use avr_hal_generic::clock; +pub use avr_hal_generic::delay; + +#[cfg(feature = "device-selected")] +pub mod adc; +#[cfg(feature = "device-selected")] +pub use adc::Adc; + +#[cfg(feature = "device-selected")] +pub mod i2c; +#[cfg(feature = "device-selected")] +pub use i2c::I2c; + +#[cfg(feature = "device-selected")] +pub mod spi; +#[cfg(feature = "device-selected")] +pub use spi::Spi; + +#[cfg(feature = "device-selected")] +pub mod port; +#[cfg(feature = "device-selected")] +pub use port::Pins; + +#[cfg(feature = "device-selected")] +pub mod usart; +#[cfg(feature = "device-selected")] +pub use usart::Usart; + +pub struct Atmega; + +#[cfg(any(feature = "atmega48p", feature = "atmega168", feature = "atmega328p"))] +#[macro_export] +macro_rules! pins { + ($p:expr) => { + $crate::Pins::new($p.PORTB, $p.PORTC, $p.PORTD) + }; +} +#[cfg(feature = "atmega328pb")] +#[macro_export] +macro_rules! pins { + ($p:expr) => { + $crate::Pins::new($p.PORTB, $p.PORTC, $p.PORTD, $p.PORTE) + }; +} +#[cfg(feature = "atmega32u4")] +#[macro_export] +macro_rules! pins { + ($p:expr) => { + $crate::Pins::new($p.PORTB, $p.PORTC, $p.PORTD, $p.PORTE, $p.PORTF) + }; +} +#[cfg(any(feature = "atmega1280", feature = "atmega2560"))] +#[macro_export] +macro_rules! pins { + ($p:expr) => { + $crate::Pins::new( + $p.PORTA, $p.PORTB, $p.PORTC, $p.PORTD, $p.PORTE, $p.PORTF, $p.PORTG, $p.PORTH, + $p.PORTJ, $p.PORTK, $p.PORTL, + ) + }; +} diff --git a/mcu/atmega-hal/src/port.rs b/mcu/atmega-hal/src/port.rs new file mode 100644 index 0000000000..0e55756279 --- /dev/null +++ b/mcu/atmega-hal/src/port.rs @@ -0,0 +1,220 @@ +#[cfg(any(feature = "atmega48p", feature = "atmega168", feature = "atmega328p"))] +avr_hal_generic::impl_port_traditional! { + enum Ports { + PORTB: (crate::pac::PORTB, portb, pinb, ddrb), + PORTC: (crate::pac::PORTC, portc, pinc, ddrc), + PORTD: (crate::pac::PORTD, portd, pind, ddrd), + } + + pub struct Pins { + pb0: PB0 = (crate::pac::PORTB, PORTB, 0, portb, pinb, ddrb), + pb1: PB1 = (crate::pac::PORTB, PORTB, 1, portb, pinb, ddrb), + pb2: PB2 = (crate::pac::PORTB, PORTB, 2, portb, pinb, ddrb), + pb3: PB3 = (crate::pac::PORTB, PORTB, 3, portb, pinb, ddrb), + pb4: PB4 = (crate::pac::PORTB, PORTB, 4, portb, pinb, ddrb), + pb5: PB5 = (crate::pac::PORTB, PORTB, 5, portb, pinb, ddrb), + pb6: PB6 = (crate::pac::PORTB, PORTB, 6, portb, pinb, ddrb), + pb7: PB7 = (crate::pac::PORTB, PORTB, 7, portb, pinb, ddrb), + pc0: PC0 = (crate::pac::PORTC, PORTC, 0, portc, pinc, ddrc), + pc1: PC1 = (crate::pac::PORTC, PORTC, 1, portc, pinc, ddrc), + pc2: PC2 = (crate::pac::PORTC, PORTC, 2, portc, pinc, ddrc), + pc3: PC3 = (crate::pac::PORTC, PORTC, 3, portc, pinc, ddrc), + pc4: PC4 = (crate::pac::PORTC, PORTC, 4, portc, pinc, ddrc), + pc5: PC5 = (crate::pac::PORTC, PORTC, 5, portc, pinc, ddrc), + pc6: PC6 = (crate::pac::PORTC, PORTC, 6, portc, pinc, ddrc), + pd0: PD0 = (crate::pac::PORTD, PORTD, 0, portd, pind, ddrd), + pd1: PD1 = (crate::pac::PORTD, PORTD, 1, portd, pind, ddrd), + pd2: PD2 = (crate::pac::PORTD, PORTD, 2, portd, pind, ddrd), + pd3: PD3 = (crate::pac::PORTD, PORTD, 3, portd, pind, ddrd), + pd4: PD4 = (crate::pac::PORTD, PORTD, 4, portd, pind, ddrd), + pd5: PD5 = (crate::pac::PORTD, PORTD, 5, portd, pind, ddrd), + pd6: PD6 = (crate::pac::PORTD, PORTD, 6, portd, pind, ddrd), + pd7: PD7 = (crate::pac::PORTD, PORTD, 7, portd, pind, ddrd), + } +} + +#[cfg(feature = "atmega328pb")] +avr_hal_generic::impl_port_traditional! { + enum Ports { + PORTB: (crate::pac::PORTB, portb, pinb, ddrb), + PORTC: (crate::pac::PORTC, portc, pinc, ddrc), + PORTD: (crate::pac::PORTD, portd, pind, ddrd), + PORTE: (crate::pac::PORTE, porte, pine, ddre), + } + + pub struct Pins { + pb0: PB0 = (crate::pac::PORTB, PORTB, 0, portb, pinb, ddrb), + pb1: PB1 = (crate::pac::PORTB, PORTB, 1, portb, pinb, ddrb), + pb2: PB2 = (crate::pac::PORTB, PORTB, 2, portb, pinb, ddrb), + pb3: PB3 = (crate::pac::PORTB, PORTB, 3, portb, pinb, ddrb), + pb4: PB4 = (crate::pac::PORTB, PORTB, 4, portb, pinb, ddrb), + pb5: PB5 = (crate::pac::PORTB, PORTB, 5, portb, pinb, ddrb), + pb6: PB6 = (crate::pac::PORTB, PORTB, 6, portb, pinb, ddrb), + pb7: PB7 = (crate::pac::PORTB, PORTB, 7, portb, pinb, ddrb), + pc0: PC0 = (crate::pac::PORTC, PORTC, 0, portc, pinc, ddrc), + pc1: PC1 = (crate::pac::PORTC, PORTC, 1, portc, pinc, ddrc), + pc2: PC2 = (crate::pac::PORTC, PORTC, 2, portc, pinc, ddrc), + pc3: PC3 = (crate::pac::PORTC, PORTC, 3, portc, pinc, ddrc), + pc4: PC4 = (crate::pac::PORTC, PORTC, 4, portc, pinc, ddrc), + pc5: PC5 = (crate::pac::PORTC, PORTC, 5, portc, pinc, ddrc), + pc6: PC6 = (crate::pac::PORTC, PORTC, 6, portc, pinc, ddrc), + pd0: PD0 = (crate::pac::PORTD, PORTD, 0, portd, pind, ddrd), + pd1: PD1 = (crate::pac::PORTD, PORTD, 1, portd, pind, ddrd), + pd2: PD2 = (crate::pac::PORTD, PORTD, 2, portd, pind, ddrd), + pd3: PD3 = (crate::pac::PORTD, PORTD, 3, portd, pind, ddrd), + pd4: PD4 = (crate::pac::PORTD, PORTD, 4, portd, pind, ddrd), + pd5: PD5 = (crate::pac::PORTD, PORTD, 5, portd, pind, ddrd), + pd6: PD6 = (crate::pac::PORTD, PORTD, 6, portd, pind, ddrd), + pd7: PD7 = (crate::pac::PORTD, PORTD, 7, portd, pind, ddrd), + pe0: PE0 = (crate::pac::PORTE, PORTE, 0, porte, pine, ddre), + pe1: PE1 = (crate::pac::PORTE, PORTE, 1, porte, pine, ddre), + pe2: PE2 = (crate::pac::PORTE, PORTE, 2, porte, pine, ddre), + pe3: PE3 = (crate::pac::PORTE, PORTE, 3, porte, pine, ddre), + } +} + +#[cfg(feature = "atmega32u4")] +avr_hal_generic::impl_port_traditional! { + enum Ports { + PORTB: (crate::pac::PORTB, portb, pinb, ddrb), + PORTC: (crate::pac::PORTC, portc, pinc, ddrc), + PORTD: (crate::pac::PORTD, portd, pind, ddrd), + PORTE: (crate::pac::PORTE, porte, pine, ddre), + PORTF: (crate::pac::PORTF, portf, pinf, ddrf), + } + + pub struct Pins { + pb0: PB0 = (crate::pac::PORTB, PORTB, 0, portb, pinb, ddrb), + pb1: PB1 = (crate::pac::PORTB, PORTB, 1, portb, pinb, ddrb), + pb2: PB2 = (crate::pac::PORTB, PORTB, 2, portb, pinb, ddrb), + pb3: PB3 = (crate::pac::PORTB, PORTB, 3, portb, pinb, ddrb), + pb4: PB4 = (crate::pac::PORTB, PORTB, 4, portb, pinb, ddrb), + pb5: PB5 = (crate::pac::PORTB, PORTB, 5, portb, pinb, ddrb), + pb6: PB6 = (crate::pac::PORTB, PORTB, 6, portb, pinb, ddrb), + pb7: PB7 = (crate::pac::PORTB, PORTB, 7, portb, pinb, ddrb), + pc6: PC6 = (crate::pac::PORTC, PORTC, 6, portc, pinc, ddrc), + pc7: PC7 = (crate::pac::PORTC, PORTC, 7, portc, pinc, ddrc), + pd0: PD0 = (crate::pac::PORTD, PORTD, 0, portd, pind, ddrd), + pd1: PD1 = (crate::pac::PORTD, PORTD, 1, portd, pind, ddrd), + pd2: PD2 = (crate::pac::PORTD, PORTD, 2, portd, pind, ddrd), + pd3: PD3 = (crate::pac::PORTD, PORTD, 3, portd, pind, ddrd), + pd4: PD4 = (crate::pac::PORTD, PORTD, 4, portd, pind, ddrd), + pd5: PD5 = (crate::pac::PORTD, PORTD, 5, portd, pind, ddrd), + pd6: PD6 = (crate::pac::PORTD, PORTD, 6, portd, pind, ddrd), + pd7: PD7 = (crate::pac::PORTD, PORTD, 7, portd, pind, ddrd), + pe2: PE2 = (crate::pac::PORTE, PORTE, 2, porte, pine, ddre), + pe6: PE6 = (crate::pac::PORTE, PORTE, 6, porte, pine, ddre), + pf0: PF0 = (crate::pac::PORTF, PORTF, 0, portf, pinf, ddrf), + pf1: PF1 = (crate::pac::PORTF, PORTF, 1, portf, pinf, ddrf), + pf4: PF4 = (crate::pac::PORTF, PORTF, 4, portf, pinf, ddrf), + pf5: PF5 = (crate::pac::PORTF, PORTF, 5, portf, pinf, ddrf), + pf6: PF6 = (crate::pac::PORTF, PORTF, 6, portf, pinf, ddrf), + pf7: PF7 = (crate::pac::PORTF, PORTF, 7, portf, pinf, ddrf), + } +} + +#[cfg(any(feature = "atmega1280", feature = "atmega2560"))] +avr_hal_generic::impl_port_traditional! { + enum Ports { + PORTA: (crate::pac::PORTA, porta, pina, ddra), + PORTB: (crate::pac::PORTB, portb, pinb, ddrb), + PORTC: (crate::pac::PORTC, portc, pinc, ddrc), + PORTD: (crate::pac::PORTD, portd, pind, ddrd), + PORTE: (crate::pac::PORTE, porte, pine, ddre), + PORTF: (crate::pac::PORTF, portf, pinf, ddrf), + PORTG: (crate::pac::PORTG, portg, ping, ddrg), + PORTH: (crate::pac::PORTH, porth, pinh, ddrh), + PORTJ: (crate::pac::PORTJ, portj, pinj, ddrj), + PORTK: (crate::pac::PORTK, portk, pink, ddrk), + PORTL: (crate::pac::PORTL, portl, pinl, ddrl), + } + + pub struct Pins { + pa0: PA0 = (crate::pac::PORTA, PORTA, 0, porta, pina, ddra), + pa1: PA1 = (crate::pac::PORTA, PORTA, 1, porta, pina, ddra), + pa2: PA2 = (crate::pac::PORTA, PORTA, 2, porta, pina, ddra), + pa3: PA3 = (crate::pac::PORTA, PORTA, 3, porta, pina, ddra), + pa4: PA4 = (crate::pac::PORTA, PORTA, 4, porta, pina, ddra), + pa5: PA5 = (crate::pac::PORTA, PORTA, 5, porta, pina, ddra), + pa6: PA6 = (crate::pac::PORTA, PORTA, 6, porta, pina, ddra), + pa7: PA7 = (crate::pac::PORTA, PORTA, 7, porta, pina, ddra), + pb0: PB0 = (crate::pac::PORTB, PORTB, 0, portb, pinb, ddrb), + pb1: PB1 = (crate::pac::PORTB, PORTB, 1, portb, pinb, ddrb), + pb2: PB2 = (crate::pac::PORTB, PORTB, 2, portb, pinb, ddrb), + pb3: PB3 = (crate::pac::PORTB, PORTB, 3, portb, pinb, ddrb), + pb4: PB4 = (crate::pac::PORTB, PORTB, 4, portb, pinb, ddrb), + pb5: PB5 = (crate::pac::PORTB, PORTB, 5, portb, pinb, ddrb), + pb6: PB6 = (crate::pac::PORTB, PORTB, 6, portb, pinb, ddrb), + pb7: PB7 = (crate::pac::PORTB, PORTB, 7, portb, pinb, ddrb), + pc0: PC0 = (crate::pac::PORTC, PORTC, 0, portc, pinc, ddrc), + pc1: PC1 = (crate::pac::PORTC, PORTC, 1, portc, pinc, ddrc), + pc2: PC2 = (crate::pac::PORTC, PORTC, 2, portc, pinc, ddrc), + pc3: PC3 = (crate::pac::PORTC, PORTC, 3, portc, pinc, ddrc), + pc4: PC4 = (crate::pac::PORTC, PORTC, 4, portc, pinc, ddrc), + pc5: PC5 = (crate::pac::PORTC, PORTC, 5, portc, pinc, ddrc), + pc6: PC6 = (crate::pac::PORTC, PORTC, 6, portc, pinc, ddrc), + pc7: PC7 = (crate::pac::PORTC, PORTC, 7, portc, pinc, ddrc), + pd0: PD0 = (crate::pac::PORTD, PORTD, 0, portd, pind, ddrd), + pd1: PD1 = (crate::pac::PORTD, PORTD, 1, portd, pind, ddrd), + pd2: PD2 = (crate::pac::PORTD, PORTD, 2, portd, pind, ddrd), + pd3: PD3 = (crate::pac::PORTD, PORTD, 3, portd, pind, ddrd), + pd4: PD4 = (crate::pac::PORTD, PORTD, 4, portd, pind, ddrd), + pd5: PD5 = (crate::pac::PORTD, PORTD, 5, portd, pind, ddrd), + pd6: PD6 = (crate::pac::PORTD, PORTD, 6, portd, pind, ddrd), + pd7: PD7 = (crate::pac::PORTD, PORTD, 7, portd, pind, ddrd), + pe0: PE0 = (crate::pac::PORTE, PORTE, 0, porte, pine, ddre), + pe1: PE1 = (crate::pac::PORTE, PORTE, 1, porte, pine, ddre), + pe2: PE2 = (crate::pac::PORTE, PORTE, 2, porte, pine, ddre), + pe3: PE3 = (crate::pac::PORTE, PORTE, 3, porte, pine, ddre), + pe4: PE4 = (crate::pac::PORTE, PORTE, 4, porte, pine, ddre), + pe5: PE5 = (crate::pac::PORTE, PORTE, 5, porte, pine, ddre), + pe6: PE6 = (crate::pac::PORTE, PORTE, 6, porte, pine, ddre), + pe7: PE7 = (crate::pac::PORTE, PORTE, 7, porte, pine, ddre), + pf0: PF0 = (crate::pac::PORTF, PORTF, 0, portf, pinf, ddrf), + pf1: PF1 = (crate::pac::PORTF, PORTF, 1, portf, pinf, ddrf), + pf2: PF2 = (crate::pac::PORTF, PORTF, 2, portf, pinf, ddrf), + pf3: PF3 = (crate::pac::PORTF, PORTF, 3, portf, pinf, ddrf), + pf4: PF4 = (crate::pac::PORTF, PORTF, 4, portf, pinf, ddrf), + pf5: PF5 = (crate::pac::PORTF, PORTF, 5, portf, pinf, ddrf), + pf6: PF6 = (crate::pac::PORTF, PORTF, 6, portf, pinf, ddrf), + pf7: PF7 = (crate::pac::PORTF, PORTF, 7, portf, pinf, ddrf), + pg0: PG0 = (crate::pac::PORTG, PORTG, 0, portg, ping, ddrg), + pg1: PG1 = (crate::pac::PORTG, PORTG, 1, portg, ping, ddrg), + pg2: PG2 = (crate::pac::PORTG, PORTG, 2, portg, ping, ddrg), + pg3: PG3 = (crate::pac::PORTG, PORTG, 3, portg, ping, ddrg), + pg4: PG4 = (crate::pac::PORTG, PORTG, 4, portg, ping, ddrg), + pg5: PG5 = (crate::pac::PORTG, PORTG, 5, portg, ping, ddrg), + ph0: PH0 = (crate::pac::PORTH, PORTH, 0, porth, pinh, ddrh), + ph1: PH1 = (crate::pac::PORTH, PORTH, 1, porth, pinh, ddrh), + ph2: PH2 = (crate::pac::PORTH, PORTH, 2, porth, pinh, ddrh), + ph3: PH3 = (crate::pac::PORTH, PORTH, 3, porth, pinh, ddrh), + ph4: PH4 = (crate::pac::PORTH, PORTH, 4, porth, pinh, ddrh), + ph5: PH5 = (crate::pac::PORTH, PORTH, 5, porth, pinh, ddrh), + ph6: PH6 = (crate::pac::PORTH, PORTH, 6, porth, pinh, ddrh), + ph7: PH7 = (crate::pac::PORTH, PORTH, 7, porth, pinh, ddrh), + pj0: PJ0 = (crate::pac::PORTJ, PORTJ, 0, portj, pinj, ddrj), + pj1: PJ1 = (crate::pac::PORTJ, PORTJ, 1, portj, pinj, ddrj), + pj2: PJ2 = (crate::pac::PORTJ, PORTJ, 2, portj, pinj, ddrj), + pj3: PJ3 = (crate::pac::PORTJ, PORTJ, 3, portj, pinj, ddrj), + pj4: PJ4 = (crate::pac::PORTJ, PORTJ, 4, portj, pinj, ddrj), + pj5: PJ5 = (crate::pac::PORTJ, PORTJ, 5, portj, pinj, ddrj), + pj6: PJ6 = (crate::pac::PORTJ, PORTJ, 6, portj, pinj, ddrj), + pj7: PJ7 = (crate::pac::PORTJ, PORTJ, 7, portj, pinj, ddrj), + pk0: PK0 = (crate::pac::PORTK, PORTK, 0, portk, pink, ddrk), + pk1: PK1 = (crate::pac::PORTK, PORTK, 1, portk, pink, ddrk), + pk2: PK2 = (crate::pac::PORTK, PORTK, 2, portk, pink, ddrk), + pk3: PK3 = (crate::pac::PORTK, PORTK, 3, portk, pink, ddrk), + pk4: PK4 = (crate::pac::PORTK, PORTK, 4, portk, pink, ddrk), + pk5: PK5 = (crate::pac::PORTK, PORTK, 5, portk, pink, ddrk), + pk6: PK6 = (crate::pac::PORTK, PORTK, 6, portk, pink, ddrk), + pk7: PK7 = (crate::pac::PORTK, PORTK, 7, portk, pink, ddrk), + pl0: PL0 = (crate::pac::PORTL, PORTL, 0, portl, pinl, ddrl), + pl1: PL1 = (crate::pac::PORTL, PORTL, 1, portl, pinl, ddrl), + pl2: PL2 = (crate::pac::PORTL, PORTL, 2, portl, pinl, ddrl), + pl3: PL3 = (crate::pac::PORTL, PORTL, 3, portl, pinl, ddrl), + pl4: PL4 = (crate::pac::PORTL, PORTL, 4, portl, pinl, ddrl), + pl5: PL5 = (crate::pac::PORTL, PORTL, 5, portl, pinl, ddrl), + pl6: PL6 = (crate::pac::PORTL, PORTL, 6, portl, pinl, ddrl), + pl7: PL7 = (crate::pac::PORTL, PORTL, 7, portl, pinl, ddrl), + } +} diff --git a/mcu/atmega-hal/src/spi.rs b/mcu/atmega-hal/src/spi.rs new file mode 100644 index 0000000000..8906c92671 --- /dev/null +++ b/mcu/atmega-hal/src/spi.rs @@ -0,0 +1,78 @@ +#[allow(unused_imports)] +use crate::port; +pub use avr_hal_generic::spi::*; + +#[cfg(any(feature = "atmega2560", feature = "atmega32u4"))] +pub type Spi = avr_hal_generic::spi::Spi< + crate::Atmega, + crate::pac::SPI, + port::PB1, + port::PB2, + port::PB3, + port::PB0, +>; +#[cfg(any(feature = "atmega2560", feature = "atmega32u4"))] +avr_hal_generic::impl_spi! { + hal: crate::Atmega, + peripheral: crate::pac::SPI, + sclk: port::PB1, + mosi: port::PB2, + miso: port::PB3, + cs: port::PB0, +} + +#[cfg(any(feature = "atmega168", feature = "atmega328p", feature = "atmega48p",))] +pub type Spi = avr_hal_generic::spi::Spi< + crate::Atmega, + crate::pac::SPI, + port::PB5, + port::PB3, + port::PB4, + port::PB2, +>; +#[cfg(any(feature = "atmega168", feature = "atmega328p", feature = "atmega48p",))] +avr_hal_generic::impl_spi! { + hal: crate::Atmega, + peripheral: crate::pac::SPI, + sclk: port::PB5, + mosi: port::PB3, + miso: port::PB4, + cs: port::PB2, +} + +#[cfg(feature = "atmega328pb")] +pub type Spi0 = avr_hal_generic::spi::Spi< + crate::Atmega, + crate::pac::SPI0, + port::PB5, + port::PB3, + port::PB4, + port::PB2, +>; +#[cfg(feature = "atmega328pb")] +avr_hal_generic::impl_spi! { + hal: crate::Atmega, + peripheral: crate::pac::SPI0, + sclk: port::PB5, + mosi: port::PB3, + miso: port::PB4, + cs: port::PB2, +} +#[cfg(feature = "atmega328pb")] +pub type Spi1 = avr_hal_generic::spi::Spi< + crate::Atmega, + crate::pac::SPI1, + port::PC1, + port::PE3, + port::PC0, + port::PE2, +>; +#[cfg(feature = "atmega328pb")] +avr_hal_generic::impl_spi! { + hal: crate::Atmega, + peripheral: crate::pac::SPI1, + sclk: port::PC1, + mosi: port::PE3, + miso: port::PC0, + cs: port::PE2, +} diff --git a/mcu/atmega-hal/src/usart.rs b/mcu/atmega-hal/src/usart.rs new file mode 100644 index 0000000000..b6216732c1 --- /dev/null +++ b/mcu/atmega-hal/src/usart.rs @@ -0,0 +1,106 @@ +#[allow(unused_imports)] +use crate::port; +pub use avr_hal_generic::usart::*; + +pub type Usart = + avr_hal_generic::usart::Usart; +pub type UsartWriter = + avr_hal_generic::usart::UsartWriter; +pub type UsartReader = + avr_hal_generic::usart::UsartReader; + +#[cfg(any(feature = "atmega168", feature = "atmega328p", feature = "atmega328pb"))] +pub type Usart0 = Usart< + crate::pac::USART0, + port::Pin, + port::Pin, + CLOCK, +>; +#[cfg(any(feature = "atmega168", feature = "atmega328p", feature = "atmega328pb"))] +avr_hal_generic::impl_usart_traditional! { + hal: crate::Atmega, + peripheral: crate::pac::USART0, + register_suffix: 0, + rx: port::PD0, + tx: port::PD1, +} + +#[cfg(feature = "atmega328pb")] +pub type Usart1 = Usart< + crate::pac::USART1, + port::Pin, + port::Pin, + CLOCK, +>; +#[cfg(feature = "atmega328pb")] +avr_hal_generic::impl_usart_traditional! { + hal: crate::Atmega, + peripheral: crate::pac::USART1, + register_suffix: 1, + rx: port::PB4, + tx: port::PB3, +} + +#[cfg(any(feature = "atmega32u4", feature = "atmega1280", feature = "atmega2560"))] +pub type Usart1 = Usart< + crate::pac::USART1, + port::Pin, + port::Pin, + CLOCK, +>; +#[cfg(any(feature = "atmega32u4", feature = "atmega1280", feature = "atmega2560"))] +avr_hal_generic::impl_usart_traditional! { + hal: crate::Atmega, + peripheral: crate::pac::USART1, + register_suffix: 1, + rx: port::PD2, + tx: port::PD3, +} + +#[cfg(any(feature = "atmega1280", feature = "atmega2560"))] +pub type Usart0 = Usart< + crate::pac::USART0, + port::Pin, + port::Pin, + CLOCK, +>; +#[cfg(any(feature = "atmega1280", feature = "atmega2560"))] +avr_hal_generic::impl_usart_traditional! { + hal: crate::Atmega, + peripheral: crate::pac::USART0, + register_suffix: 0, + rx: port::PE0, + tx: port::PE1, +} + +#[cfg(any(feature = "atmega1280", feature = "atmega2560"))] +pub type Usart2 = Usart< + crate::pac::USART2, + port::Pin, + port::Pin, + CLOCK, +>; +#[cfg(any(feature = "atmega1280", feature = "atmega2560"))] +avr_hal_generic::impl_usart_traditional! { + hal: crate::Atmega, + peripheral: crate::pac::USART2, + register_suffix: 2, + rx: port::PH0, + tx: port::PH1, +} + +#[cfg(any(feature = "atmega1280", feature = "atmega2560"))] +pub type Usart3 = Usart< + crate::pac::USART3, + port::Pin, + port::Pin, + CLOCK, +>; +#[cfg(any(feature = "atmega1280", feature = "atmega2560"))] +avr_hal_generic::impl_usart_traditional! { + hal: crate::Atmega, + peripheral: crate::pac::USART3, + register_suffix: 3, + rx: port::PJ0, + tx: port::PJ1, +} diff --git a/mcu/attiny-hal/Cargo.toml b/mcu/attiny-hal/Cargo.toml new file mode 100644 index 0000000000..6352becbd8 --- /dev/null +++ b/mcu/attiny-hal/Cargo.toml @@ -0,0 +1,28 @@ +[package] +name = "attiny-hal" +version = "0.1.0" +authors = ["Rahix "] +edition = "2018" + +[features] +rt = ["avr-device/rt"] +device-selected = [] +attiny85 = ["avr-device/attiny85", "device-selected"] +attiny88 = ["avr-device/attiny88", "device-selected"] + +# Allow certain downstream crates to overwrite the device selection error by themselves. +disable-device-selection-error = [] + +[dependencies] +avr-hal-generic = { path = "../../avr-hal-generic/" } + +[dependencies.avr-device] +version = "0.3" + +# Because this crate has its own check that at least one device is selected, we +# can safely "circumvent" the check in `avr-device`. +# +# Why would we want that? Otherwise, as `avr-device` is compiled first, its +# error will be shown and ours won't which leads to a degraded user experience +# as the displayed error message does not really tell what needs to be done... +features = ["device-selected"] diff --git a/mcu/attiny-hal/src/lib.rs b/mcu/attiny-hal/src/lib.rs new file mode 100644 index 0000000000..70ba5b589b --- /dev/null +++ b/mcu/attiny-hal/src/lib.rs @@ -0,0 +1,69 @@ +#![no_std] + +//! `attiny-hal` +//! ============= +//! Common HAL (hardware abstraction layer) for ATtiny* microcontrollers. +//! +//! **Note**: This version of the documentation was built for +#![cfg_attr(feature = "attiny85", doc = "**ATtiny85**.")] +#![cfg_attr(feature = "attiny88", doc = "**ATtiny88**.")] +//! This means that only items which are available for this MCU are visible. If you are using +//! a different chip, try building the documentation locally with: +//! +//! ```text +//! cargo doc --features --open +//! ``` + +#[cfg(all( + not(feature = "device-selected"), + not(feature = "disable-device-selection-error") +))] +compile_error!( + "This crate requires you to specify your target chip as a feature. + + Please select one of the following + + * attiny85 + * attiny88 + " +); + +/// Reexport of `attiny85` from `avr-device` +#[cfg(feature = "attiny85")] +pub use avr_device::attiny85 as pac; + +/// Reexport of `attiny88` from `avr-device` +#[cfg(feature = "attiny88")] +pub use avr_device::attiny88 as pac; + +/// See [`avr_device::entry`](https://docs.rs/avr-device/latest/avr_device/attr.entry.html). +#[cfg(feature = "rt")] +pub use avr_device::entry; + +#[cfg(feature = "device-selected")] +pub use pac::Peripherals; + +pub use avr_hal_generic::clock; +pub use avr_hal_generic::delay; + +#[cfg(feature = "device-selected")] +pub mod port; +#[cfg(feature = "device-selected")] +pub use port::Pins; + +pub struct Attiny; + +#[cfg(feature = "attiny85")] +#[macro_export] +macro_rules! pins { + ($p:expr) => { + $crate::Pins::new($p.PORTB) + }; +} +#[cfg(feature = "attiny88")] +#[macro_export] +macro_rules! pins { + ($p:expr) => { + $crate::Pins::new($p.PORTA, $p.PORTB, $p.PORTC, $p.PORTD) + }; +} diff --git a/mcu/attiny-hal/src/port.rs b/mcu/attiny-hal/src/port.rs new file mode 100644 index 0000000000..a66661963a --- /dev/null +++ b/mcu/attiny-hal/src/port.rs @@ -0,0 +1,56 @@ +#[cfg(feature = "attiny85")] +avr_hal_generic::impl_port_traditional! { + enum Ports { + PORTB: (crate::pac::PORTB, portb, pinb, ddrb), + } + + pub struct Pins { + pb0: PB0 = (crate::pac::PORTB, PORTB, 0, portb, pinb, ddrb), + pb1: PB1 = (crate::pac::PORTB, PORTB, 1, portb, pinb, ddrb), + pb2: PB2 = (crate::pac::PORTB, PORTB, 2, portb, pinb, ddrb), + pb3: PB3 = (crate::pac::PORTB, PORTB, 3, portb, pinb, ddrb), + pb4: PB4 = (crate::pac::PORTB, PORTB, 4, portb, pinb, ddrb), + pb5: PB5 = (crate::pac::PORTB, PORTB, 5, portb, pinb, ddrb), + } +} + +#[cfg(feature = "attiny88")] +avr_hal_generic::impl_port_traditional! { + enum Ports { + PORTA: (crate::pac::PORTA, porta, pina, ddra), + PORTB: (crate::pac::PORTB, portb, pinb, ddrb), + PORTC: (crate::pac::PORTC, portc, pinc, ddrc), + PORTD: (crate::pac::PORTD, portd, pind, ddrd), + } + + pub struct Pins { + pa0: PA0 = (crate::pac::PORTA, PORTA, 0, porta, pina, ddra), + pa1: PA1 = (crate::pac::PORTA, PORTA, 1, porta, pina, ddra), + pa2: PA2 = (crate::pac::PORTA, PORTA, 2, porta, pina, ddra), + pa3: PA3 = (crate::pac::PORTA, PORTA, 3, porta, pina, ddra), + pb0: PB0 = (crate::pac::PORTB, PORTB, 0, portb, pinb, ddrb), + pb1: PB1 = (crate::pac::PORTB, PORTB, 1, portb, pinb, ddrb), + pb2: PB2 = (crate::pac::PORTB, PORTB, 2, portb, pinb, ddrb), + pb3: PB3 = (crate::pac::PORTB, PORTB, 3, portb, pinb, ddrb), + pb4: PB4 = (crate::pac::PORTB, PORTB, 4, portb, pinb, ddrb), + pb5: PB5 = (crate::pac::PORTB, PORTB, 5, portb, pinb, ddrb), + pb6: PB6 = (crate::pac::PORTB, PORTB, 6, portb, pinb, ddrb), + pb7: PB7 = (crate::pac::PORTB, PORTB, 7, portb, pinb, ddrb), + pc0: PC0 = (crate::pac::PORTC, PORTC, 0, portc, pinc, ddrc), + pc1: PC1 = (crate::pac::PORTC, PORTC, 1, portc, pinc, ddrc), + pc2: PC2 = (crate::pac::PORTC, PORTC, 2, portc, pinc, ddrc), + pc3: PC3 = (crate::pac::PORTC, PORTC, 3, portc, pinc, ddrc), + pc4: PC4 = (crate::pac::PORTC, PORTC, 4, portc, pinc, ddrc), + pc5: PC5 = (crate::pac::PORTC, PORTC, 5, portc, pinc, ddrc), + pc6: PC6 = (crate::pac::PORTC, PORTC, 6, portc, pinc, ddrc), + pc7: PC7 = (crate::pac::PORTC, PORTC, 7, portc, pinc, ddrc), + pd0: PD0 = (crate::pac::PORTD, PORTD, 0, portd, pind, ddrd), + pd1: PD1 = (crate::pac::PORTD, PORTD, 1, portd, pind, ddrd), + pd2: PD2 = (crate::pac::PORTD, PORTD, 2, portd, pind, ddrd), + pd3: PD3 = (crate::pac::PORTD, PORTD, 3, portd, pind, ddrd), + pd4: PD4 = (crate::pac::PORTD, PORTD, 4, portd, pind, ddrd), + pd5: PD5 = (crate::pac::PORTD, PORTD, 5, portd, pind, ddrd), + pd6: PD6 = (crate::pac::PORTD, PORTD, 6, portd, pind, ddrd), + pd7: PD7 = (crate::pac::PORTD, PORTD, 7, portd, pind, ddrd), + } +} diff --git a/mcu/attiny-hal/src/spi.rs b/mcu/attiny-hal/src/spi.rs new file mode 100644 index 0000000000..2b0176a2b6 --- /dev/null +++ b/mcu/attiny-hal/src/spi.rs @@ -0,0 +1,22 @@ +#[allow(unused_imports)] +use crate::port; +pub use avr_hal_generic::spi::*; + +#[cfg(feature = "attiny88")] +pub type Spi = avr_hal_generic::spi::Spi< + crate::Atmega, + crate::pac::SPI, + port::PB5, + port::PB3, + port::PB4, + port::PB2, +>; +#[cfg(feature = "attiny88")] +avr_hal_generic::impl_spi! { + hal: crate::Atmega, + peripheral: crate::pac::SPI, + sclk: port::PB5, + mosi: port::PB3, + miso: port::PB4, + cs: port::PB2, +} diff --git a/mkhex.sh b/mkhex.sh deleted file mode 100755 index 00c1298df0..0000000000 --- a/mkhex.sh +++ /dev/null @@ -1,36 +0,0 @@ -#!/bin/sh -set -e - -if [ $# -gt 2 -o $1 = "--help" ]; then - echo "usage: $0 [--release|--debug] " >&2 - exit 1 -fi - -BUILD="debug" -if [ "$1" = "--debug" ]; then - shift 1 - BUILD="debug" -elif [ "$1" = "--release" ]; then - shift 1 - BUILD="release" -fi - -TARGET="$(realpath --relative-to="$(pwd)" "$(dirname "$0")/target")" -HEX="$TARGET/$1.hex" -ELF="$(echo "$TARGET"/avr-*/"$BUILD/examples/$1.elf")" - -if [ ! -e "$ELF" ]; then - echo "No $1.elf found. The following binaries exist:" >&2 - for target_dir in "$TARGET"/avr-*; do - for bin in "$target_dir/$BUILD/examples"/*.elf; do - echo " - $(basename -s.elf "$bin")" >&2 - done - done - exit 1 -fi - -avr-objcopy -S -j .text -j .data -O ihex "$ELF" "$HEX" - -BYTES=$(avr-size "$ELF" | tail -1 | cut -f4 | bc) -echo "$ELF:" >&2 -echo " $(numfmt --to=si "$BYTES") Bytes used ($BYTES exact)." >&2 diff --git a/ravedude/.gitignore b/ravedude/.gitignore new file mode 100644 index 0000000000..8ce0a8f200 --- /dev/null +++ b/ravedude/.gitignore @@ -0,0 +1,2 @@ +/target +!Cargo.lock diff --git a/ravedude/CHANGELOG.md b/ravedude/CHANGELOG.md new file mode 100644 index 0000000000..b6dad48724 --- /dev/null +++ b/ravedude/CHANGELOG.md @@ -0,0 +1,33 @@ +# Changelog +All notable changes to *ravedude* will be documented in this file. + +The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), +and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). + +## [Unreleased] +### Added +- Support for *Arduino Mega 2560*. + + +## [0.1.2] - 2021-03-21 +### Removed +- The `--no-program` flag was removed, just don't pass a binary if you want to + skip flashing. + +### Fixed +- Fixed support for *Arduino Nano*. + + +## [0.1.1] - 2021-03-13 +### Fixed +- Fixed broken metadata. + + +## [0.1.0] - 2021-03-06 +Initial, miminal version. + + +[Unreleased]: https://github.com/rahix/avr-hal/compare/ravedude-0.1.2...HEAD +[0.1.2]: https://github.com/rahix/avr-hal/compare/ravedude-0.1.1...ravedude-0.1.2 +[0.1.1]: https://github.com/rahix/avr-hal/compare/ravedude-0.1.0...ravedude-0.1.1 +[0.1.0]: https://github.com/rahix/avr-hal/releases/tag/ravedude-0.1.0 diff --git a/ravedude/Cargo.lock b/ravedude/Cargo.lock new file mode 100644 index 0000000000..7175628015 --- /dev/null +++ b/ravedude/Cargo.lock @@ -0,0 +1,505 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +[[package]] +name = "CoreFoundation-sys" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d0e9889e6db118d49d88d84728d0e964d973a5680befb5f85f55141beea5c20b" +dependencies = [ + "libc", + "mach 0.1.2", +] + +[[package]] +name = "IOKit-sys" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "99696c398cbaf669d2368076bdb3d627fb0ce51a26899d7c61228c5c0af3bf4a" +dependencies = [ + "CoreFoundation-sys", + "libc", + "mach 0.1.2", +] + +[[package]] +name = "aho-corasick" +version = "0.7.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7404febffaa47dac81aa44dba71523c9d069b1bdc50a77db41195149e17f68e5" +dependencies = [ + "memchr", +] + +[[package]] +name = "ansi_term" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ee49baf6cb617b853aa8d93bf420db2383fab46d314482ca2803b40d5fde979b" +dependencies = [ + "winapi", +] + +[[package]] +name = "anyhow" +version = "1.0.38" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "afddf7f520a80dbf76e6f50a35bca42a2331ef227a28b3b6dc5c2e2338d114b1" + +[[package]] +name = "atty" +version = "0.2.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d9b39be18770d11421cdb1b9947a45dd3f37e93092cbf377614828a319d5fee8" +dependencies = [ + "hermit-abi", + "libc", + "winapi", +] + +[[package]] +name = "bitflags" +version = "1.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cf1de2fe8c75bc145a2f577add951f8134889b4795d47466a54a5c846d691693" + +[[package]] +name = "cc" +version = "1.0.67" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e3c69b077ad434294d3ce9f1f6143a2a4b89a8a2d54ef813d85003a4fd1137fd" + +[[package]] +name = "cfg-if" +version = "0.1.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4785bdd1c96b2a846b2bd7cc02e86b6b3dbf14e7e53446c4f54c92a361040822" + +[[package]] +name = "cfg-if" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" + +[[package]] +name = "clap" +version = "2.33.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "37e58ac78573c40708d45522f0d80fa2f01cc4f9b4e2bf749807255454312002" +dependencies = [ + "ansi_term", + "atty", + "bitflags", + "textwrap", + "unicode-width", +] + +[[package]] +name = "colored" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b3616f750b84d8f0de8a58bda93e08e2a81ad3f523089b05f1dffecab48c6cbd" +dependencies = [ + "atty", + "lazy_static", + "winapi", +] + +[[package]] +name = "getrandom" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c9495705279e7140bf035dde1f6e750c162df8b625267cd52cc44e0b156732c8" +dependencies = [ + "cfg-if 1.0.0", + "libc", + "wasi", +] + +[[package]] +name = "git-version" +version = "0.3.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "94918e83f1e01dedc2e361d00ce9487b14c58c7f40bab148026fa39d42cb41e2" +dependencies = [ + "git-version-macro", + "proc-macro-hack", +] + +[[package]] +name = "git-version-macro" +version = "0.3.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "34a97a52fdee1870a34fa6e4b77570cba531b27d1838874fef4429a791a3d657" +dependencies = [ + "proc-macro-hack", + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "heck" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "87cbf45460356b7deeb5e3415b5563308c0a9b057c85e12b06ad551f98d0a6ac" +dependencies = [ + "unicode-segmentation", +] + +[[package]] +name = "hermit-abi" +version = "0.1.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "322f4de77956e22ed0e5032c359a0f1273f1f7f0d79bfa3b8ffbc730d7fbcc5c" +dependencies = [ + "libc", +] + +[[package]] +name = "lazy_static" +version = "1.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" + +[[package]] +name = "libc" +version = "0.2.90" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ba4aede83fc3617411dc6993bc8c70919750c1c257c6ca6a502aed6e0e2394ae" + +[[package]] +name = "libudev" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ea626d3bdf40a1c5aee3bcd4f40826970cae8d80a8fec934c82a63840094dcfe" +dependencies = [ + "libc", + "libudev-sys", +] + +[[package]] +name = "libudev-sys" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3c8469b4a23b962c1396b9b451dda50ef5b283e8dd309d69033475fa9b334324" +dependencies = [ + "libc", + "pkg-config", +] + +[[package]] +name = "mach" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2fd13ee2dd61cc82833ba05ade5a30bb3d63f7ced605ef827063c63078302de9" +dependencies = [ + "libc", +] + +[[package]] +name = "mach" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "86dd2487cdfea56def77b88438a2c915fb45113c5319bfe7e14306ca4cd0b0e1" +dependencies = [ + "libc", +] + +[[package]] +name = "memchr" +version = "2.3.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0ee1c47aaa256ecabcaea351eae4a9b01ef39ed810004e298d2511ed284b1525" + +[[package]] +name = "nix" +version = "0.16.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dd0eaf8df8bab402257e0a5c17a254e4cc1f72a93588a1ddfb5d356c801aa7cb" +dependencies = [ + "bitflags", + "cc", + "cfg-if 0.1.10", + "libc", + "void", +] + +[[package]] +name = "pkg-config" +version = "0.3.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3831453b3449ceb48b6d9c7ad7c96d5ea673e9b470a1dc578c2ce6521230884c" + +[[package]] +name = "ppv-lite86" +version = "0.2.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ac74c624d6b2d21f425f752262f42188365d7b8ff1aff74c82e45136510a4857" + +[[package]] +name = "proc-macro-error" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "da25490ff9892aab3fcf7c36f08cfb902dd3e71ca0f9f9517bea02a73a5ce38c" +dependencies = [ + "proc-macro-error-attr", + "proc-macro2", + "quote", + "syn", + "version_check", +] + +[[package]] +name = "proc-macro-error-attr" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a1be40180e52ecc98ad80b184934baf3d0d29f979574e439af5a55274b35f869" +dependencies = [ + "proc-macro2", + "quote", + "version_check", +] + +[[package]] +name = "proc-macro-hack" +version = "0.5.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dbf0c48bc1d91375ae5c3cd81e3722dff1abcf81a30960240640d223f59fe0e5" + +[[package]] +name = "proc-macro2" +version = "1.0.24" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e0704ee1a7e00d7bb417d0770ea303c1bccbabf0ef1667dae92b5967f5f8a71" +dependencies = [ + "unicode-xid", +] + +[[package]] +name = "quote" +version = "1.0.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c3d0b9745dc2debf507c8422de05d7226cc1f0644216dfdfead988f9b1ab32a7" +dependencies = [ + "proc-macro2", +] + +[[package]] +name = "rand" +version = "0.8.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0ef9e7e66b4468674bfcb0c81af8b7fa0bb154fa9f28eb840da5c447baeb8d7e" +dependencies = [ + "libc", + "rand_chacha", + "rand_core", + "rand_hc", +] + +[[package]] +name = "rand_chacha" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e12735cf05c9e10bf21534da50a147b924d555dc7a547c42e6bb2d5b6017ae0d" +dependencies = [ + "ppv-lite86", + "rand_core", +] + +[[package]] +name = "rand_core" +version = "0.6.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "34cf66eb183df1c5876e2dcf6b13d57340741e8dc255b48e40a26de954d06ae7" +dependencies = [ + "getrandom", +] + +[[package]] +name = "rand_hc" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3190ef7066a446f2e7f42e239d161e905420ccab01eb967c9eb27d21b2322a73" +dependencies = [ + "rand_core", +] + +[[package]] +name = "ravedude" +version = "0.1.2" +dependencies = [ + "anyhow", + "colored", + "git-version", + "serialport", + "structopt", + "tempfile", +] + +[[package]] +name = "redox_syscall" +version = "0.2.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "94341e4e44e24f6b591b59e47a8a027df12e008d73fd5672dbea9cc22f4507d9" +dependencies = [ + "bitflags", +] + +[[package]] +name = "regex" +version = "1.4.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "957056ecddbeba1b26965114e191d2e8589ce74db242b6ea25fc4062427a5c19" +dependencies = [ + "aho-corasick", + "memchr", + "regex-syntax", +] + +[[package]] +name = "regex-syntax" +version = "0.6.23" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "24d5f089152e60f62d28b835fbff2cd2e8dc0baf1ac13343bef92ab7eed84548" + +[[package]] +name = "remove_dir_all" +version = "0.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3acd125665422973a33ac9d3dd2df85edad0f4ae9b00dafb1a05e43a9f5ef8e7" +dependencies = [ + "winapi", +] + +[[package]] +name = "serialport" +version = "4.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "22f37409d980045734250d679750bdf11bd875fec5bb5417dd21bb75d04d31a1" +dependencies = [ + "CoreFoundation-sys", + "IOKit-sys", + "bitflags", + "cfg-if 0.1.10", + "libudev", + "mach 0.2.3", + "nix", + "regex", + "winapi", +] + +[[package]] +name = "structopt" +version = "0.3.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5277acd7ee46e63e5168a80734c9f6ee81b1367a7d8772a2d765df2a3705d28c" +dependencies = [ + "clap", + "lazy_static", + "structopt-derive", +] + +[[package]] +name = "structopt-derive" +version = "0.4.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5ba9cdfda491b814720b6b06e0cac513d922fc407582032e8706e9f137976f90" +dependencies = [ + "heck", + "proc-macro-error", + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "syn" +version = "1.0.64" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3fd9d1e9976102a03c542daa2eff1b43f9d72306342f3f8b3ed5fb8908195d6f" +dependencies = [ + "proc-macro2", + "quote", + "unicode-xid", +] + +[[package]] +name = "tempfile" +version = "3.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dac1c663cfc93810f88aed9b8941d48cabf856a1b111c29a40439018d870eb22" +dependencies = [ + "cfg-if 1.0.0", + "libc", + "rand", + "redox_syscall", + "remove_dir_all", + "winapi", +] + +[[package]] +name = "textwrap" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d326610f408c7a4eb6f51c37c330e496b08506c9457c9d34287ecc38809fb060" +dependencies = [ + "unicode-width", +] + +[[package]] +name = "unicode-segmentation" +version = "1.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bb0d2e7be6ae3a5fa87eed5fb451aff96f2573d2694942e40543ae0bbe19c796" + +[[package]] +name = "unicode-width" +version = "0.1.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9337591893a19b88d8d87f2cec1e73fad5cdfd10e5a6f349f498ad6ea2ffb1e3" + +[[package]] +name = "unicode-xid" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f7fe0bb3479651439c9112f72b6c505038574c9fbb575ed1bf3b797fa39dd564" + +[[package]] +name = "version_check" +version = "0.9.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5fecdca9a5291cc2b8dcf7dc02453fee791a280f3743cb0905f8822ae463b3fe" + +[[package]] +name = "void" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6a02e4885ed3bc0f2de90ea6dd45ebcbb66dacffe03547fadbb0eeae2770887d" + +[[package]] +name = "wasi" +version = "0.10.2+wasi-snapshot-preview1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fd6fbd9a79829dd1ad0cc20627bf1ed606756a7f77edff7b66b7064f9cb327c6" + +[[package]] +name = "winapi" +version = "0.3.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419" +dependencies = [ + "winapi-i686-pc-windows-gnu", + "winapi-x86_64-pc-windows-gnu", +] + +[[package]] +name = "winapi-i686-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" + +[[package]] +name = "winapi-x86_64-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" diff --git a/ravedude/Cargo.toml b/ravedude/Cargo.toml new file mode 100644 index 0000000000..0a9b901988 --- /dev/null +++ b/ravedude/Cargo.toml @@ -0,0 +1,23 @@ +[package] +name = "ravedude" +version = "0.1.2" +authors = ["Rahix "] +edition = "2018" +description = "Tool to easily flash code onto an AVR microcontroller with avrdude" +readme = "README.md" +repository = "https://github.com/Rahix/avr-hal/tree/next/ravedude" +license = "MIT OR Apache-2.0" +keywords = ["avr", "arduino", "avrdude"] +categories = ["embedded", "hardware-support", "development-tools"] + +[dependencies] +colored = "2.0.0" +tempfile = "3.2.0" +serialport = "4.0.0" +anyhow = "1.0.38" +git-version = "0.3.4" + +[dependencies.structopt] +version = "0.3.21" +default-features = false +features = ["color"] diff --git a/ravedude/README.md b/ravedude/README.md new file mode 100644 index 0000000000..5343a73af2 --- /dev/null +++ b/ravedude/README.md @@ -0,0 +1,101 @@ +ravedude +======== +`ravedude` is a CLI utility to make Rust development for AVR microcontrollers +super smooth. It's a wrapper around `avrdude` and provides easy access to the +target's serial console, similar to the Arduino IDE. + +`ravedude` is meant to be used as a cargo "runner". This allows you to just use +`cargo run` for building, deploying, and running your AVR code! + +## Installation +On Linux systems, you'll need pkg-config and libudev development files +installed: + +- *Archlinux*: `pacman -S systemd pkgconf` +- *Ubuntu/Debian*: `apt install libudev-dev pkg-config` +- *Fedora*: `dnf install systemd-devel pkgconf-pkg-config` + +Next, install the latest version from crates.io with the following command: + +```bash +cargo install ravedude +``` + +Now you need to add *ravedude* to your project. For example in a project for +Arduino Uno, place the following into your `.cargo/config.toml` (**not in +`Cargo.toml`**): + +```toml +[target.'cfg(target_arch = "avr")'] +runner = "ravedude uno --open-console --baudrate 57600" +``` + +And that's all, now just call `cargo run` and watch it do its magic: + +
avr-hal/examples/arduino-uno on ravedude via v1.51.0-nightly 
+ cargo run --bin uno-i2cdetect
+   Compiling arduino-uno-examples v0.0.0 (avr-hal/examples/arduino-uno)
+    Finished dev [optimized + debuginfo] target(s) in 1.26s
+     Running `ravedude uno -cb 57600 avr-hal/target/avr-atmega328p/debug/uno-i2cdetect.elf`
+       Board Arduino Uno
+ Programming avr-hal/target/avr-atmega328p/debug/uno-i2cdetect.elf => /dev/ttyACM0
+
+avrdude: AVR device initialized and ready to accept instructions
+
+Reading | ################################################## | 100% 0.00s
+
+avrdude: Device signature = 0x1e950f (probably m328p)
+avrdude: erasing chip
+avrdude: reading input file "avr-hal/target/avr-atmega328p/debug/uno-i2cdetect.elf"
+avrdude: writing flash (1654 bytes):
+
+Writing | ################################################## | 100% 0.27s
+
+avrdude: 1654 bytes of flash written
+avrdude: verifying flash memory against avr-hal/target/avr-atmega328p/debug/uno-i2cdetect.elf:
+avrdude: load data flash data from input file avr-hal/target/avr-atmega328p/debug/uno-i2cdetect.elf:
+avrdude: input file avr-hal/target/avr-atmega328p/debug/uno-i2cdetect.elf contains 1654 bytes
+avrdude: reading on-chip flash data:
+
+Reading | ################################################## | 100% 0.21s
+
+avrdude: verifying ...
+avrdude: 1654 bytes of flash verified
+
+avrdude: safemode: Fuses OK (E:00, H:00, L:00)
+
+avrdude done.  Thank you.
+
+  Programmed avr-hal/target/avr-atmega328p/debug/uno-i2cdetect.elf
+     Console /dev/ttyACM0 at 57600 baud
+
+Write direction test:
+-    0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f
+00:       -- -- -- -- -- -- -- -- -- -- -- -- -- --
+10: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
+20: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
+30: -- -- -- -- -- -- -- -- 38 39 -- -- -- -- -- --
+40: -- -- -- -- -- -- -- -- 48 -- -- -- -- -- -- --
+50: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
+60: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
+70: -- -- -- -- -- -- -- --
+
+Read direction test:
+-    0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f
+00:       -- -- -- -- -- -- -- -- -- -- -- -- -- --
+10: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
+20: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
+30: -- -- -- -- -- -- -- -- 38 39 -- -- -- -- -- --
+40: -- -- -- -- -- -- -- -- 48 -- -- -- -- -- -- --
+50: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
+60: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
+70: -- -- -- -- -- -- -- --
+
+ +## License +*ravedude* is licensed under either of + + * Apache License, Version 2.0 ([LICENSE-APACHE](../LICENSE-APACHE) or http://www.apache.org/licenses/LICENSE-2.0) + * MIT license ([LICENSE-MIT](../LICENSE-MIT) or http://opensource.org/licenses/MIT) + +at your option. diff --git a/ravedude/rust-toolchain.toml b/ravedude/rust-toolchain.toml new file mode 100644 index 0000000000..2fc3eef24c --- /dev/null +++ b/ravedude/rust-toolchain.toml @@ -0,0 +1,3 @@ +[toolchain] +channel = "stable" +profile = "minimal" diff --git a/ravedude/src/avrdude/avrdude.conf b/ravedude/src/avrdude/avrdude.conf new file mode 100644 index 0000000000..32110344d4 --- /dev/null +++ b/ravedude/src/avrdude/avrdude.conf @@ -0,0 +1,14972 @@ +# $Id: avrdude.conf.in 1371 2016-02-15 20:15:07Z joerg_wunsch $ -*- text -*- +# +# AVRDUDE Configuration File +# +# This file contains configuration data used by AVRDUDE which describes +# the programming hardware pinouts and also provides part definitions. +# AVRDUDE's "-C" command line option specifies the location of the +# configuration file. The "-c" option names the programmer configuration +# which must match one of the entry's "id" parameter. The "-p" option +# identifies which part AVRDUDE is going to be programming and must match +# one of the parts' "id" parameter. +# +# DO NOT MODIFY THIS FILE. Modifications will be overwritten the next +# time a "make install" is run. For user-specific additions, use the +# "-C +filename" commandline option. +# +# Possible entry formats are: +# +# programmer +# parent # optional parent +# id = [, [, ] ...] ; # are quoted strings +# desc = ; # quoted string +# type = ; # programmer type, quoted string +# # supported programmer types can be listed by "-c ?type" +# connection_type = parallel | serial | usb +# baudrate = ; # baudrate for avr910-programmer +# vcc = [, ... ] ; # pin number(s) +# buff = [, ... ] ; # pin number(s) +# reset = ; # pin number +# sck = ; # pin number +# mosi = ; # pin number +# miso = ; # pin number +# errled = ; # pin number +# rdyled = ; # pin number +# pgmled = ; # pin number +# vfyled = ; # pin number +# usbvid = ; # USB VID (Vendor ID) +# usbpid = [, ...] # USB PID (Product ID) (1) +# usbdev = ; # USB interface or other device info +# usbvendor = ; # USB Vendor Name +# usbproduct = ; # USB Product Name +# usbsn = ; # USB Serial Number +# +# To invert a bit, use = ~ , the spaces are important. +# For a pin list all pins must be inverted. +# A single pin can be specified as usual = ~ , for lists +# specify it as follows = ~ ( [, ... ] ) . +# +# (1) Not all programmer types can process a list of PIDs. +# ; +# +# part +# id = ; # quoted string +# desc = ; # quoted string +# has_jtag = ; # part has JTAG i/f +# has_debugwire = ; # part has debugWire i/f +# has_pdi = ; # part has PDI i/f +# has_tpi = ; # part has TPI i/f +# devicecode = ; # deprecated, use stk500_devcode +# stk500_devcode = ; # numeric +# avr910_devcode = ; # numeric +# signature = ; # signature bytes +# usbpid = ; # DFU USB PID +# chip_erase_delay = ; # micro-seconds +# reset = dedicated | io; +# retry_pulse = reset | sck; +# pgm_enable = ; +# chip_erase = ; +# chip_erase_delay = ; # chip erase delay (us) +# # STK500 parameters (parallel programming IO lines) +# pagel = ; # pin name in hex, i.e., 0xD7 +# bs2 = ; # pin name in hex, i.e., 0xA0 +# serial = ; # can use serial downloading +# parallel = ; # can use par. programming +# # STK500v2 parameters, to be taken from Atmel's XML files +# timeout = ; +# stabdelay = ; +# cmdexedelay = ; +# synchloops = ; +# bytedelay = ; +# pollvalue = ; +# pollindex = ; +# predelay = ; +# postdelay = ; +# pollmethod = ; +# mode = ; +# delay = ; +# blocksize = ; +# readsize = ; +# hvspcmdexedelay = ; +# # STK500v2 HV programming parameters, from XML +# pp_controlstack = , , ...; # PP only +# hvsp_controlstack = , , ...; # HVSP only +# hventerstabdelay = ; +# progmodedelay = ; # PP only +# latchcycles = ; +# togglevtg = ; +# poweroffdelay = ; +# resetdelayms = ; +# resetdelayus = ; +# hvleavestabdelay = ; +# resetdelay = ; +# synchcycles = ; # HVSP only +# chiperasepulsewidth = ; # PP only +# chiperasepolltimeout = ; +# chiperasetime = ; # HVSP only +# programfusepulsewidth = ; # PP only +# programfusepolltimeout = ; +# programlockpulsewidth = ; # PP only +# programlockpolltimeout = ; +# # JTAG ICE mkII parameters, also from XML files +# allowfullpagebitstream = ; +# enablepageprogramming = ; +# idr = ; # IO addr of IDR (OCD) reg. +# rampz = ; # IO addr of RAMPZ reg. +# spmcr = ; # mem addr of SPMC[S]R reg. +# eecr = ; # mem addr of EECR reg. +# # (only when != 0x3c) +# is_at90s1200 = ; # AT90S1200 part +# is_avr32 = ; # AVR32 part +# +# memory +# paged = ; # yes / no +# size = ; # bytes +# page_size = ; # bytes +# num_pages = ; # numeric +# min_write_delay = ; # micro-seconds +# max_write_delay = ; # micro-seconds +# readback_p1 = ; # byte value +# readback_p2 = ; # byte value +# pwroff_after_write = ; # yes / no +# read = ; +# write = ; +# read_lo = ; +# read_hi = ; +# write_lo = ; +# write_hi = ; +# loadpage_lo = ; +# loadpage_hi = ; +# writepage = ; +# ; +# ; +# +# If any of the above parameters are not specified, the default value +# of 0 is used for numerics or the empty string ("") for string +# values. If a required parameter is left empty, AVRDUDE will +# complain. +# +# Parts can also inherit parameters from previously defined parts +# using the following syntax. In this case specified integer and +# string values override parameter values from the parent part. New +# memory definitions are added to the definitions inherited from the +# parent. +# +# part parent # quoted string +# id = ; # quoted string +# +# ; +# +# NOTES: +# * 'devicecode' is the device code used by the STK500 (see codes +# listed below) +# * Not all memory types will implement all instructions. +# * AVR Fuse bits and Lock bits are implemented as a type of memory. +# * Example memory types are: +# "flash", "eeprom", "fuse", "lfuse" (low fuse), "hfuse" (high +# fuse), "signature", "calibration", "lock" +# * The memory type specified on the avrdude command line must match +# one of the memory types defined for the specified chip. +# * The pwroff_after_write flag causes avrdude to attempt to +# power the device off and back on after an unsuccessful write to +# the affected memory area if VCC programmer pins are defined. If +# VCC pins are not defined for the programmer, a message +# indicating that the device needs a power-cycle is printed out. +# This flag was added to work around a problem with the +# at90s4433/2333's; see the at90s4433 errata at: +# +# http://www.atmel.com/dyn/resources/prod_documents/doc1280.pdf +# +# INSTRUCTION FORMATS +# +# Instruction formats are specified as a comma seperated list of +# string values containing information (bit specifiers) about each +# of the 32 bits of the instruction. Bit specifiers may be one of +# the following formats: +# +# '1' = the bit is always set on input as well as output +# +# '0' = the bit is always clear on input as well as output +# +# 'x' = the bit is ignored on input and output +# +# 'a' = the bit is an address bit, the bit-number matches this bit +# specifier's position within the current instruction byte +# +# 'aN' = the bit is the Nth address bit, bit-number = N, i.e., a12 +# is address bit 12 on input, a0 is address bit 0. +# +# 'i' = the bit is an input data bit +# +# 'o' = the bit is an output data bit +# +# Each instruction must be composed of 32 bit specifiers. The +# instruction specification closely follows the instruction data +# provided in Atmel's data sheets for their parts. +# +# See below for some examples. +# +# +# The following are STK500 part device codes to use for the +# "devicecode" field of the part. These came from Atmel's software +# section avr061.zip which accompanies the application note +# AVR061 available from: +# +# http://www.atmel.com/dyn/resources/prod_documents/doc2525.pdf +# + +#define ATTINY10 0x10 /* the _old_ one that never existed! */ +#define ATTINY11 0x11 +#define ATTINY12 0x12 +#define ATTINY15 0x13 +#define ATTINY13 0x14 + +#define ATTINY22 0x20 +#define ATTINY26 0x21 +#define ATTINY28 0x22 +#define ATTINY2313 0x23 + +#define AT90S1200 0x33 + +#define AT90S2313 0x40 +#define AT90S2323 0x41 +#define AT90S2333 0x42 +#define AT90S2343 0x43 + +#define AT90S4414 0x50 +#define AT90S4433 0x51 +#define AT90S4434 0x52 +#define ATMEGA48 0x59 + +#define AT90S8515 0x60 +#define AT90S8535 0x61 +#define AT90C8534 0x62 +#define ATMEGA8515 0x63 +#define ATMEGA8535 0x64 + +#define ATMEGA8 0x70 +#define ATMEGA88 0x73 +#define ATMEGA168 0x86 + +#define ATMEGA161 0x80 +#define ATMEGA163 0x81 +#define ATMEGA16 0x82 +#define ATMEGA162 0x83 +#define ATMEGA169 0x84 + +#define ATMEGA323 0x90 +#define ATMEGA32 0x91 + +#define ATMEGA64 0xA0 + +#define ATMEGA103 0xB1 +#define ATMEGA128 0xB2 +#define AT90CAN128 0xB3 +#define AT90CAN64 0xB3 +#define AT90CAN32 0xB3 + +#define AT86RF401 0xD0 + +#define AT89START 0xE0 +#define AT89S51 0xE0 +#define AT89S52 0xE1 + +# The following table lists the devices in the original AVR910 +# appnote: +# |Device |Signature | Code | +# +-------+----------+------+ +# |tiny12 | 1E 90 05 | 0x55 | +# |tiny15 | 1E 90 06 | 0x56 | +# | | | | +# | S1200 | 1E 90 01 | 0x13 | +# | | | | +# | S2313 | 1E 91 01 | 0x20 | +# | S2323 | 1E 91 02 | 0x48 | +# | S2333 | 1E 91 05 | 0x34 | +# | S2343 | 1E 91 03 | 0x4C | +# | | | | +# | S4414 | 1E 92 01 | 0x28 | +# | S4433 | 1E 92 03 | 0x30 | +# | S4434 | 1E 92 02 | 0x6C | +# | | | | +# | S8515 | 1E 93 01 | 0x38 | +# | S8535 | 1E 93 03 | 0x68 | +# | | | | +# |mega32 | 1E 95 01 | 0x72 | +# |mega83 | 1E 93 05 | 0x65 | +# |mega103| 1E 97 01 | 0x41 | +# |mega161| 1E 94 01 | 0x60 | +# |mega163| 1E 94 02 | 0x64 | + +# Appnote AVR109 also has a table of AVR910 device codes, which +# lists: +# dev avr910 signature +# ATmega8 0x77 0x1E 0x93 0x07 +# ATmega8515 0x3B 0x1E 0x93 0x06 +# ATmega8535 0x6A 0x1E 0x93 0x08 +# ATmega16 0x75 0x1E 0x94 0x03 +# ATmega162 0x63 0x1E 0x94 0x04 +# ATmega163 0x66 0x1E 0x94 0x02 +# ATmega169 0x79 0x1E 0x94 0x05 +# ATmega32 0x7F 0x1E 0x95 0x02 +# ATmega323 0x73 0x1E 0x95 0x01 +# ATmega64 0x46 0x1E 0x96 0x02 +# ATmega128 0x44 0x1E 0x97 0x02 +# +# These codes refer to "BOOT" device codes which are apparently +# different than standard device codes, for whatever reasons +# (often one above the standard code). + +# There are several extended versions of AVR910 implementations around +# in the Internet. These add the following codes (only devices that +# actually exist are listed): + +# ATmega8515 0x3A +# ATmega128 0x43 +# ATmega64 0x45 +# ATtiny26 0x5E +# ATmega8535 0x69 +# ATmega32 0x72 +# ATmega16 0x74 +# ATmega8 0x76 +# ATmega169 0x78 + +# +# Overall avrdude defaults; suitable for ~/.avrduderc +# +default_parallel = "/dev/parport0"; +default_serial = "/dev/ttyS0"; +# default_bitclock = 2.5; + +# Turn off safemode by default +#default_safemode = no; + + +# +# PROGRAMMER DEFINITIONS +# + +# http://wiring.org.co/ +# Basically STK500v2 protocol, with some glue to trigger the +# bootloader. +programmer + id = "wiring"; + desc = "Wiring"; + type = "wiring"; + connection_type = serial; +; + +programmer + id = "arduino"; + desc = "Arduino"; + type = "arduino"; + connection_type = serial; +; +# this will interface with the chips on these programmers: +# +# http://real.kiev.ua/old/avreal/en/adapters +# http://www.amontec.com/jtagkey.shtml, jtagkey-tiny.shtml +# http://www.olimex.com/dev/arm-usb-ocd.html, arm-usb-tiny.html +# http://www.ethernut.de/en/hardware/turtelizer/index.html +# http://elk.informatik.fh-augsburg.de/hhweb/doc/openocd/usbjtag/usbjtag.html +# http://dangerousprototypes.com/docs/FT2232_breakout_board +# http://www.ftdichip.com/Products/Modules/DLPModules.htm,DLP-2232*,DLP-USB1232H +# http://flashrom.org/FT2232SPI_Programmer +# +# The drivers will look for a specific device and use the first one found. +# If you have mulitple devices, then look for unique information (like SN) +# And fill that in here. +# +# Note that the pin numbers for the main ISP signals (reset, sck, +# mosi, miso) are fixed and cannot be changed, since they must match +# the way the Multi-Protocol Synchronous Serial Engine (MPSSE) of +# these FTDI ICs has been designed. + +programmer + id = "avrftdi"; + desc = "FT2232D based generic programmer"; + type = "avrftdi"; + connection_type = usb; + usbvid = 0x0403; + usbpid = 0x6010; + usbvendor = ""; + usbproduct = ""; + usbdev = "A"; + usbsn = ""; +#ISP-signals - lower ADBUS-Nibble (default) + reset = 3; + sck = 0; + mosi = 1; + miso = 2; +#LED SIGNALs - higher ADBUS-Nibble +# errled = 4; +# rdyled = 5; +# pgmled = 6; +# vfyled = 7; +#Buffer Signal - ACBUS - Nibble +# buff = 8; +; +# This is an implementation of the above with a buffer IC (74AC244) and +# 4 LEDs directly attached, all active low. +programmer + id = "2232HIO"; + desc = "FT2232H based generic programmer"; + type = "avrftdi"; + connection_type = usb; + usbvid = 0x0403; +# Note: This PID is reserved for generic H devices and +# should be programmed into the EEPROM +# usbpid = 0x8A48; + usbpid = 0x6010; + usbdev = "A"; + usbvendor = ""; + usbproduct = ""; + usbsn = ""; +#ISP-signals + reset = 3; + sck = 0; + mosi = 1; + miso = 2; + buff = ~4; +#LED SIGNALs + errled = ~ 11; + rdyled = ~ 14; + pgmled = ~ 13; + vfyled = ~ 12; +; + +#The FT4232H can be treated as FT2232H, but it has a different USB +#device ID of 0x6011. +programmer parent "avrftdi" + id = "4232h"; + desc = "FT4232H based generic programmer"; + usbpid = 0x6011; +; + +programmer + id = "jtagkey"; + desc = "Amontec JTAGKey, JTAGKey-Tiny and JTAGKey2"; + type = "avrftdi"; + connection_type = usb; + usbvid = 0x0403; +# Note: This PID is used in all JTAGKey variants + usbpid = 0xCFF8; + usbdev = "A"; + usbvendor = ""; + usbproduct = ""; + usbsn = ""; +#ISP-signals => 20 - Pin connector on JTAGKey + reset = 3; # TMS 7 violet + sck = 0; # TCK 9 white + mosi = 1; # TDI 5 green + miso = 2; # TDO 13 orange + buff = ~4; +# VTG VREF 1 brown with red tip +# GND GND 20 black +# The colors are on the 20 pin breakout cable +# from Amontec +; + +# UM232H module from FTDI and Glyn.com.au. +# See helix.air.net.au for detailed usage information. +# J1: Connect pin 2 and 3 for USB power. +# J2: Connect pin 2 and 3 for USB power. +# J2: Pin 7 is SCK +# : Pin 8 is MOSI +# : Pin 9 is MISO +# : Pin 11 is RST +# : Pin 6 is ground +# Use the -b flag to set the SPI clock rate eg -b 3750000 is the fastest I could get +# a 16MHz Atmega1280 to program reliably. The 232H is conveniently 5V tolerant. +programmer + id = "UM232H"; + desc = "FT232H based module from FTDI and Glyn.com.au"; + type = "avrftdi"; + usbvid = 0x0403; +# Note: This PID is reserved for generic 232H devices and +# should be programmed into the EEPROM + usbpid = 0x6014; + usbdev = "A"; + usbvendor = ""; + usbproduct = ""; + usbsn = ""; +#ISP-signals + sck = 0; + mosi = 1; + miso = 2; + reset = 3; +; + +# C232HM module from FTDI and Glyn.com.au. +# : Orange is SCK +# : Yellow is MOSI +# : Green is MISO +# : Brown is RST +# : Black is ground +# Use the -b flag to set the SPI clock rate eg -b 3750000 is the fastest I could get +# a 16MHz Atmega1280 to program reliably. The 232H is conveniently 5V tolerant. +programmer + id = "C232HM"; + desc = "FT232H based module from FTDI and Glyn.com.au"; + type = "avrftdi"; + usbvid = 0x0403; +# Note: This PID is reserved for generic 232H devices and +# should be programmed into the EEPROM + usbpid = 0x6014; + usbdev = "A"; + usbvendor = ""; + usbproduct = ""; + usbsn = ""; +#ISP-signals + sck = 0; + mosi = 1; + miso = 2; + reset = 3; +; + + +# On the adapter you can read "O-Link". On the PCB is printed "OpenJTAG v3.1" +# You can find it as "OpenJTAG ARM JTAG USB" in the internet. +# (But there are also several projects called Open JTAG, eg. +# http://www.openjtag.org, which are completely different.) +# http://www.100ask.net/shop/english.html (website seems to be outdated) +# http://item.taobao.com/item.htm?id=1559277013 +# http://www.micro4you.com/store/openjtag-arm-jtag-usb.html (schematics!) +# some other sources which call it O-Link +# http://www.andahammer.com/olink/ +# http://www.developmentboard.net/31-o-link-debugger.html +# http://armwerks.com/catalog/o-link-debugger-copy/ +# or just have a look at ebay ... +# It is basically the same entry as jtagkey with different usb ids. +programmer parent "jtagkey" + id = "o-link"; + desc = "O-Link, OpenJTAG from www.100ask.net"; + usbvid = 0x1457; + usbpid = 0x5118; + usbvendor = "www.100ask.net"; + usbproduct = "USB<=>JTAG&RS232"; +; + +# http://wiki.openmoko.org/wiki/Debug_Board_v3 +programmer + id = "openmoko"; + desc = "Openmoko debug board (v3)"; + type = "avrftdi"; + usbvid = 0x1457; + usbpid = 0x5118; + usbdev = "A"; + usbvendor = ""; + usbproduct = ""; + usbsn = ""; + reset = 3; # TMS 7 + sck = 0; # TCK 9 + mosi = 1; # TDI 5 + miso = 2; # TDO 13 +; + +# Only Rev. A boards. +# Schematic and user manual: http://www.cs.put.poznan.pl/wswitala/download/pdf/811EVBK.pdf +programmer + id = "lm3s811"; + desc = "Luminary Micro LM3S811 Eval Board (Rev. A)"; + type = "avrftdi"; + connection_type = usb; + usbvid = 0x0403; + usbpid = 0xbcd9; + usbvendor = "LMI"; + usbproduct = "LM3S811 Evaluation Board"; + usbdev = "A"; + usbsn = ""; +#ISP-signals - lower ACBUS-Nibble (default) + reset = 3; + sck = 0; + mosi = 1; + miso = 2; +# Enable correct buffers + buff = 7; +; + +# submitted as bug #46020 +programmer + id = "tumpa"; + desc = "TIAO USB Multi-Protocol Adapter"; + type = "avrftdi"; + connection_type = usb; + usbvid = 0x0403; + usbpid = 0x8A98; + usbdev = "A"; + usbvendor = "TIAO"; + usbproduct = ""; + usbsn = ""; + sck = 0; # TCK 9 + mosi = 1; # TDI 5 + miso = 2; # TDO 13 + reset = 3; # TMS 7 +; + +programmer + id = "avrisp"; + desc = "Atmel AVR ISP"; + type = "stk500"; + connection_type = serial; +; + +programmer + id = "avrispv2"; + desc = "Atmel AVR ISP V2"; + type = "stk500v2"; + connection_type = serial; +; + +programmer + id = "avrispmkII"; + desc = "Atmel AVR ISP mkII"; + type = "stk500v2"; + connection_type = usb; +; + +programmer parent "avrispmkII" + id = "avrisp2"; +; + +programmer + id = "buspirate"; + desc = "The Bus Pirate"; + type = "buspirate"; + connection_type = serial; +; + +programmer + id = "buspirate_bb"; + desc = "The Bus Pirate (bitbang interface, supports TPI)"; + type = "buspirate_bb"; + connection_type = serial; + # pins are bits in bitbang byte (numbers are 87654321) + # 1|POWER|PULLUP|AUX|MOSI|CLK|MISO|CS + reset = 1; + sck = 3; + mosi = 4; + miso = 2; + #vcc = 7; This is internally set independent of this setting. +; + +# This is supposed to be the "default" STK500 entry. +# Attempts to select the correct firmware version +# by probing for it. Better use one of the entries +# below instead. +programmer + id = "stk500"; + desc = "Atmel STK500"; + type = "stk500generic"; + connection_type = serial; +; + +programmer + id = "stk500v1"; + desc = "Atmel STK500 Version 1.x firmware"; + type = "stk500"; + connection_type = serial; +; + +programmer + id = "mib510"; + desc = "Crossbow MIB510 programming board"; + type = "stk500"; + connection_type = serial; +; + +programmer + id = "stk500v2"; + desc = "Atmel STK500 Version 2.x firmware"; + type = "stk500v2"; + connection_type = serial; +; + +programmer + id = "stk500pp"; + desc = "Atmel STK500 V2 in parallel programming mode"; + type = "stk500pp"; + connection_type = serial; +; + +programmer + id = "stk500hvsp"; + desc = "Atmel STK500 V2 in high-voltage serial programming mode"; + type = "stk500hvsp"; + connection_type = serial; +; + +programmer + id = "stk600"; + desc = "Atmel STK600"; + type = "stk600"; + connection_type = usb; +; + +programmer + id = "stk600pp"; + desc = "Atmel STK600 in parallel programming mode"; + type = "stk600pp"; + connection_type = usb; +; + +programmer + id = "stk600hvsp"; + desc = "Atmel STK600 in high-voltage serial programming mode"; + type = "stk600hvsp"; + connection_type = usb; +; + +programmer + id = "avr910"; + desc = "Atmel Low Cost Serial Programmer"; + type = "avr910"; + connection_type = serial; +; + +programmer + id = "ft245r"; + desc = "FT245R Synchronous BitBang"; + type = "ftdi_syncbb"; + connection_type = usb; + miso = 1; # D1 + sck = 0; # D0 + mosi = 2; # D2 + reset = 4; # D4 +; + +programmer + id = "ft232r"; + desc = "FT232R Synchronous BitBang"; + type = "ftdi_syncbb"; + connection_type = usb; + miso = 1; # RxD + sck = 0; # TxD + mosi = 2; # RTS + reset = 4; # DTR +; + +# see http://www.bitwizard.nl/wiki/index.php/FTDI_ATmega +programmer + id = "bwmega"; + desc = "BitWizard ftdi_atmega builtin programmer"; + type = "ftdi_syncbb"; + connection_type = usb; + miso = 5; # DSR + sck = 6; # DCD + mosi = 3; # CTS + reset = 7; # RI +; + +# see http://www.geocities.jp/arduino_diecimila/bootloader/index_en.html +# Note: pins are numbered from 1! +programmer + id = "arduino-ft232r"; + desc = "Arduino: FT232R connected to ISP"; + type = "ftdi_syncbb"; + connection_type = usb; + miso = 3; # CTS X3(1) + sck = 5; # DSR X3(2) + mosi = 6; # DCD X3(3) + reset = 7; # RI X3(4) +; + +# website mentioned above uses this id +programmer parent "arduino-ft232r" + id = "diecimila"; + desc = "alias for arduino-ft232r"; +; + +# There is a ATmega328P kit PCB called "uncompatino". +# This board allows ISP via its on-board FT232R. +# This is designed like Arduino Duemilanove but has no standard ICPS header. +# Its 4 pairs of pins are shorted to enable ftdi_syncbb. +# http://akizukidenshi.com/catalog/g/gP-07487/ +# http://akizukidenshi.com/download/ds/akizuki/k6096_manual_20130816.pdf +programmer + id = "uncompatino"; + desc = "uncompatino with all pairs of pins shorted"; + type = "ftdi_syncbb"; + connection_type = usb; + miso = 3; # cts + sck = 5; # dsr + mosi = 6; # dcd + reset = 7; # ri +; + +# FTDI USB to serial cable TTL-232R-5V with a custom adapter for ICSP +# http://www.ftdichip.com/Products/Cables/USBTTLSerial.htm +# http://www.ftdichip.com/Support/Documents/DataSheets/Cables/DS_TTL-232R_CABLES.pdf +# For ICSP pinout see for example http://www.atmel.com/images/doc2562.pdf +# (Figure 1. ISP6PIN header pinout and Table 1. Connections required for ISP ...) +# TTL-232R GND 1 Black -> ICPS GND (pin 6) +# TTL-232R CTS 2 Brown -> ICPS MOSI (pin 4) +# TTL-232R VCC 3 Red -> ICPS VCC (pin 2) +# TTL-232R TXD 4 Orange -> ICPS RESET (pin 5) +# TTL-232R RXD 5 Yellow -> ICPS SCK (pin 3) +# TTL-232R RTS 6 Green -> ICPS MISO (pin 1) +# Except for VCC and GND, you can connect arbitual pairs as long as +# the following table is adjusted. +programmer + id = "ttl232r"; + desc = "FTDI TTL232R-5V with ICSP adapter"; + type = "ftdi_syncbb"; + connection_type = usb; + miso = 2; # rts + sck = 1; # rxd + mosi = 3; # cts + reset = 0; # txd +; + +programmer + id = "usbasp"; + desc = "USBasp, http://www.fischl.de/usbasp/"; + type = "usbasp"; + connection_type = usb; + usbvid = 0x16C0; # VOTI + usbpid = 0x05DC; # Obdev's free shared PID + usbvendor = "www.fischl.de"; + usbproduct = "USBasp"; + + # following variants are autodetected for id "usbasp" + + # original usbasp from fischl.de + # see above "usbasp" + + # old usbasp from fischl.de + #usbvid = 0x03EB; # ATMEL + #usbpid = 0xC7B4; # (unoffical) USBasp + #usbvendor = "www.fischl.de"; + #usbproduct = "USBasp"; + + # NIBObee (only if -P nibobee is given on command line) + # see below "nibobee" +; + +programmer + id = "nibobee"; + desc = "NIBObee"; + type = "usbasp"; + connection_type = usb; + usbvid = 0x16C0; # VOTI + usbpid = 0x092F; # NIBObee PID + usbvendor = "www.nicai-systems.com"; + usbproduct = "NIBObee"; +; + +programmer + id = "usbasp-clone"; + desc = "Any usbasp clone with correct VID/PID"; + type = "usbasp"; + connection_type = usb; + usbvid = 0x16C0; # VOTI + usbpid = 0x05DC; # Obdev's free shared PID + #usbvendor = ""; + #usbproduct = ""; +; + +programmer + id = "usbtiny"; + desc = "USBtiny simple USB programmer, http://www.ladyada.net/make/usbtinyisp/"; + type = "usbtiny"; + connection_type = usb; + usbvid = 0x1781; + usbpid = 0x0c9f; +; + +programmer + id = "butterfly"; + desc = "Atmel Butterfly Development Board"; + type = "butterfly"; + connection_type = serial; +; + +programmer + id = "avr109"; + desc = "Atmel AppNote AVR109 Boot Loader"; + type = "butterfly"; + connection_type = serial; +; + +programmer + id = "avr911"; + desc = "Atmel AppNote AVR911 AVROSP"; + type = "butterfly"; + connection_type = serial; +; + +# suggested in http://forum.mikrokopter.de/topic-post48317.html +programmer + id = "mkbutterfly"; + desc = "Mikrokopter.de Butterfly"; + type = "butterfly_mk"; + connection_type = serial; +; + +programmer parent "mkbutterfly" + id = "butterfly_mk"; +; + +programmer + id = "jtagmkI"; + desc = "Atmel JTAG ICE (mkI)"; + baudrate = 115200; # default is 115200 + type = "jtagmki"; + connection_type = serial; +; + +# easier to type +programmer parent "jtagmkI" + id = "jtag1"; +; + +# easier to type +programmer parent "jtag1" + id = "jtag1slow"; + baudrate = 19200; +; + +# The JTAG ICE mkII has both, serial and USB connectivity. As it is +# mostly used through USB these days (AVR Studio 5 only supporting it +# that way), we make connection_type = usb the default. Users are +# still free to use a serial port with the -P option. + +programmer + id = "jtagmkII"; + desc = "Atmel JTAG ICE mkII"; + baudrate = 19200; # default is 19200 + type = "jtagmkii"; + connection_type = usb; +; + +# easier to type +programmer parent "jtagmkII" + id = "jtag2slow"; +; + +# JTAG ICE mkII @ 115200 Bd +programmer parent "jtag2slow" + id = "jtag2fast"; + baudrate = 115200; +; + +# make the fast one the default, people will love that +programmer parent "jtag2fast" + id = "jtag2"; +; + +# JTAG ICE mkII in ISP mode +programmer + id = "jtag2isp"; + desc = "Atmel JTAG ICE mkII in ISP mode"; + baudrate = 115200; + type = "jtagmkii_isp"; + connection_type = usb; +; + +# JTAG ICE mkII in debugWire mode +programmer + id = "jtag2dw"; + desc = "Atmel JTAG ICE mkII in debugWire mode"; + baudrate = 115200; + type = "jtagmkii_dw"; + connection_type = usb; +; + +# JTAG ICE mkII in AVR32 mode +programmer + id = "jtagmkII_avr32"; + desc = "Atmel JTAG ICE mkII im AVR32 mode"; + baudrate = 115200; + type = "jtagmkii_avr32"; + connection_type = usb; +; + +# JTAG ICE mkII in AVR32 mode +programmer + id = "jtag2avr32"; + desc = "Atmel JTAG ICE mkII im AVR32 mode"; + baudrate = 115200; + type = "jtagmkii_avr32"; + connection_type = usb; +; + +# JTAG ICE mkII in PDI mode +programmer + id = "jtag2pdi"; + desc = "Atmel JTAG ICE mkII PDI mode"; + baudrate = 115200; + type = "jtagmkii_pdi"; + connection_type = usb; +; + +# AVR Dragon in JTAG mode +programmer + id = "dragon_jtag"; + desc = "Atmel AVR Dragon in JTAG mode"; + baudrate = 115200; + type = "dragon_jtag"; + connection_type = usb; +; + +# AVR Dragon in ISP mode +programmer + id = "dragon_isp"; + desc = "Atmel AVR Dragon in ISP mode"; + baudrate = 115200; + type = "dragon_isp"; + connection_type = usb; +; + +# AVR Dragon in PP mode +programmer + id = "dragon_pp"; + desc = "Atmel AVR Dragon in PP mode"; + baudrate = 115200; + type = "dragon_pp"; + connection_type = usb; +; + +# AVR Dragon in HVSP mode +programmer + id = "dragon_hvsp"; + desc = "Atmel AVR Dragon in HVSP mode"; + baudrate = 115200; + type = "dragon_hvsp"; + connection_type = usb; +; + +# AVR Dragon in debugWire mode +programmer + id = "dragon_dw"; + desc = "Atmel AVR Dragon in debugWire mode"; + baudrate = 115200; + type = "dragon_dw"; + connection_type = usb; +; + +# AVR Dragon in PDI mode +programmer + id = "dragon_pdi"; + desc = "Atmel AVR Dragon in PDI mode"; + baudrate = 115200; + type = "dragon_pdi"; + connection_type = usb; +; + +programmer + id = "jtag3"; + desc = "Atmel AVR JTAGICE3 in JTAG mode"; + type = "jtagice3"; + connection_type = usb; + usbpid = 0x2110, 0x2140; +; + +programmer + id = "jtag3pdi"; + desc = "Atmel AVR JTAGICE3 in PDI mode"; + type = "jtagice3_pdi"; + connection_type = usb; + usbpid = 0x2110, 0x2140; +; + +programmer + id = "jtag3dw"; + desc = "Atmel AVR JTAGICE3 in debugWIRE mode"; + type = "jtagice3_dw"; + connection_type = usb; + usbpid = 0x2110, 0x2140; +; + +programmer + id = "jtag3isp"; + desc = "Atmel AVR JTAGICE3 in ISP mode"; + type = "jtagice3_isp"; + connection_type = usb; + usbpid = 0x2110, 0x2140; +; + +programmer + id = "xplainedpro"; + desc = "Atmel AVR XplainedPro in JTAG mode"; + type = "jtagice3"; + connection_type = usb; + usbpid = 0x2111; +; + +programmer + id = "xplainedmini"; + desc = "Atmel AVR XplainedMini in ISP mode"; + type = "jtagice3_isp"; + connection_type = usb; + usbpid = 0x2145; +; + +programmer + id = "xplainedmini_dw"; + desc = "Atmel AVR XplainedMini in debugWIRE mode"; + type = "jtagice3_dw"; + connection_type = usb; + usbpid = 0x2145; +; + +programmer + id = "atmelice"; + desc = "Atmel-ICE (ARM/AVR) in JTAG mode"; + type = "jtagice3"; + connection_type = usb; + usbpid = 0x2141; +; + +programmer + id = "atmelice_pdi"; + desc = "Atmel-ICE (ARM/AVR) in PDI mode"; + type = "jtagice3_pdi"; + connection_type = usb; + usbpid = 0x2141; +; + +programmer + id = "atmelice_dw"; + desc = "Atmel-ICE (ARM/AVR) in debugWIRE mode"; + type = "jtagice3_dw"; + connection_type = usb; + usbpid = 0x2141; +; + +programmer + id = "atmelice_isp"; + desc = "Atmel-ICE (ARM/AVR) in ISP mode"; + type = "jtagice3_isp"; + connection_type = usb; + usbpid = 0x2141; +; + + +programmer + id = "pavr"; + desc = "Jason Kyle's pAVR Serial Programmer"; + type = "avr910"; + connection_type = serial; +; + +programmer + id = "pickit2"; + desc = "MicroChip's PICkit2 Programmer"; + type = "pickit2"; + connection_type = usb; +; + +programmer + id = "flip1"; + desc = "FLIP USB DFU protocol version 1 (doc7618)"; + type = "flip1"; + connection_type = usb; +; + +programmer + id = "flip2"; + desc = "FLIP USB DFU protocol version 2 (AVR4023)"; + type = "flip2"; + connection_type = usb; +; + +# Parallel port programmers. + +programmer + id = "bsd"; + desc = "Brian Dean's Programmer, http://www.bsdhome.com/avrdude/"; + type = "par"; + connection_type = parallel; + vcc = 2, 3, 4, 5; + reset = 7; + sck = 8; + mosi = 9; + miso = 10; +; + +programmer + id = "stk200"; + desc = "STK200"; + type = "par"; + connection_type = parallel; + buff = 4, 5; + sck = 6; + mosi = 7; + reset = 9; + miso = 10; +; + +# The programming dongle used by the popular Ponyprog +# utility. It is almost similar to the STK200 one, +# except that there is a LED indicating that the +# programming is currently in progress. + +programmer parent "stk200" + id = "pony-stk200"; + desc = "Pony Prog STK200"; + pgmled = 8; +; + +programmer + id = "dt006"; + desc = "Dontronics DT006"; + type = "par"; + connection_type = parallel; + reset = 4; + sck = 5; + mosi = 2; + miso = 11; +; + +programmer parent "dt006" + id = "bascom"; + desc = "Bascom SAMPLE programming cable"; +; + +programmer + id = "alf"; + desc = "Nightshade ALF-PgmAVR, http://nightshade.homeip.net/"; + type = "par"; + connection_type = parallel; + vcc = 2, 3, 4, 5; + buff = 6; + reset = 7; + sck = 8; + mosi = 9; + miso = 10; + errled = 1; + rdyled = 14; + pgmled = 16; + vfyled = 17; +; + +programmer + id = "sp12"; + desc = "Steve Bolt's Programmer"; + type = "par"; + connection_type = parallel; + vcc = 4,5,6,7,8; + reset = 3; + sck = 2; + mosi = 9; + miso = 11; +; + +programmer + id = "picoweb"; + desc = "Picoweb Programming Cable, http://www.picoweb.net/"; + type = "par"; + connection_type = parallel; + reset = 2; + sck = 3; + mosi = 4; + miso = 13; +; + +programmer + id = "abcmini"; + desc = "ABCmini Board, aka Dick Smith HOTCHIP"; + type = "par"; + connection_type = parallel; + reset = 4; + sck = 3; + mosi = 2; + miso = 10; +; + +programmer + id = "futurlec"; + desc = "Futurlec.com programming cable."; + type = "par"; + connection_type = parallel; + reset = 3; + sck = 2; + mosi = 1; + miso = 10; +; + + +# From the contributor of the "xil" jtag cable: +# The "vcc" definition isn't really vcc (the cable gets its power from +# the programming circuit) but is necessary to switch one of the +# buffer lines (trying to add it to the "buff" lines doesn't work in +# avrdude versions before 5.5j). +# With this, TMS connects to RESET, TDI to MOSI, TDO to MISO and TCK +# to SCK (plus vcc/gnd of course) +programmer + id = "xil"; + desc = "Xilinx JTAG cable"; + type = "par"; + connection_type = parallel; + mosi = 2; + sck = 3; + reset = 4; + buff = 5; + miso = 13; + vcc = 6; +; + + +programmer + id = "dapa"; + desc = "Direct AVR Parallel Access cable"; + type = "par"; + connection_type = parallel; + vcc = 3; + reset = 16; + sck = 1; + mosi = 2; + miso = 11; +; + +programmer + id = "atisp"; + desc = "AT-ISP V1.1 programming cable for AVR-SDK1 from micro-research.co.th"; + type = "par"; + connection_type = parallel; + reset = ~6; + sck = ~8; + mosi = ~7; + miso = ~10; +; + +programmer + id = "ere-isp-avr"; + desc = "ERE ISP-AVR "; + type = "par"; + connection_type = parallel; + reset = ~4; + sck = 3; + mosi = 2; + miso = 10; +; + +programmer + id = "blaster"; + desc = "Altera ByteBlaster"; + type = "par"; + connection_type = parallel; + sck = 2; + miso = 11; + reset = 3; + mosi = 8; + buff = 14; +; + +# It is almost same as pony-stk200, except vcc on pin 5 to auto +# disconnect port (download on http://electropol.free.fr/spip/spip.php?article27) +programmer parent "pony-stk200" + id = "frank-stk200"; + desc = "Frank STK200"; + buff = ; # delete buff pin assignment + vcc = 5; +; + +# The AT98ISP Cable is a simple parallel dongle for AT89 family. +# http://www.atmel.com/dyn/products/tools_card.asp?tool_id=2877 +programmer + id = "89isp"; + desc = "Atmel at89isp cable"; + type = "par"; + connection_type = parallel; + reset = 17; + sck = 1; + mosi = 2; + miso = 10; +; + + +#This programmer bitbangs GPIO lines using the Linux sysfs GPIO interface +# +#To enable it set the configuration below to match the GPIO lines connected to the +#relevant ISP header pins and uncomment the entry definition. In case you don't +#have the required permissions to edit this system wide config file put the +#entry in a separate .conf file and use it with -C+.conf +#on the command line. +# +#To check if your avrdude build has support for the linuxgpio programmer compiled in, +#use -c?type on the command line and look for linuxgpio in the list. If it's not available +#you need pass the --enable-linuxgpio=yes option to configure and recompile avrdude. +# +#programmer +# id = "linuxgpio"; +# desc = "Use the Linux sysfs interface to bitbang GPIO lines"; +# type = "linuxgpio"; +# reset = ?; +# sck = ?; +# mosi = ?; +# miso = ?; +#; + +# some ultra cheap programmers use bitbanging on the +# serialport. +# +# PC - DB9 - Pins for RS232: +# +# GND 5 -- |O +# | O| <- 9 RI +# DTR 4 <- |O | +# | O| <- 8 CTS +# TXD 3 <- |O | +# | O| -> 7 RTS +# RXD 2 -> |O | +# | O| <- 6 DSR +# DCD 1 -> |O +# +# Using RXD is currently not supported. +# Using RI is not supported under Win32 but is supported under Posix. + +# serial ponyprog design (dasa2 in uisp) +# reset=!txd sck=rts mosi=dtr miso=cts + +programmer + id = "ponyser"; + desc = "design ponyprog serial, reset=!txd sck=rts mosi=dtr miso=cts"; + type = "serbb"; + connection_type = serial; + reset = ~3; + sck = 7; + mosi = 4; + miso = 8; +; + +# Same as above, different name +# reset=!txd sck=rts mosi=dtr miso=cts + +programmer parent "ponyser" + id = "siprog"; + desc = "Lancos SI-Prog "; +; + +# unknown (dasa in uisp) +# reset=rts sck=dtr mosi=txd miso=cts + +programmer + id = "dasa"; + desc = "serial port banging, reset=rts sck=dtr mosi=txd miso=cts"; + type = "serbb"; + connection_type = serial; + reset = 7; + sck = 4; + mosi = 3; + miso = 8; +; + +# unknown (dasa3 in uisp) +# reset=!dtr sck=rts mosi=txd miso=cts + +programmer + id = "dasa3"; + desc = "serial port banging, reset=!dtr sck=rts mosi=txd miso=cts"; + type = "serbb"; + connection_type = serial; + reset = ~4; + sck = 7; + mosi = 3; + miso = 8; +; + +# C2N232i (jumper configuration "auto") +# reset=dtr sck=!rts mosi=!txd miso=!cts + +programmer + id = "c2n232i"; + desc = "serial port banging, reset=dtr sck=!rts mosi=!txd miso=!cts"; + type = "serbb"; + connection_type = serial; + reset = 4; + sck = ~7; + mosi = ~3; + miso = ~8; +; + +# +# PART DEFINITIONS +# + +#------------------------------------------------------------ +# ATtiny11 +#------------------------------------------------------------ + +# This is an HVSP-only device. + +part + id = "t11"; + desc = "ATtiny11"; + stk500_devcode = 0x11; + signature = 0x1e 0x90 0x04; + chip_erase_delay = 20000; + + timeout = 200; + hvsp_controlstack = + 0x4C, 0x0C, 0x1C, 0x2C, 0x3C, 0x64, 0x74, 0x00, + 0x68, 0x78, 0x68, 0x68, 0x00, 0x00, 0x68, 0x78, + 0x78, 0x00, 0x6D, 0x0C, 0x80, 0x40, 0x20, 0x10, + 0x11, 0x08, 0x04, 0x02, 0x03, 0x08, 0x04, 0x00; + hventerstabdelay = 100; + progmodedelay = 0; + hvspcmdexedelay = 0; + synchcycles = 6; + latchcycles = 1; + togglevtg = 1; + poweroffdelay = 25; + resetdelayms = 0; + resetdelayus = 50; + hvleavestabdelay = 100; + resetdelay = 25; + chiperasepolltimeout = 40; + chiperasetime = 0; + programfusepolltimeout = 25; + programlockpolltimeout = 25; + + memory "eeprom" + size = 64; + blocksize = 64; + readsize = 256; + delay = 5; + ; + + memory "flash" + size = 1024; + blocksize = 128; + readsize = 256; + delay = 3; + ; + + memory "signature" + size = 3; + ; + + memory "lock" + size = 1; + ; + + memory "calibration" + size = 1; + ; + + memory "fuse" + size = 1; + ; +; + +#------------------------------------------------------------ +# ATtiny12 +#------------------------------------------------------------ + +part + id = "t12"; + desc = "ATtiny12"; + stk500_devcode = 0x12; + avr910_devcode = 0x55; + signature = 0x1e 0x90 0x05; + chip_erase_delay = 20000; + pgm_enable = "1 0 1 0 1 1 0 0 0 1 0 1 0 0 1 1", + "x x x x x x x x x x x x x x x x"; + + chip_erase = "1 0 1 0 1 1 0 0 1 0 0 x x x x x", + "x x x x x x x x x x x x x x x x"; + + timeout = 200; + stabdelay = 100; + cmdexedelay = 25; + synchloops = 32; + bytedelay = 0; + pollindex = 3; + pollvalue = 0x53; + predelay = 1; + postdelay = 1; + pollmethod = 0; + + hvsp_controlstack = + 0x4C, 0x0C, 0x1C, 0x2C, 0x3C, 0x64, 0x74, 0x00, + 0x68, 0x78, 0x68, 0x68, 0x00, 0x00, 0x68, 0x78, + 0x78, 0x00, 0x6D, 0x0C, 0x80, 0x40, 0x20, 0x10, + 0x11, 0x08, 0x04, 0x02, 0x03, 0x08, 0x04, 0x00; + hventerstabdelay = 100; + hvspcmdexedelay = 0; + synchcycles = 6; + latchcycles = 1; + togglevtg = 1; + poweroffdelay = 25; + resetdelayms = 0; + resetdelayus = 50; + hvleavestabdelay = 100; + resetdelay = 25; + chiperasepolltimeout = 40; + chiperasetime = 0; + programfusepolltimeout = 25; + programlockpolltimeout = 25; + + memory "eeprom" + size = 64; + min_write_delay = 9000; + max_write_delay = 20000; + readback_p1 = 0xff; + readback_p2 = 0xff; + read = "1 0 1 0 0 0 0 0 x x x x x x x x", + "x x a5 a4 a3 a2 a1 a0 o o o o o o o o"; + + write = "1 1 0 0 0 0 0 0 x x x x x x x x", + "x x a5 a4 a3 a2 a1 a0 i i i i i i i i"; + + mode = 0x04; + delay = 8; + blocksize = 64; + readsize = 256; + ; + + memory "flash" + size = 1024; + min_write_delay = 4500; + max_write_delay = 20000; + readback_p1 = 0xff; + readback_p2 = 0xff; + read_lo = " 0 0 1 0 0 0 0 0", + " x x x x x x x a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + read_hi = " 0 0 1 0 1 0 0 0", + " x x x x x x x a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + write_lo = " 0 1 0 0 0 0 0 0", + " x x x x x x x a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " i i i i i i i i"; + + write_hi = " 0 1 0 0 1 0 0 0", + " x x x x x x x a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " i i i i i i i i"; + + mode = 0x04; + delay = 5; + blocksize = 128; + readsize = 256; + ; + + memory "signature" + size = 3; + read = "0 0 1 1 0 0 0 0 x x x x x x x x", + "0 0 0 0 0 0 a1 a0 o o o o o o o o"; + ; + + memory "lock" + size = 1; + read = "0 1 0 1 1 0 0 0 x x x x x x x x", + "x x x x x x x x x x x x x o o x"; + + write = "1 0 1 0 1 1 0 0 1 1 1 1 1 i i 1", + "x x x x x x x x x x x x x x x x"; + min_write_delay = 9000; + max_write_delay = 9000; + ; + + memory "calibration" + size = 1; + read = "0 0 1 1 1 0 0 0 x x x x x x x x", + "0 0 0 0 0 0 0 0 o o o o o o o o"; + ; + + memory "fuse" + size = 1; + read = "0 1 0 1 0 0 0 0 x x x x x x x x", + "x x x x x x x x o o o o o o o o"; + + write = "1 0 1 0 1 1 0 0 1 0 1 x x x x x", + "x x x x x x x x i i i i i i i i"; + min_write_delay = 9000; + max_write_delay = 9000; + ; +; + +#------------------------------------------------------------ +# ATtiny13 +#------------------------------------------------------------ + +part + id = "t13"; + desc = "ATtiny13"; + has_debugwire = yes; + flash_instr = 0xB4, 0x0E, 0x1E; + eeprom_instr = 0xBB, 0xFE, 0xBB, 0xEE, 0xBB, 0xCC, 0xB2, 0x0D, + 0xBC, 0x0E, 0xB4, 0x0E, 0xBA, 0x0D, 0xBB, 0xBC, + 0x99, 0xE1, 0xBB, 0xAC; + stk500_devcode = 0x14; + signature = 0x1e 0x90 0x07; + chip_erase_delay = 4000; + pgm_enable = "1 0 1 0 1 1 0 0 0 1 0 1 0 0 1 1", + "x x x x x x x x x x x x x x x x"; + + chip_erase = "1 0 1 0 1 1 0 0 1 0 0 x x x x x", + "x x x x x x x x x x x x x x x x"; + + timeout = 200; + stabdelay = 100; + cmdexedelay = 25; + synchloops = 32; + bytedelay = 0; + pollindex = 3; + pollvalue = 0x53; + predelay = 1; + postdelay = 1; + pollmethod = 1; + + hvsp_controlstack = + 0x4C, 0x0C, 0x1C, 0x2C, 0x3C, 0x64, 0x74, 0x66, + 0x68, 0x78, 0x68, 0x68, 0x7A, 0x6A, 0x68, 0x78, + 0x78, 0x7D, 0x6D, 0x0C, 0x80, 0x40, 0x20, 0x10, + 0x11, 0x08, 0x04, 0x02, 0x03, 0x08, 0x04, 0x00; + hventerstabdelay = 100; + progmodedelay = 0; + hvspcmdexedelay = 0; + synchcycles = 6; + latchcycles = 1; + togglevtg = 1; + poweroffdelay = 25; + resetdelayms = 0; + resetdelayus = 90; + hvleavestabdelay = 100; + resetdelay = 25; + chiperasepolltimeout = 40; + chiperasetime = 0; + programfusepolltimeout = 25; + programlockpolltimeout = 25; + + ocdrev = 0; + + memory "eeprom" + size = 64; + page_size = 4; + min_write_delay = 4000; + max_write_delay = 4000; + readback_p1 = 0xff; + readback_p2 = 0xff; + read = "1 0 1 0 0 0 0 0 0 0 0 x x x x x", + "x x a5 a4 a3 a2 a1 a0 o o o o o o o o"; + + write = "1 1 0 0 0 0 0 0 0 0 0 x x x x x", + "x x a5 a4 a3 a2 a1 a0 i i i i i i i i"; + + loadpage_lo = " 1 1 0 0 0 0 0 1", + " 0 0 0 0 0 0 0 0", + " 0 0 0 0 0 0 a1 a0", + " i i i i i i i i"; + + writepage = " 1 1 0 0 0 0 1 0", + " 0 0 x x x x x x", + " x x a5 a4 a3 a2 0 0", + " x x x x x x x x"; + + mode = 0x41; + delay = 5; + blocksize = 4; + readsize = 256; + ; + + memory "flash" + paged = yes; + size = 1024; + page_size = 32; + num_pages = 32; + min_write_delay = 4500; + max_write_delay = 4500; + readback_p1 = 0xff; + readback_p2 = 0xff; + read_lo = " 0 0 1 0 0 0 0 0", + " 0 0 0 0 0 0 0 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + read_hi = " 0 0 1 0 1 0 0 0", + " 0 0 0 0 0 0 0 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + loadpage_lo = " 0 1 0 0 0 0 0 0", + " 0 0 0 x x x x x", + " x x x x a3 a2 a1 a0", + " i i i i i i i i"; + + loadpage_hi = " 0 1 0 0 1 0 0 0", + " 0 0 0 x x x x x", + " x x x x a3 a2 a1 a0", + " i i i i i i i i"; + + writepage = " 0 1 0 0 1 1 0 0", + " 0 0 0 0 0 0 0 a8", + " a7 a6 a5 a4 x x x x", + " x x x x x x x x"; + + mode = 0x41; + delay = 6; + blocksize = 32; + readsize = 256; + ; + + memory "signature" + size = 3; + read = "0 0 1 1 0 0 0 0 0 0 0 x x x x x", + "x x x x x x a1 a0 o o o o o o o o"; + ; + + memory "lock" + size = 1; + min_write_delay = 4500; + max_write_delay = 4500; + + read = "0 1 0 1 1 0 0 0 0 0 0 0 0 0 0 0", + "x x x x x x x x x x o o o o o o"; + + write = "1 0 1 0 1 1 0 0 1 1 1 x x x x x", + "x x x x x x x x 1 1 i i i i i i"; + ; + + memory "calibration" + size = 2; + read = "0 0 1 1 1 0 0 0 0 0 0 x x x x x", + "0 0 0 0 0 0 0 a0 o o o o o o o o"; + ; + + memory "lfuse" + size = 1; + min_write_delay = 4500; + max_write_delay = 4500; + + write = "1 0 1 0 1 1 0 0 1 0 1 0 0 0 0 0", + "x x x x x x x x i i i i i i i i"; + + read = "0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0", + "x x x x x x x x o o o o o o o o"; + ; + + memory "hfuse" + size = 1; + min_write_delay = 4500; + max_write_delay = 4500; + + write = "1 0 1 0 1 1 0 0 1 0 1 0 1 0 0 0", + "x x x x x x x x i i i i i i i i"; + + read = "0 1 0 1 1 0 0 0 0 0 0 0 1 0 0 0", + "x x x x x x x x o o o o o o o o"; + ; + +; + + +#------------------------------------------------------------ +# ATtiny15 +#------------------------------------------------------------ + +part + id = "t15"; + desc = "ATtiny15"; + stk500_devcode = 0x13; + avr910_devcode = 0x56; + signature = 0x1e 0x90 0x06; + chip_erase_delay = 8200; + pgm_enable = "1 0 1 0 1 1 0 0 0 1 0 1 0 0 1 1", + "x x x x x x x x x x x x x x x x"; + + chip_erase = "1 0 1 0 1 1 0 0 1 0 0 x x x x x", + "x x x x x x x x x x x x x x x x"; + + timeout = 200; + stabdelay = 100; + cmdexedelay = 25; + synchloops = 32; + bytedelay = 0; + pollindex = 3; + pollvalue = 0x53; + predelay = 1; + postdelay = 1; + pollmethod = 0; + + hvsp_controlstack = + 0x4C, 0x0C, 0x1C, 0x2C, 0x3C, 0x64, 0x74, 0x00, + 0x68, 0x78, 0x68, 0x68, 0x00, 0x00, 0x68, 0x78, + 0x78, 0x00, 0x6D, 0x0C, 0x80, 0x40, 0x20, 0x10, + 0x11, 0x08, 0x04, 0x02, 0x03, 0x08, 0x04, 0x00; + hventerstabdelay = 100; + hvspcmdexedelay = 5; + synchcycles = 6; + latchcycles = 16; + togglevtg = 1; + poweroffdelay = 25; + resetdelayms = 0; + resetdelayus = 50; + hvleavestabdelay = 100; + resetdelay = 25; + chiperasepolltimeout = 40; + chiperasetime = 0; + programfusepolltimeout = 25; + programlockpolltimeout = 25; + + memory "eeprom" + size = 64; + min_write_delay = 8200; + max_write_delay = 8200; + readback_p1 = 0xff; + readback_p2 = 0xff; + read = "1 0 1 0 0 0 0 0 x x x x x x x x", + "x x a5 a4 a3 a2 a1 a0 o o o o o o o o"; + + write = "1 1 0 0 0 0 0 0 x x x x x x x x", + "x x a5 a4 a3 a2 a1 a0 i i i i i i i i"; + + mode = 0x04; + delay = 10; + blocksize = 64; + readsize = 256; + ; + + memory "flash" + size = 1024; + min_write_delay = 4100; + max_write_delay = 4100; + readback_p1 = 0xff; + readback_p2 = 0xff; + read_lo = " 0 0 1 0 0 0 0 0", + " x x x x x x x a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + read_hi = " 0 0 1 0 1 0 0 0", + " x x x x x x x a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + write_lo = " 0 1 0 0 0 0 0 0", + " x x x x x x x a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " i i i i i i i i"; + + write_hi = " 0 1 0 0 1 0 0 0", + " x x x x x x x a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " i i i i i i i i"; + + mode = 0x04; + delay = 5; + blocksize = 128; + readsize = 256; + ; + + memory "signature" + size = 3; + read = "0 0 1 1 0 0 0 0 x x x x x x x x", + "0 0 0 0 0 0 a1 a0 o o o o o o o o"; + ; + + memory "lock" + size = 1; + read = "0 1 0 1 1 0 0 0 x x x x x x x x", + "x x x x x x x x x x x x x o o x"; + + write = "1 0 1 0 1 1 0 0 1 1 1 1 1 i i 1", + "x x x x x x x x x x x x x x x x"; + min_write_delay = 9000; + max_write_delay = 9000; + ; + + memory "calibration" + size = 1; + read = "0 0 1 1 1 0 0 0 x x x x x x x x", + "0 0 0 0 0 0 0 0 o o o o o o o o"; + ; + + memory "fuse" + size = 1; + read = "0 1 0 1 0 0 0 0 x x x x x x x x", + "x x x x x x x x o o o o x x o o"; + + write = "1 0 1 0 1 1 0 0 1 0 1 x x x x x", + "x x x x x x x x i i i i 1 1 i i"; + min_write_delay = 9000; + max_write_delay = 9000; + ; +; + +#------------------------------------------------------------ +# AT90s1200 +#------------------------------------------------------------ + +part + id = "1200"; + desc = "AT90S1200"; + is_at90s1200 = yes; + stk500_devcode = 0x33; + avr910_devcode = 0x13; + signature = 0x1e 0x90 0x01; + pagel = 0xd7; + bs2 = 0xa0; + chip_erase_delay = 20000; + pgm_enable = "1 0 1 0 1 1 0 0 0 1 0 1 0 0 1 1", + "x x x x x x x x x x x x x x x x"; + + chip_erase = "1 0 1 0 1 1 0 0 1 0 0 0 0 0 0 0", + "x x x x x x x x x x x x x x x x"; + + timeout = 200; + stabdelay = 100; + cmdexedelay = 25; + synchloops = 1; + bytedelay = 0; + pollindex = 0; + pollvalue = 0xFF; + predelay = 1; + postdelay = 1; + pollmethod = 0; + + pp_controlstack = + 0x0E, 0x1E, 0x0F, 0x1F, 0x2E, 0x3E, 0x2F, 0x3F, + 0x4E, 0x5E, 0x4F, 0x5F, 0x6E, 0x7E, 0x6F, 0x7F, + 0x66, 0x76, 0x67, 0x77, 0x6A, 0x7A, 0x6B, 0x7B, + 0xBE, 0xFD, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00; + hventerstabdelay = 100; + progmodedelay = 0; + latchcycles = 0; + togglevtg = 0; + poweroffdelay = 0; + resetdelayms = 0; + resetdelayus = 0; + hvleavestabdelay = 15; + chiperasepulsewidth = 15; + chiperasepolltimeout = 0; + programfusepulsewidth = 2; + programfusepolltimeout = 0; + programlockpulsewidth = 0; + programlockpolltimeout = 1; + + memory "eeprom" + size = 64; + min_write_delay = 4000; + max_write_delay = 9000; + readback_p1 = 0x00; + readback_p2 = 0xff; + read = "1 0 1 0 0 0 0 0 x x x x x x x x", + "x x a5 a4 a3 a2 a1 a0 o o o o o o o o"; + + write = "1 1 0 0 0 0 0 0 x x x x x x x x", + "x x a5 a4 a3 a2 a1 a0 i i i i i i i i"; + + mode = 0x04; + delay = 20; + blocksize = 32; + readsize = 256; + ; + memory "flash" + size = 1024; + min_write_delay = 4000; + max_write_delay = 9000; + readback_p1 = 0xff; + readback_p2 = 0xff; + read_lo = " 0 0 1 0 0 0 0 0", + " x x x x x x x a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + read_hi = " 0 0 1 0 1 0 0 0", + " x x x x x x x a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + write_lo = " 0 1 0 0 0 0 0 0", + " x x x x x x x a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " i i i i i i i i"; + + write_hi = " 0 1 0 0 1 0 0 0", + " x x x x x x x a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " i i i i i i i i"; + + mode = 0x02; + delay = 15; + blocksize = 128; + readsize = 256; + ; + memory "signature" + size = 3; + read = "0 0 1 1 0 0 0 0 x x x x x x x x", + "x x x x x x a1 a0 o o o o o o o o"; + ; + memory "fuse" + size = 1; + ; + memory "lock" + size = 1; + min_write_delay = 9000; + max_write_delay = 20000; + write = "1 0 1 0 1 1 0 0 1 1 1 1 1 i i 1", + "x x x x x x x x x x x x x x x x"; + ; + ; + +#------------------------------------------------------------ +# AT90s4414 +#------------------------------------------------------------ + +part + id = "4414"; + desc = "AT90S4414"; + stk500_devcode = 0x50; + avr910_devcode = 0x28; + signature = 0x1e 0x92 0x01; + chip_erase_delay = 20000; + pgm_enable = "1 0 1 0 1 1 0 0 0 1 0 1 0 0 1 1", + "x x x x x x x x x x x x x x x x"; + + chip_erase = "1 0 1 0 1 1 0 0 1 0 0 0 0 0 0 0", + "x x x x x x x x x x x x x x x x"; + + timeout = 200; + stabdelay = 100; + cmdexedelay = 25; + synchloops = 32; + bytedelay = 0; + pollindex = 3; + pollvalue = 0x53; + predelay = 1; + postdelay = 1; + pollmethod = 0; + + pp_controlstack = + 0x0E, 0x1E, 0x0F, 0x1F, 0x2E, 0x3E, 0x2F, 0x3F, + 0x4E, 0x5E, 0x4F, 0x5F, 0x6E, 0x7E, 0x6F, 0x7F, + 0x66, 0x76, 0x67, 0x77, 0x6A, 0x7A, 0x6B, 0x7B, + 0xBE, 0xFD, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01; + hventerstabdelay = 100; + progmodedelay = 0; + latchcycles = 0; + togglevtg = 0; + poweroffdelay = 0; + resetdelayms = 0; + resetdelayus = 0; + hvleavestabdelay = 15; + chiperasepulsewidth = 15; + chiperasepolltimeout = 0; + programfusepulsewidth = 2; + programfusepolltimeout = 0; + programlockpulsewidth = 0; + programlockpolltimeout = 1; + + memory "eeprom" + size = 256; + min_write_delay = 9000; + max_write_delay = 20000; + readback_p1 = 0x80; + readback_p2 = 0x7f; + read = " 1 0 1 0 0 0 0 0 x x x x x x x a8", + "a7 a6 a5 a4 a3 a2 a1 a0 o o o o o o o o"; + + write = " 1 1 0 0 0 0 0 0 x x x x x x x a8", + "a7 a6 a5 a4 a3 a2 a1 a0 i i i i i i i i"; + + mode = 0x04; + delay = 12; + blocksize = 64; + readsize = 256; + ; + memory "flash" + size = 4096; + min_write_delay = 9000; + max_write_delay = 20000; + readback_p1 = 0x7f; + readback_p2 = 0x7f; + read_lo = " 0 0 1 0 0 0 0 0", + " x x x x a11 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + read_hi = " 0 0 1 0 1 0 0 0", + " x x x x a11 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + write_lo = " 0 1 0 0 0 0 0 0", + " x x x x a11 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " i i i i i i i i"; + + write_hi = " 0 1 0 0 1 0 0 0", + " x x x x a11 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " i i i i i i i i"; + + mode = 0x04; + delay = 12; + blocksize = 64; + readsize = 256; + ; + memory "signature" + size = 3; + read = "0 0 1 1 0 0 0 0 x x x x x x x x", + "x x x x x x a1 a0 o o o o o o o o"; + ; + memory "fuse" + size = 1; + ; + memory "lock" + size = 1; + write = "1 0 1 0 1 1 0 0 1 1 1 1 1 i i 1", + "x x x x x x x x x x x x x x x x"; + min_write_delay = 9000; + max_write_delay = 9000; + ; + ; + +#------------------------------------------------------------ +# AT90s2313 +#------------------------------------------------------------ + +part + id = "2313"; + desc = "AT90S2313"; + stk500_devcode = 0x40; + avr910_devcode = 0x20; + signature = 0x1e 0x91 0x01; + chip_erase_delay = 20000; + pgm_enable = "1 0 1 0 1 1 0 0 0 1 0 1 0 0 1 1", + "x x x x x x x x x x x x x x x x"; + + chip_erase = "1 0 1 0 1 1 0 0 1 0 0 0 0 0 0 0", + "x x x x x x x x x x x x x x x x"; + + timeout = 200; + stabdelay = 100; + cmdexedelay = 25; + synchloops = 32; + bytedelay = 0; + pollindex = 3; + pollvalue = 0x53; + predelay = 1; + postdelay = 1; + pollmethod = 0; + + pp_controlstack = + 0x0E, 0x1E, 0x0F, 0x1F, 0x2E, 0x3E, 0x2F, 0x3F, + 0x4E, 0x5E, 0x4F, 0x5F, 0x6E, 0x7E, 0x6F, 0x7F, + 0x66, 0x76, 0x67, 0x77, 0x6A, 0x7A, 0x6B, 0x7B, + 0xBE, 0xFD, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00; + hventerstabdelay = 100; + progmodedelay = 0; + latchcycles = 0; + togglevtg = 0; + poweroffdelay = 0; + resetdelayms = 0; + resetdelayus = 0; + hvleavestabdelay = 15; + chiperasepulsewidth = 15; + chiperasepolltimeout = 0; + programfusepulsewidth = 2; + programfusepolltimeout = 0; + programlockpulsewidth = 0; + programlockpolltimeout = 1; + + memory "eeprom" + size = 128; + min_write_delay = 4000; + max_write_delay = 9000; + readback_p1 = 0x80; + readback_p2 = 0x7f; + read = "1 0 1 0 0 0 0 0 x x x x x x x x", + "x a6 a5 a4 a3 a2 a1 a0 o o o o o o o o"; + + write = "1 1 0 0 0 0 0 0 x x x x x x x x", + "x a6 a5 a4 a3 a2 a1 a0 i i i i i i i i"; + + mode = 0x04; + delay = 12; + blocksize = 64; + readsize = 256; + ; + memory "flash" + size = 2048; + min_write_delay = 4000; + max_write_delay = 9000; + readback_p1 = 0x7f; + readback_p2 = 0x7f; + read_lo = " 0 0 1 0 0 0 0 0", + " x x x x x x a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + read_hi = " 0 0 1 0 1 0 0 0", + " x x x x x x a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + write_lo = " 0 1 0 0 0 0 0 0", + " x x x x x x a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " i i i i i i i i"; + + write_hi = " 0 1 0 0 1 0 0 0", + " x x x x x x a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " i i i i i i i i"; + + mode = 0x04; + delay = 12; + blocksize = 128; + readsize = 256; + ; + memory "signature" + size = 3; + read = "0 0 1 1 0 0 0 0 x x x x x x x x", + "x x x x x x a1 a0 o o o o o o o o"; + ; + memory "fuse" + size = 1; + ; + memory "lock" + size = 1; + write = "1 0 1 0 1 1 0 0 1 1 1 x x i i x", + "x x x x x x x x x x x x x x x x"; + min_write_delay = 9000; + max_write_delay = 9000; + ; + ; + +#------------------------------------------------------------ +# AT90s2333 +#------------------------------------------------------------ + +part + id = "2333"; +##### WARNING: No XML file for device 'AT90S2333'! ##### + desc = "AT90S2333"; + stk500_devcode = 0x42; + avr910_devcode = 0x34; + signature = 0x1e 0x91 0x05; + chip_erase_delay = 20000; + pgm_enable = "1 0 1 0 1 1 0 0 0 1 0 1 0 0 1 1", + "x x x x x x x x x x x x x x x x"; + + chip_erase = "1 0 1 0 1 1 0 0 1 0 0 0 0 0 0 0", + "x x x x x x x x x x x x x x x x"; + + timeout = 200; + stabdelay = 100; + cmdexedelay = 25; + synchloops = 32; + bytedelay = 0; + pollindex = 3; + pollvalue = 0x53; + predelay = 1; + postdelay = 1; + pollmethod = 0; + + pp_controlstack = + 0x0E, 0x1E, 0x0F, 0x1F, 0x2E, 0x3E, 0x2F, 0x3F, + 0x4E, 0x5E, 0x4F, 0x5F, 0x6E, 0x7E, 0x6F, 0x7F, + 0x66, 0x76, 0x67, 0x77, 0x6A, 0x7A, 0x6B, 0x7B, + 0xBE, 0xFD, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00; + hventerstabdelay = 100; + progmodedelay = 0; + latchcycles = 0; + togglevtg = 0; + poweroffdelay = 0; + resetdelayms = 0; + resetdelayus = 0; + hvleavestabdelay = 15; + chiperasepulsewidth = 15; + chiperasepolltimeout = 0; + programfusepulsewidth = 2; + programfusepolltimeout = 0; + programlockpulsewidth = 0; + programlockpolltimeout = 1; + + memory "eeprom" + size = 128; + min_write_delay = 9000; + max_write_delay = 20000; + readback_p1 = 0x00; + readback_p2 = 0xff; + read = "1 0 1 0 0 0 0 0 x x x x x x x x", + "x a6 a5 a4 a3 a2 a1 a0 o o o o o o o o"; + + write = "1 1 0 0 0 0 0 0 x x x x x x x x", + "x a6 a5 a4 a3 a2 a1 a0 i i i i i i i i"; + + mode = 0x04; + delay = 12; + blocksize = 128; + readsize = 256; + ; + + memory "flash" + size = 2048; + min_write_delay = 9000; + max_write_delay = 20000; + readback_p1 = 0xff; + readback_p2 = 0xff; + read_lo = " 0 0 1 0 0 0 0 0", + " x x x x x x a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + read_hi = " 0 0 1 0 1 0 0 0", + " x x x x x x a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + write_lo = " 0 1 0 0 0 0 0 0", + " x x x x x x a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " i i i i i i i i"; + + write_hi = " 0 1 0 0 1 0 0 0", + " x x x x x x a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " i i i i i i i i"; + + mode = 0x04; + delay = 12; + blocksize = 128; + readsize = 256; + ; + + memory "signature" + size = 3; + read = "0 0 1 1 0 0 0 0 x x x x x x x x", + "x x x x x x a1 a0 o o o o o o o o"; + ; + memory "fuse" + size = 1; + min_write_delay = 9000; + max_write_delay = 20000; + pwroff_after_write = yes; + read = "0 1 0 1 0 0 0 0 x x x x x x x x", + "x x x x x x x x x x o o o o o o"; + + write = "1 0 1 0 1 1 0 0 1 0 1 i i i i i", + "x x x x x x x x x x x x x x x x"; + ; + memory "lock" + size = 1; + min_write_delay = 9000; + max_write_delay = 20000; + read = "0 1 0 1 1 0 0 0 x x x x x x x x", + "x x x x x x x x x x x x x o o x"; + + write = "1 0 1 0 1 1 0 0 1 1 1 1 1 i i 1", + "x x x x x x x x x x x x x x x x"; + ; + ; + + +#------------------------------------------------------------ +# AT90s2343 (also AT90s2323 and ATtiny22) +#------------------------------------------------------------ + +part + id = "2343"; + desc = "AT90S2343"; + stk500_devcode = 0x43; + avr910_devcode = 0x4c; + signature = 0x1e 0x91 0x03; + chip_erase_delay = 18000; + pgm_enable = "1 0 1 0 1 1 0 0 0 1 0 1 0 0 1 1", + "x x x x x x x x x x x x x x x x"; + + chip_erase = "1 0 1 0 1 1 0 0 1 0 0 x x x x x", + "x x x x x x x x x x x x x x x x"; + + timeout = 200; + stabdelay = 100; + cmdexedelay = 25; + synchloops = 32; + bytedelay = 0; + pollindex = 3; + pollvalue = 0x53; + predelay = 1; + postdelay = 1; + pollmethod = 0; + + hvsp_controlstack = + 0x4C, 0x0C, 0x1C, 0x2C, 0x3C, 0x64, 0x74, 0x00, + 0x68, 0x78, 0x68, 0x68, 0x00, 0x00, 0x68, 0x78, + 0x78, 0x00, 0x6D, 0x0C, 0x80, 0x40, 0x20, 0x10, + 0x11, 0x08, 0x04, 0x02, 0x03, 0x08, 0x04, 0x00; + hventerstabdelay = 100; + hvspcmdexedelay = 0; + synchcycles = 6; + latchcycles = 1; + togglevtg = 0; + poweroffdelay = 25; + resetdelayms = 0; + resetdelayus = 50; + hvleavestabdelay = 100; + resetdelay = 25; + chiperasepolltimeout = 40; + chiperasetime = 0; + programfusepolltimeout = 25; + programlockpolltimeout = 25; + + memory "eeprom" + size = 128; + min_write_delay = 9000; + max_write_delay = 20000; + readback_p1 = 0x00; + readback_p2 = 0xff; + read = "1 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0", + "x a6 a5 a4 a3 a2 a1 a0 o o o o o o o o"; + + write = "1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0", + "x a6 a5 a4 a3 a2 a1 a0 i i i i i i i i"; + + mode = 0x04; + delay = 12; + blocksize = 64; + readsize = 256; + ; + memory "flash" + size = 2048; + min_write_delay = 9000; + max_write_delay = 20000; + readback_p1 = 0xff; + readback_p2 = 0xff; + read_lo = " 0 0 1 0 0 0 0 0", + " x x x x x x a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + read_hi = " 0 0 1 0 1 0 0 0", + " x x x x x x a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + write_lo = " 0 1 0 0 0 0 0 0", + " x x x x x x a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " i i i i i i i i"; + + write_hi = " 0 1 0 0 1 0 0 0", + " x x x x x x a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " i i i i i i i i"; + + mode = 0x04; + delay = 12; + blocksize = 128; + readsize = 128; + ; + memory "signature" + size = 3; + read = "0 0 1 1 0 0 0 0 x x x x x x x x", + "x x x x x x a1 a0 o o o o o o o o"; + ; + memory "fuse" + size = 1; + min_write_delay = 9000; + max_write_delay = 20000; + read = "0 1 0 1 1 0 0 0 x x x x x x x x", + "x x x x x x x x o o o x x x x o"; + + write = "1 0 1 0 1 1 0 0 1 0 1 1 1 1 1 i", + "x x x x x x x x x x x x x x x x"; + ; + memory "lock" + size = 1; + min_write_delay = 9000; + max_write_delay = 20000; + read = "0 1 0 1 1 0 0 0 x x x x x x x x", + "x x x x x x x x o o o x x x x o"; + + write = "1 0 1 0 1 1 0 0 1 1 1 1 1 i i 1", + "x x x x x x x x x x x x x x x x"; + ; + ; + + +#------------------------------------------------------------ +# AT90s4433 +#------------------------------------------------------------ + +part + id = "4433"; + desc = "AT90S4433"; + stk500_devcode = 0x51; + avr910_devcode = 0x30; + signature = 0x1e 0x92 0x03; + chip_erase_delay = 20000; + pgm_enable = "1 0 1 0 1 1 0 0 0 1 0 1 0 0 1 1", + "x x x x x x x x x x x x x x x x"; + + chip_erase = "1 0 1 0 1 1 0 0 1 0 0 0 0 0 0 0", + "x x x x x x x x x x x x x x x x"; + + timeout = 200; + stabdelay = 100; + cmdexedelay = 25; + synchloops = 32; + bytedelay = 0; + pollindex = 3; + pollvalue = 0x53; + predelay = 1; + postdelay = 1; + pollmethod = 0; + + pp_controlstack = + 0x0E, 0x1E, 0x0F, 0x1F, 0x2E, 0x3E, 0x2F, 0x3F, + 0x4E, 0x5E, 0x4F, 0x5F, 0x6E, 0x7E, 0x6F, 0x7F, + 0x66, 0x76, 0x67, 0x77, 0x6A, 0x7A, 0x6B, 0x7B, + 0xBE, 0xFD, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00; + hventerstabdelay = 100; + progmodedelay = 0; + latchcycles = 0; + togglevtg = 0; + poweroffdelay = 0; + resetdelayms = 0; + resetdelayus = 0; + hvleavestabdelay = 15; + chiperasepulsewidth = 15; + chiperasepolltimeout = 0; + programfusepulsewidth = 2; + programfusepolltimeout = 0; + programlockpulsewidth = 0; + programlockpolltimeout = 1; + + memory "eeprom" + size = 256; + min_write_delay = 9000; + max_write_delay = 20000; + readback_p1 = 0x00; + readback_p2 = 0xff; + read = " 1 0 1 0 0 0 0 0 x x x x x x x x", + "a7 a6 a5 a4 a3 a2 a1 a0 o o o o o o o o"; + + write = " 1 1 0 0 0 0 0 0 x x x x x x x x", + "a7 a6 a5 a4 a3 a2 a1 a0 i i i i i i i i"; + + mode = 0x04; + delay = 12; + blocksize = 128; + readsize = 256; + ; + memory "flash" + size = 4096; + min_write_delay = 9000; + max_write_delay = 20000; + readback_p1 = 0xff; + readback_p2 = 0xff; + read_lo = " 0 0 1 0 0 0 0 0", + " x x x x x a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + read_hi = " 0 0 1 0 1 0 0 0", + " x x x x x a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + write_lo = " 0 1 0 0 0 0 0 0", + " x x x x x a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " i i i i i i i i"; + + write_hi = " 0 1 0 0 1 0 0 0", + " x x x x x a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " i i i i i i i i"; + + mode = 0x04; + delay = 12; + blocksize = 128; + readsize = 256; + ; + memory "signature" + size = 3; + read = "0 0 1 1 0 0 0 0 x x x x x x x x", + "x x x x x x a1 a0 o o o o o o o o"; + ; + memory "fuse" + size = 1; + min_write_delay = 9000; + max_write_delay = 20000; + pwroff_after_write = yes; + read = "0 1 0 1 0 0 0 0 x x x x x x x x", + "x x x x x x x x x x o o o o o o"; + + write = "1 0 1 0 1 1 0 0 1 0 1 i i i i i", + "x x x x x x x x x x x x x x x x"; + ; + memory "lock" + size = 1; + min_write_delay = 9000; + max_write_delay = 20000; + read = "0 1 0 1 1 0 0 0 x x x x x x x x", + "x x x x x x x x x x x x x o o x"; + + write = "1 0 1 0 1 1 0 0 1 1 1 1 1 i i 1", + "x x x x x x x x x x x x x x x x"; + ; + ; + +#------------------------------------------------------------ +# AT90s4434 +#------------------------------------------------------------ + +part + id = "4434"; +##### WARNING: No XML file for device 'AT90S4434'! ##### + desc = "AT90S4434"; + stk500_devcode = 0x52; + avr910_devcode = 0x6c; + signature = 0x1e 0x92 0x02; + chip_erase_delay = 20000; + pgm_enable = "1 0 1 0 1 1 0 0 0 1 0 1 0 0 1 1", + "x x x x x x x x x x x x x x x x"; + + chip_erase = "1 0 1 0 1 1 0 0 1 0 0 0 0 0 0 0", + "x x x x x x x x x x x x x x x x"; + + memory "eeprom" + size = 256; + min_write_delay = 9000; + max_write_delay = 20000; + readback_p1 = 0x00; + readback_p2 = 0xff; + read = " 1 0 1 0 0 0 0 0 x x x x x x x x", + "a7 a6 a5 a4 a3 a2 a1 a0 o o o o o o o o"; + + write = " 1 1 0 0 0 0 0 0 x x x x x x x x", + "a7 a6 a5 a4 a3 a2 a1 a0 i i i i i i i i"; + ; + memory "flash" + size = 4096; + min_write_delay = 9000; + max_write_delay = 20000; + readback_p1 = 0xff; + readback_p2 = 0xff; + read_lo = " 0 0 1 0 0 0 0 0", + " x x x x x a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + read_hi = " 0 0 1 0 1 0 0 0", + " x x x x x a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + write_lo = " 0 1 0 0 0 0 0 0", + " x x x x x a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " i i i i i i i i"; + + write_hi = " 0 1 0 0 1 0 0 0", + " x x x x x a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " i i i i i i i i"; + ; + memory "signature" + size = 3; + read = "0 0 1 1 0 0 0 0 x x x x x x x x", + "x x x x x x a1 a0 o o o o o o o o"; + ; + memory "fuse" + size = 1; + min_write_delay = 9000; + max_write_delay = 20000; + read = "0 1 0 1 0 0 0 0 x x x x x x x x", + "x x x x x x x x x x o o o o o o"; + + write = "1 0 1 0 1 1 0 0 1 0 1 i i i i i", + "x x x x x x x x x x x x x x x x"; + ; + memory "lock" + size = 1; + min_write_delay = 9000; + max_write_delay = 20000; + read = "0 1 0 1 1 0 0 0 x x x x x x x x", + "x x x x x x x x x x x x x o o x"; + + write = "1 0 1 0 1 1 0 0 1 1 1 1 1 i i 1", + "x x x x x x x x x x x x x x x x"; + ; + ; + +#------------------------------------------------------------ +# AT90s8515 +#------------------------------------------------------------ + +part + id = "8515"; + desc = "AT90S8515"; + stk500_devcode = 0x60; + avr910_devcode = 0x38; + signature = 0x1e 0x93 0x01; + chip_erase_delay = 20000; + pgm_enable = "1 0 1 0 1 1 0 0 0 1 0 1 0 0 1 1", + "x x x x x x x x x x x x x x x x"; + + chip_erase = "1 0 1 0 1 1 0 0 1 0 0 x x x x x", + "x x x x x x x x x x x x x x x x"; + + timeout = 200; + stabdelay = 100; + cmdexedelay = 25; + synchloops = 32; + bytedelay = 0; + pollindex = 3; + pollvalue = 0x53; + predelay = 1; + postdelay = 1; + pollmethod = 0; + + pp_controlstack = + 0x0E, 0x1E, 0x0F, 0x1F, 0x2E, 0x3E, 0x2F, 0x3F, + 0x4E, 0x5E, 0x4F, 0x5F, 0x6E, 0x7E, 0x6F, 0x7F, + 0x66, 0x76, 0x67, 0x77, 0x6A, 0x7A, 0x6B, 0x7B, + 0xBE, 0xFD, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00; + hventerstabdelay = 100; + progmodedelay = 0; + latchcycles = 0; + togglevtg = 0; + poweroffdelay = 0; + resetdelayms = 0; + resetdelayus = 0; + hvleavestabdelay = 15; + resetdelay = 15; + chiperasepulsewidth = 15; + chiperasepolltimeout = 0; + programfusepulsewidth = 2; + programfusepolltimeout = 0; + programlockpulsewidth = 0; + programlockpolltimeout = 1; + + memory "eeprom" + size = 512; + min_write_delay = 4000; + max_write_delay = 9000; + readback_p1 = 0x80; + readback_p2 = 0x7f; + read = " 1 0 1 0 0 0 0 0 x x x x x x x a8", + "a7 a6 a5 a4 a3 a2 a1 a0 o o o o o o o o"; + + write = " 1 1 0 0 0 0 0 0 x x x x x x x a8", + "a7 a6 a5 a4 a3 a2 a1 a0 i i i i i i i i"; + + mode = 0x04; + delay = 12; + blocksize = 128; + readsize = 256; + ; + memory "flash" + size = 8192; + min_write_delay = 4000; + max_write_delay = 9000; + readback_p1 = 0x7f; + readback_p2 = 0x7f; + read_lo = " 0 0 1 0 0 0 0 0", + " x x x x a11 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + read_hi = " 0 0 1 0 1 0 0 0", + " x x x x a11 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + write_lo = " 0 1 0 0 0 0 0 0", + " x x x x a11 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " i i i i i i i i"; + + write_hi = " 0 1 0 0 1 0 0 0", + " x x x x a11 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " i i i i i i i i"; + + mode = 0x04; + delay = 12; + blocksize = 128; + readsize = 256; + ; + memory "signature" + size = 3; + read = "0 0 1 1 0 0 0 0 x x x x x x x x", + "x x x x x x a1 a0 o o o o o o o o"; + ; + memory "fuse" + size = 1; + ; + memory "lock" + size = 1; + write = "1 0 1 0 1 1 0 0 1 1 1 1 1 i i 1", + "x x x x x x x x x x x x x x x x"; + min_write_delay = 9000; + max_write_delay = 9000; + ; + ; + +#------------------------------------------------------------ +# AT90s8535 +#------------------------------------------------------------ + +part + id = "8535"; + desc = "AT90S8535"; + stk500_devcode = 0x61; + avr910_devcode = 0x68; + signature = 0x1e 0x93 0x03; + chip_erase_delay = 20000; + pgm_enable = "1 0 1 0 1 1 0 0 0 1 0 1 0 0 1 1", + "x x x x x x x x x x x x x x x x"; + + chip_erase = "1 0 1 0 1 1 0 0 1 0 0 0 0 0 0 0", + "x x x x x x x x x x x x x x x x"; + + timeout = 200; + stabdelay = 100; + cmdexedelay = 25; + synchloops = 32; + bytedelay = 0; + pollindex = 3; + pollvalue = 0x53; + predelay = 1; + postdelay = 1; + pollmethod = 0; + + pp_controlstack = + 0x0E, 0x1E, 0x0F, 0x1F, 0x2E, 0x3E, 0x2F, 0x3F, + 0x4E, 0x5E, 0x4F, 0x5F, 0x6E, 0x7E, 0x6F, 0x7F, + 0x66, 0x76, 0x67, 0x77, 0x6A, 0x7A, 0x6B, 0x7B, + 0xBE, 0xFD, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00; + hventerstabdelay = 100; + progmodedelay = 0; + latchcycles = 0; + togglevtg = 0; + poweroffdelay = 0; + resetdelayms = 0; + resetdelayus = 0; + hvleavestabdelay = 15; + chiperasepulsewidth = 15; + chiperasepolltimeout = 0; + programfusepulsewidth = 2; + programfusepolltimeout = 0; + programlockpulsewidth = 0; + programlockpolltimeout = 1; + + memory "eeprom" + size = 512; + min_write_delay = 9000; + max_write_delay = 20000; + readback_p1 = 0x00; + readback_p2 = 0xff; + read = " 1 0 1 0 0 0 0 0 x x x x x x x a8", + "a7 a6 a5 a4 a3 a2 a1 a0 o o o o o o o o"; + + write = " 1 1 0 0 0 0 0 0 x x x x x x x a8", + "a7 a6 a5 a4 a3 a2 a1 a0 i i i i i i i i"; + + mode = 0x04; + delay = 12; + blocksize = 128; + readsize = 256; + ; + memory "flash" + size = 8192; + min_write_delay = 9000; + max_write_delay = 20000; + readback_p1 = 0xff; + readback_p2 = 0xff; + read_lo = " 0 0 1 0 0 0 0 0", + " x x x x a11 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + read_hi = " 0 0 1 0 1 0 0 0", + " x x x x a11 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + write_lo = " 0 1 0 0 0 0 0 0", + " x x x x a11 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " i i i i i i i i"; + + write_hi = " 0 1 0 0 1 0 0 0", + " x x x x a11 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " i i i i i i i i"; + + mode = 0x04; + delay = 12; + blocksize = 128; + readsize = 256; + ; + memory "signature" + size = 3; + read = "0 0 1 1 0 0 0 0 x x x x x x x x", + "x x x x x x a1 a0 o o o o o o o o"; + ; + memory "fuse" + size = 1; + read = "0 1 0 1 1 0 0 0 x x x x x x x x", + "x x x x x x x x x x x x x x x o"; + write = "1 0 1 0 1 1 0 0 1 0 1 1 1 1 1 i", + "x x x x x x x x x x x x x x x x"; + min_write_delay = 9000; + max_write_delay = 9000; + ; + memory "lock" + size = 1; + read = "0 1 0 1 1 0 0 0 x x x x x x x x", + "x x x x x x x x o o x x x x x x"; + write = "1 0 1 0 1 1 0 0 1 1 1 1 1 i i 1", + "x x x x x x x x x x x x x x x x"; + min_write_delay = 9000; + max_write_delay = 9000; + ; + ; + +#------------------------------------------------------------ +# ATmega103 +#------------------------------------------------------------ + +part + id = "m103"; + desc = "ATmega103"; + stk500_devcode = 0xB1; + avr910_devcode = 0x41; + signature = 0x1e 0x97 0x01; + chip_erase_delay = 112000; + pgm_enable = "1 0 1 0 1 1 0 0 0 1 0 1 0 0 1 1", + "x x x x x x x x x x x x x x x x"; + + chip_erase = "1 0 1 0 1 1 0 0 1 0 0 0 0 0 0 0", + "x x x x x x x x x x x x x x x x"; + + timeout = 200; + stabdelay = 100; + cmdexedelay = 25; + synchloops = 32; + bytedelay = 0; + pollindex = 3; + pollvalue = 0x53; + predelay = 1; + postdelay = 1; + pollmethod = 0; + + pp_controlstack = + 0x0E, 0x1E, 0x8E, 0x9E, 0x2E, 0x3E, 0xAE, 0xBE, + 0x4E, 0x5E, 0xCE, 0xDE, 0x6E, 0x7E, 0xEE, 0xDE, + 0x66, 0x76, 0xE6, 0xF6, 0x6A, 0x7A, 0xEA, 0x7A, + 0x7F, 0xFD, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00; + hventerstabdelay = 100; + progmodedelay = 0; + latchcycles = 0; + togglevtg = 0; + poweroffdelay = 0; + resetdelayms = 0; + resetdelayus = 0; + hvleavestabdelay = 15; + chiperasepulsewidth = 15; + chiperasepolltimeout = 0; + programfusepulsewidth = 2; + programfusepolltimeout = 0; + programlockpulsewidth = 0; + programlockpolltimeout = 10; + + memory "eeprom" + size = 4096; + min_write_delay = 4000; + max_write_delay = 9000; + readback_p1 = 0x80; + readback_p2 = 0x7f; + read = " 1 0 1 0 0 0 0 0", + " x x x x a11 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + write = " 1 1 0 0 0 0 0 0", + " x x x x a11 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " i i i i i i i i"; + + mode = 0x04; + delay = 12; + blocksize = 64; + readsize = 256; + ; + + memory "flash" + paged = yes; + size = 131072; + page_size = 256; + num_pages = 512; + min_write_delay = 22000; + max_write_delay = 56000; + readback_p1 = 0xff; + readback_p2 = 0xff; + read_lo = " 0 0 1 0 0 0 0 0", + "a15 a14 a13 a12 a11 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + read_hi = " 0 0 1 0 1 0 0 0", + "a15 a14 a13 a12 a11 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + loadpage_lo = " 0 1 0 0 0 0 0 0", + " x x x x x x x x", + " x a6 a5 a4 a3 a2 a1 a0", + " i i i i i i i i"; + + loadpage_hi = " 0 1 0 0 1 0 0 0", + " x x x x x x x x", + " x a6 a5 a4 a3 a2 a1 a0", + " i i i i i i i i"; + + writepage = " 0 1 0 0 1 1 0 0", + "a15 a14 a13 a12 a11 a10 a9 a8", + " a7 x x x x x x x", + " x x x x x x x x"; + + mode = 0x11; + delay = 70; + blocksize = 256; + readsize = 256; + ; + + memory "fuse" + size = 1; + read = "0 1 0 1 0 0 0 0 x x x x x x x x", + "x x x x x x x x x x o x o 1 o o"; + + write = "1 0 1 0 1 1 0 0 1 0 1 1 i 1 i i", + "x x x x x x x x x x x x x x x x"; + min_write_delay = 9000; + max_write_delay = 9000; + ; + + memory "lock" + size = 1; + read = "0 1 0 1 1 0 0 0 x x x x x x x x", + "x x x x x x x x x x x x x o o x"; + + write = "1 0 1 0 1 1 0 0 1 1 1 1 1 i i 1", + "x x x x x x x x x x x x x x x x"; + min_write_delay = 9000; + max_write_delay = 9000; + ; + + memory "signature" + size = 3; + read = "0 0 1 1 0 0 0 0 x x x x x x x x", + "x x x x x x a1 a0 o o o o o o o o"; + ; + ; + + +#------------------------------------------------------------ +# ATmega64 +#------------------------------------------------------------ + +part + id = "m64"; + desc = "ATmega64"; + has_jtag = yes; + stk500_devcode = 0xA0; + avr910_devcode = 0x45; + signature = 0x1e 0x96 0x02; + chip_erase_delay = 9000; + pagel = 0xD7; + bs2 = 0xA0; + reset = dedicated; + pgm_enable = "1 0 1 0 1 1 0 0 0 1 0 1 0 0 1 1", + "x x x x x x x x x x x x x x x x"; + + chip_erase = "1 0 1 0 1 1 0 0 1 0 0 0 0 0 0 0", + "x x x x x x x x x x x x x x x x"; + + timeout = 200; + stabdelay = 100; + cmdexedelay = 25; + synchloops = 32; + bytedelay = 0; + pollindex = 3; + pollvalue = 0x53; + predelay = 1; + postdelay = 1; + pollmethod = 0; + + pp_controlstack = + 0x0E, 0x1E, 0x0F, 0x1F, 0x2E, 0x3E, 0x2F, 0x3F, + 0x4E, 0x5E, 0x4F, 0x5F, 0x6E, 0x7E, 0x6F, 0x7F, + 0x66, 0x76, 0x67, 0x77, 0x6A, 0x7A, 0x6B, 0x7B, + 0xBE, 0xFD, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00; + hventerstabdelay = 100; + progmodedelay = 0; + latchcycles = 6; + togglevtg = 0; + poweroffdelay = 0; + resetdelayms = 0; + resetdelayus = 0; + hvleavestabdelay = 15; + chiperasepulsewidth = 0; + chiperasepolltimeout = 10; + programfusepulsewidth = 0; + programfusepolltimeout = 5; + programlockpulsewidth = 0; + programlockpolltimeout = 5; + + idr = 0x22; + spmcr = 0x68; + allowfullpagebitstream = yes; + + ocdrev = 2; + + memory "eeprom" + paged = no; /* leave this "no" */ + page_size = 8; /* for parallel programming */ + size = 2048; + min_write_delay = 9000; + max_write_delay = 9000; + readback_p1 = 0xff; + readback_p2 = 0xff; + read = " 1 0 1 0 0 0 0 0", + " x x x x a11 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + write = " 1 1 0 0 0 0 0 0", + " x x x x a11 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " i i i i i i i i"; + + mode = 0x04; + delay = 20; + blocksize = 64; + readsize = 256; + ; + + memory "flash" + paged = yes; + size = 65536; + page_size = 256; + num_pages = 256; + min_write_delay = 4500; + max_write_delay = 4500; + readback_p1 = 0xff; + readback_p2 = 0xff; + read_lo = " 0 0 1 0 0 0 0 0", + " x a14 a13 a12 a11 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + read_hi = " 0 0 1 0 1 0 0 0", + " x a14 a13 a12 a11 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + + loadpage_lo = " 0 1 0 0 0 0 0 0", + " x x x x x x x x", + " x a6 a5 a4 a3 a2 a1 a0", + " i i i i i i i i"; + + loadpage_hi = " 0 1 0 0 1 0 0 0", + " x x x x x x x x", + " x a6 a5 a4 a3 a2 a1 a0", + " i i i i i i i i"; + + writepage = " 0 1 0 0 1 1 0 0", + " x a14 a13 a12 a11 a10 a9 a8", + " a7 x x x x x x x", + " x x x x x x x x"; + + mode = 0x21; + delay = 6; + blocksize = 128; + readsize = 256; + ; + + memory "lfuse" + size = 1; + write = "1 0 1 0 1 1 0 0 1 0 1 0 0 0 0 0", + "x x x x x x x x i i i i i i i i"; + + read = "0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0", + "x x x x x x x x o o o o o o o o"; + min_write_delay = 9000; + max_write_delay = 9000; + ; + + memory "hfuse" + size = 1; + write = "1 0 1 0 1 1 0 0 1 0 1 0 1 0 0 0", + "x x x x x x x x i i i i i i i i"; + + read = "0 1 0 1 1 0 0 0 0 0 0 0 1 0 0 0", + "x x x x x x x x o o o o o o o o"; + min_write_delay = 9000; + max_write_delay = 9000; + ; + + memory "efuse" + size = 1; + write = "1 0 1 0 1 1 0 0 1 0 1 0 0 1 0 0", + "x x x x x x x x x x x x x x i i"; + + read = "0 1 0 1 0 0 0 0 0 0 0 0 1 0 0 0", + "x x x x x x x x o o o o o o o o"; + min_write_delay = 9000; + max_write_delay = 9000; + ; + + memory "lock" + size = 1; + read = "0 1 0 1 1 0 0 0 0 0 0 0 0 0 0 0", + "x x x x x x x x x x o o o o o o"; + + write = "1 0 1 0 1 1 0 0 1 1 1 x x x x x", + "x x x x x x x x 1 1 i i i i i i"; + min_write_delay = 9000; + max_write_delay = 9000; + ; + + memory "calibration" + size = 4; + read = "0 0 1 1 1 0 0 0 x x x x x x x x", + "0 0 0 0 0 0 a1 a0 o o o o o o o o"; + ; + + memory "signature" + size = 3; + read = "0 0 1 1 0 0 0 0 x x x x x x x x", + "x x x x x x a1 a0 o o o o o o o o"; + ; + ; + + + + +#------------------------------------------------------------ +# ATmega128 +#------------------------------------------------------------ + +part + id = "m128"; + desc = "ATmega128"; + has_jtag = yes; + stk500_devcode = 0xB2; + avr910_devcode = 0x43; + signature = 0x1e 0x97 0x02; + chip_erase_delay = 9000; + pagel = 0xD7; + bs2 = 0xA0; + reset = dedicated; + pgm_enable = "1 0 1 0 1 1 0 0 0 1 0 1 0 0 1 1", + "x x x x x x x x x x x x x x x x"; + + chip_erase = "1 0 1 0 1 1 0 0 1 0 0 0 0 0 0 0", + "x x x x x x x x x x x x x x x x"; + + timeout = 200; + stabdelay = 100; + cmdexedelay = 25; + synchloops = 32; + bytedelay = 0; + pollindex = 3; + pollvalue = 0x53; + predelay = 1; + postdelay = 1; + pollmethod = 0; + + pp_controlstack = + 0x0E, 0x1E, 0x0F, 0x1F, 0x2E, 0x3E, 0x2F, 0x3F, + 0x4E, 0x5E, 0x4F, 0x5F, 0x6E, 0x7E, 0x6F, 0x7F, + 0x66, 0x76, 0x67, 0x77, 0x6A, 0x7A, 0x6B, 0x7B, + 0xBE, 0xFD, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00; + hventerstabdelay = 100; + progmodedelay = 0; + latchcycles = 6; + togglevtg = 0; + poweroffdelay = 0; + resetdelayms = 0; + resetdelayus = 0; + hvleavestabdelay = 15; + chiperasepulsewidth = 0; + chiperasepolltimeout = 10; + programfusepulsewidth = 0; + programfusepolltimeout = 5; + programlockpulsewidth = 0; + programlockpolltimeout = 5; + + idr = 0x22; + spmcr = 0x68; + rampz = 0x3b; + allowfullpagebitstream = yes; + + ocdrev = 1; + + memory "eeprom" + paged = no; /* leave this "no" */ + page_size = 8; /* for parallel programming */ + size = 4096; + min_write_delay = 9000; + max_write_delay = 9000; + readback_p1 = 0xff; + readback_p2 = 0xff; + read = " 1 0 1 0 0 0 0 0", + " x x x x a11 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + write = " 1 1 0 0 0 0 0 0", + " x x x x a11 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " i i i i i i i i"; + + mode = 0x04; + delay = 12; + blocksize = 64; + readsize = 256; + ; + + memory "flash" + paged = yes; + size = 131072; + page_size = 256; + num_pages = 512; + min_write_delay = 4500; + max_write_delay = 4500; + readback_p1 = 0xff; + readback_p2 = 0xff; + read_lo = " 0 0 1 0 0 0 0 0", + "a15 a14 a13 a12 a11 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + read_hi = " 0 0 1 0 1 0 0 0", + "a15 a14 a13 a12 a11 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + loadpage_lo = " 0 1 0 0 0 0 0 0", + " x x x x x x x x", + " x a6 a5 a4 a3 a2 a1 a0", + " i i i i i i i i"; + + loadpage_hi = " 0 1 0 0 1 0 0 0", + " x x x x x x x x", + " x a6 a5 a4 a3 a2 a1 a0", + " i i i i i i i i"; + + writepage = " 0 1 0 0 1 1 0 0", + "a15 a14 a13 a12 a11 a10 a9 a8", + " a7 x x x x x x x", + " x x x x x x x x"; + + mode = 0x21; + delay = 6; + blocksize = 128; + readsize = 256; + ; + + memory "lfuse" + size = 1; + write = "1 0 1 0 1 1 0 0 1 0 1 0 0 0 0 0", + "x x x x x x x x i i i i i i i i"; + + read = "0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0", + "x x x x x x x x o o o o o o o o"; + min_write_delay = 9000; + max_write_delay = 9000; + ; + + memory "hfuse" + size = 1; + write = "1 0 1 0 1 1 0 0 1 0 1 0 1 0 0 0", + "x x x x x x x x i i i i i i i i"; + + read = "0 1 0 1 1 0 0 0 0 0 0 0 1 0 0 0", + "x x x x x x x x o o o o o o o o"; + min_write_delay = 9000; + max_write_delay = 9000; + ; + + memory "efuse" + size = 1; + write = "1 0 1 0 1 1 0 0 1 0 1 0 0 1 0 0", + "x x x x x x x x x x x x x x i i"; + + read = "0 1 0 1 0 0 0 0 0 0 0 0 1 0 0 0", + "x x x x x x x x o o o o o o o o"; + min_write_delay = 9000; + max_write_delay = 9000; + ; + + memory "lock" + size = 1; + read = "0 1 0 1 1 0 0 0 0 0 0 0 0 0 0 0", + "x x x x x x x x x x o o o o o o"; + + write = "1 0 1 0 1 1 0 0 1 1 1 x x x x x", + "x x x x x x x x 1 1 i i i i i i"; + min_write_delay = 9000; + max_write_delay = 9000; + ; + + memory "calibration" + size = 4; + read = "0 0 1 1 1 0 0 0 x x x x x x x x", + "0 0 0 0 0 0 a1 a0 o o o o o o o o"; + ; + + memory "signature" + size = 3; + read = "0 0 1 1 0 0 0 0 x x x x x x x x", + "x x x x x x a1 a0 o o o o o o o o"; + ; + ; + +#------------------------------------------------------------ +# AT90CAN128 +#------------------------------------------------------------ + +part + id = "c128"; + desc = "AT90CAN128"; + has_jtag = yes; + stk500_devcode = 0xB3; +# avr910_devcode = 0x43; + signature = 0x1e 0x97 0x81; + chip_erase_delay = 9000; + pagel = 0xD7; + bs2 = 0xA0; + reset = dedicated; + pgm_enable = "1 0 1 0 1 1 0 0 0 1 0 1 0 0 1 1", + "x x x x x x x x x x x x x x x x"; + + chip_erase = "1 0 1 0 1 1 0 0 1 0 0 x x x x x", + "x x x x x x x x x x x x x x x x"; + + timeout = 200; + stabdelay = 100; + cmdexedelay = 25; + synchloops = 32; + bytedelay = 0; + pollindex = 3; + pollvalue = 0x53; + predelay = 1; + postdelay = 1; + pollmethod = 1; + + pp_controlstack = + 0x0E, 0x1E, 0x0F, 0x1F, 0x2E, 0x3E, 0x2F, 0x3F, + 0x4E, 0x5E, 0x4F, 0x5F, 0x6E, 0x7E, 0x6F, 0x7F, + 0x66, 0x76, 0x67, 0x77, 0x6A, 0x7A, 0x6B, 0x7B, + 0xBE, 0xFD, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01; + hventerstabdelay = 100; + progmodedelay = 0; + latchcycles = 6; + togglevtg = 0; + poweroffdelay = 0; + resetdelayms = 0; + resetdelayus = 0; + hvleavestabdelay = 15; + chiperasepulsewidth = 0; + chiperasepolltimeout = 10; + programfusepulsewidth = 0; + programfusepolltimeout = 5; + programlockpulsewidth = 0; + programlockpolltimeout = 5; + + idr = 0x31; + spmcr = 0x57; + rampz = 0x3b; + eecr = 0x3f; + allowfullpagebitstream = no; + + ocdrev = 3; + + memory "eeprom" + paged = no; /* leave this "no" */ + page_size = 8; /* for parallel programming */ + size = 4096; + min_write_delay = 9000; + max_write_delay = 9000; + readback_p1 = 0xff; + readback_p2 = 0xff; + read = " 1 0 1 0 0 0 0 0", + " 0 0 0 x a11 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + write = " 1 1 0 0 0 0 0 0", + " 0 0 0 x a11 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " i i i i i i i i"; + + loadpage_lo = " 1 1 0 0 0 0 0 1", + " 0 0 0 0 0 0 0 0", + " 0 0 0 0 0 a2 a1 a0", + " i i i i i i i i"; + + writepage = " 1 1 0 0 0 0 1 0", + " 0 0 x x a11 a10 a9 a8", + " a7 a6 a5 a4 a3 0 0 0", + " x x x x x x x x"; + + + mode = 0x41; + delay = 20; + blocksize = 8; + readsize = 256; + ; + + memory "flash" + paged = yes; + size = 131072; + page_size = 256; + num_pages = 512; + min_write_delay = 4500; + max_write_delay = 4500; + readback_p1 = 0xff; + readback_p2 = 0xff; + read_lo = " 0 0 1 0 0 0 0 0", + "a15 a14 a13 a12 a11 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + read_hi = " 0 0 1 0 1 0 0 0", + "a15 a14 a13 a12 a11 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + loadpage_lo = " 0 1 0 0 0 0 0 0", + " 0 0 0 x x x x x", + " x a6 a5 a4 a3 a2 a1 a0", + " i i i i i i i i"; + + loadpage_hi = " 0 1 0 0 1 0 0 0", + " 0 0 0 x x x x x", + " x a6 a5 a4 a3 a2 a1 a0", + " i i i i i i i i"; + + writepage = " 0 1 0 0 1 1 0 0", + "a15 a14 a13 a12 a11 a10 a9 a8", + " a7 x x x x x x x", + " x x x x x x x x"; + + mode = 0x41; + delay = 6; + blocksize = 256; + readsize = 256; + ; + + memory "lfuse" + size = 1; + write = "1 0 1 0 1 1 0 0 1 0 1 0 0 0 0 0", + "x x x x x x x x i i i i i i i i"; + + read = "0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0", + "x x x x x x x x o o o o o o o o"; + min_write_delay = 9000; + max_write_delay = 9000; + ; + + memory "hfuse" + size = 1; + write = "1 0 1 0 1 1 0 0 1 0 1 0 1 0 0 0", + "x x x x x x x x i i i i i i i i"; + + read = "0 1 0 1 1 0 0 0 0 0 0 0 1 0 0 0", + "x x x x x x x x o o o o o o o o"; + min_write_delay = 9000; + max_write_delay = 9000; + ; + + memory "efuse" + size = 1; + write = "1 0 1 0 1 1 0 0 1 0 1 0 0 1 0 0", + "x x x x x x x x x x x x i i i i"; + + read = "0 1 0 1 0 0 0 0 0 0 0 0 1 0 0 0", + "x x x x x x x x o o o o o o o o"; + min_write_delay = 9000; + max_write_delay = 9000; + ; + + memory "lock" + size = 1; + read = "0 1 0 1 1 0 0 0 0 0 0 0 0 0 0 0", + "x x x x x x x x x x o o o o o o"; + + write = "1 0 1 0 1 1 0 0 1 1 1 x x x x x", + "x x x x x x x x 1 1 i i i i i i"; + min_write_delay = 9000; + max_write_delay = 9000; + ; + + memory "calibration" + size = 1; + read = "0 0 1 1 1 0 0 0 0 0 0 x x x x x", + "0 0 0 0 0 0 0 0 o o o o o o o o"; + ; + + memory "signature" + size = 3; + read = "0 0 1 1 0 0 0 0 x x x x x x x x", + "x x x x x x a1 a0 o o o o o o o o"; + ; + ; + +#------------------------------------------------------------ +# AT90CAN64 +#------------------------------------------------------------ + +part + id = "c64"; + desc = "AT90CAN64"; + has_jtag = yes; + stk500_devcode = 0xB3; +# avr910_devcode = 0x43; + signature = 0x1e 0x96 0x81; + chip_erase_delay = 9000; + pagel = 0xD7; + bs2 = 0xA0; + reset = dedicated; + pgm_enable = "1 0 1 0 1 1 0 0 0 1 0 1 0 0 1 1", + "x x x x x x x x x x x x x x x x"; + + chip_erase = "1 0 1 0 1 1 0 0 1 0 0 x x x x x", + "x x x x x x x x x x x x x x x x"; + + timeout = 200; + stabdelay = 100; + cmdexedelay = 25; + synchloops = 32; + bytedelay = 0; + pollindex = 3; + pollvalue = 0x53; + predelay = 1; + postdelay = 1; + pollmethod = 1; + + pp_controlstack = + 0x0E, 0x1E, 0x0F, 0x1F, 0x2E, 0x3E, 0x2F, 0x3F, + 0x4E, 0x5E, 0x4F, 0x5F, 0x6E, 0x7E, 0x6F, 0x7F, + 0x66, 0x76, 0x67, 0x77, 0x6A, 0x7A, 0x6B, 0x7B, + 0xBE, 0xFD, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01; + hventerstabdelay = 100; + progmodedelay = 0; + latchcycles = 6; + togglevtg = 0; + poweroffdelay = 0; + resetdelayms = 0; + resetdelayus = 0; + hvleavestabdelay = 15; + chiperasepulsewidth = 0; + chiperasepolltimeout = 10; + programfusepulsewidth = 0; + programfusepolltimeout = 5; + programlockpulsewidth = 0; + programlockpolltimeout = 5; + + idr = 0x31; + spmcr = 0x57; + rampz = 0x3b; + eecr = 0x3f; + allowfullpagebitstream = no; + + ocdrev = 3; + + memory "eeprom" + paged = no; /* leave this "no" */ + page_size = 8; /* for parallel programming */ + size = 2048; + min_write_delay = 9000; + max_write_delay = 9000; + readback_p1 = 0xff; + readback_p2 = 0xff; + read = " 1 0 1 0 0 0 0 0", + " 0 0 0 x x a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + write = " 1 1 0 0 0 0 0 0", + " 0 0 0 x x a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " i i i i i i i i"; + + loadpage_lo = " 1 1 0 0 0 0 0 1", + " 0 0 0 0 0 0 0 0", + " 0 0 0 0 0 a2 a1 a0", + " i i i i i i i i"; + + writepage = " 1 1 0 0 0 0 1 0", + " 0 0 x x x a10 a9 a8", + " a7 a6 a5 a4 a3 0 0 0", + " x x x x x x x x"; + + + mode = 0x41; + delay = 20; + blocksize = 8; + readsize = 256; + ; + + memory "flash" + paged = yes; + size = 65536; + page_size = 256; + num_pages = 256; + min_write_delay = 4500; + max_write_delay = 4500; + readback_p1 = 0xff; + readback_p2 = 0xff; + read_lo = " 0 0 1 0 0 0 0 0", + "a15 a14 a13 a12 a11 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + read_hi = " 0 0 1 0 1 0 0 0", + "a15 a14 a13 a12 a11 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + loadpage_lo = " 0 1 0 0 0 0 0 0", + " 0 0 0 x x x x x", + " x a6 a5 a4 a3 a2 a1 a0", + " i i i i i i i i"; + + loadpage_hi = " 0 1 0 0 1 0 0 0", + " 0 0 0 x x x x x", + " x a6 a5 a4 a3 a2 a1 a0", + " i i i i i i i i"; + + writepage = " 0 1 0 0 1 1 0 0", + "a15 a14 a13 a12 a11 a10 a9 a8", + " a7 x x x x x x x", + " x x x x x x x x"; + + mode = 0x41; + delay = 6; + blocksize = 256; + readsize = 256; + ; + + memory "lfuse" + size = 1; + write = "1 0 1 0 1 1 0 0 1 0 1 0 0 0 0 0", + "x x x x x x x x i i i i i i i i"; + + read = "0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0", + "x x x x x x x x o o o o o o o o"; + min_write_delay = 9000; + max_write_delay = 9000; + ; + + memory "hfuse" + size = 1; + write = "1 0 1 0 1 1 0 0 1 0 1 0 1 0 0 0", + "x x x x x x x x i i i i i i i i"; + + read = "0 1 0 1 1 0 0 0 0 0 0 0 1 0 0 0", + "x x x x x x x x o o o o o o o o"; + min_write_delay = 9000; + max_write_delay = 9000; + ; + + memory "efuse" + size = 1; + write = "1 0 1 0 1 1 0 0 1 0 1 0 0 1 0 0", + "x x x x x x x x x x x x i i i i"; + + read = "0 1 0 1 0 0 0 0 0 0 0 0 1 0 0 0", + "x x x x x x x x o o o o o o o o"; + min_write_delay = 9000; + max_write_delay = 9000; + ; + + memory "lock" + size = 1; + read = "0 1 0 1 1 0 0 0 0 0 0 0 0 0 0 0", + "x x x x x x x x x x o o o o o o"; + + write = "1 0 1 0 1 1 0 0 1 1 1 x x x x x", + "x x x x x x x x 1 1 i i i i i i"; + min_write_delay = 9000; + max_write_delay = 9000; + ; + + memory "calibration" + size = 1; + read = "0 0 1 1 1 0 0 0 0 0 0 x x x x x", + "0 0 0 0 0 0 0 0 o o o o o o o o"; + ; + + memory "signature" + size = 3; + read = "0 0 1 1 0 0 0 0 x x x x x x x x", + "x x x x x x a1 a0 o o o o o o o o"; + ; + ; + +#------------------------------------------------------------ +# AT90CAN32 +#------------------------------------------------------------ + +part + id = "c32"; + desc = "AT90CAN32"; + has_jtag = yes; + stk500_devcode = 0xB3; +# avr910_devcode = 0x43; + signature = 0x1e 0x95 0x81; + chip_erase_delay = 9000; + pagel = 0xD7; + bs2 = 0xA0; + reset = dedicated; + pgm_enable = "1 0 1 0 1 1 0 0 0 1 0 1 0 0 1 1", + "x x x x x x x x x x x x x x x x"; + + chip_erase = "1 0 1 0 1 1 0 0 1 0 0 x x x x x", + "x x x x x x x x x x x x x x x x"; + + timeout = 200; + stabdelay = 100; + cmdexedelay = 25; + synchloops = 32; + bytedelay = 0; + pollindex = 3; + pollvalue = 0x53; + predelay = 1; + postdelay = 1; + pollmethod = 1; + + pp_controlstack = + 0x0E, 0x1E, 0x0F, 0x1F, 0x2E, 0x3E, 0x2F, 0x3F, + 0x4E, 0x5E, 0x4F, 0x5F, 0x6E, 0x7E, 0x6F, 0x7F, + 0x66, 0x76, 0x67, 0x77, 0x6A, 0x7A, 0x6B, 0x7B, + 0xBE, 0xFD, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01; + hventerstabdelay = 100; + progmodedelay = 0; + latchcycles = 6; + togglevtg = 0; + poweroffdelay = 0; + resetdelayms = 0; + resetdelayus = 0; + hvleavestabdelay = 15; + chiperasepulsewidth = 0; + chiperasepolltimeout = 10; + programfusepulsewidth = 0; + programfusepolltimeout = 5; + programlockpulsewidth = 0; + programlockpolltimeout = 5; + + idr = 0x31; + spmcr = 0x57; + rampz = 0x3b; + eecr = 0x3f; + allowfullpagebitstream = no; + + ocdrev = 3; + + memory "eeprom" + paged = no; /* leave this "no" */ + page_size = 8; /* for parallel programming */ + size = 1024; + min_write_delay = 9000; + max_write_delay = 9000; + readback_p1 = 0xff; + readback_p2 = 0xff; + read = " 1 0 1 0 0 0 0 0", + " 0 0 0 x x x a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + write = " 1 1 0 0 0 0 0 0", + " 0 0 0 x x x a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " i i i i i i i i"; + + loadpage_lo = " 1 1 0 0 0 0 0 1", + " 0 0 0 0 0 0 0 0", + " 0 0 0 0 0 a2 a1 a0", + " i i i i i i i i"; + + writepage = " 1 1 0 0 0 0 1 0", + " 0 0 x x x x a9 a8", + " a7 a6 a5 a4 a3 0 0 0", + " x x x x x x x x"; + + + mode = 0x41; + delay = 20; + blocksize = 8; + readsize = 256; + ; + + memory "flash" + paged = yes; + size = 32768; + page_size = 256; + num_pages = 128; + min_write_delay = 4500; + max_write_delay = 4500; + readback_p1 = 0xff; + readback_p2 = 0xff; + read_lo = " 0 0 1 0 0 0 0 0", + "a15 a14 a13 a12 a11 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + read_hi = " 0 0 1 0 1 0 0 0", + "a15 a14 a13 a12 a11 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + loadpage_lo = " 0 1 0 0 0 0 0 0", + " 0 0 0 x x x x x", + " x a6 a5 a4 a3 a2 a1 a0", + " i i i i i i i i"; + + loadpage_hi = " 0 1 0 0 1 0 0 0", + " 0 0 0 x x x x x", + " x a6 a5 a4 a3 a2 a1 a0", + " i i i i i i i i"; + + writepage = " 0 1 0 0 1 1 0 0", + "a15 a14 a13 a12 a11 a10 a9 a8", + " a7 x x x x x x x", + " x x x x x x x x"; + + mode = 0x41; + delay = 6; + blocksize = 256; + readsize = 256; + ; + + memory "lfuse" + size = 1; + write = "1 0 1 0 1 1 0 0 1 0 1 0 0 0 0 0", + "x x x x x x x x i i i i i i i i"; + + read = "0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0", + "x x x x x x x x o o o o o o o o"; + min_write_delay = 9000; + max_write_delay = 9000; + ; + + memory "hfuse" + size = 1; + write = "1 0 1 0 1 1 0 0 1 0 1 0 1 0 0 0", + "x x x x x x x x i i i i i i i i"; + + read = "0 1 0 1 1 0 0 0 0 0 0 0 1 0 0 0", + "x x x x x x x x o o o o o o o o"; + min_write_delay = 9000; + max_write_delay = 9000; + ; + + memory "efuse" + size = 1; + write = "1 0 1 0 1 1 0 0 1 0 1 0 0 1 0 0", + "x x x x x x x x x x x x i i i i"; + + read = "0 1 0 1 0 0 0 0 0 0 0 0 1 0 0 0", + "x x x x x x x x o o o o o o o o"; + min_write_delay = 9000; + max_write_delay = 9000; + ; + + memory "lock" + size = 1; + read = "0 1 0 1 1 0 0 0 0 0 0 0 0 0 0 0", + "x x x x x x x x x x o o o o o o"; + + write = "1 0 1 0 1 1 0 0 1 1 1 x x x x x", + "x x x x x x x x 1 1 i i i i i i"; + min_write_delay = 9000; + max_write_delay = 9000; + ; + + memory "calibration" + size = 1; + read = "0 0 1 1 1 0 0 0 0 0 0 x x x x x", + "0 0 0 0 0 0 0 0 o o o o o o o o"; + ; + + memory "signature" + size = 3; + read = "0 0 1 1 0 0 0 0 x x x x x x x x", + "x x x x x x a1 a0 o o o o o o o o"; + ; + ; + + +#------------------------------------------------------------ +# ATmega16 +#------------------------------------------------------------ + +part + id = "m16"; + desc = "ATmega16"; + has_jtag = yes; + stk500_devcode = 0x82; + avr910_devcode = 0x74; + signature = 0x1e 0x94 0x03; + pagel = 0xd7; + bs2 = 0xa0; + chip_erase_delay = 9000; + pgm_enable = "1 0 1 0 1 1 0 0 0 1 0 1 0 0 1 1", + "x x x x x x x x x x x x x x x x"; + + chip_erase = "1 0 1 0 1 1 0 0 1 0 0 x x x x x", + "x x x x x x x x x x x x x x x x"; + + timeout = 200; + stabdelay = 100; + cmdexedelay = 25; + synchloops = 32; + bytedelay = 0; + pollindex = 3; + pollvalue = 0x53; + predelay = 1; + postdelay = 1; + pollmethod = 0; + + pp_controlstack = + 0x0E, 0x1E, 0x0F, 0x1F, 0x2E, 0x3E, 0x2F, 0x3F, + 0x4E, 0x5E, 0x4F, 0x5F, 0x6E, 0x7E, 0x6F, 0x7F, + 0x66, 0x76, 0x67, 0x77, 0x6A, 0x7A, 0x6B, 0x7B, + 0xBE, 0xFD, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00; + hventerstabdelay = 100; + progmodedelay = 100; + latchcycles = 6; + togglevtg = 0; + poweroffdelay = 0; + resetdelayms = 0; + resetdelayus = 0; + hvleavestabdelay = 15; + resetdelay = 15; + chiperasepulsewidth = 0; + chiperasepolltimeout = 10; + programfusepulsewidth = 0; + programfusepolltimeout = 5; + programlockpulsewidth = 0; + programlockpolltimeout = 5; + + idr = 0x31; + spmcr = 0x57; + allowfullpagebitstream = yes; + + ocdrev = 2; + + memory "eeprom" + paged = no; /* leave this "no" */ + page_size = 4; /* for parallel programming */ + size = 512; + min_write_delay = 9000; + max_write_delay = 9000; + readback_p1 = 0xff; + readback_p2 = 0xff; + read = " 1 0 1 0 0 0 0 0", + " 0 0 x x x x a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + write = " 1 1 0 0 0 0 0 0", + " 0 0 x x x x a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " i i i i i i i i"; + + loadpage_lo = " 1 1 0 0 0 0 0 1", + " 0 0 0 0 0 0 0 0", + " 0 0 0 0 0 0 a1 a0", + " i i i i i i i i"; + + writepage = " 1 1 0 0 0 0 1 0", + " 0 0 x x x x a9 a8", + " a7 a6 a5 a4 a3 a2 0 0", + " x x x x x x x x"; + + mode = 0x04; + delay = 10; + blocksize = 128; + readsize = 256; + ; + + memory "flash" + paged = yes; + size = 16384; + page_size = 128; + num_pages = 128; + min_write_delay = 4500; + max_write_delay = 4500; + readback_p1 = 0xff; + readback_p2 = 0xff; + read_lo = " 0 0 1 0 0 0 0 0", + " 0 0 a13 a12 a11 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + read_hi = " 0 0 1 0 1 0 0 0", + " 0 0 a13 a12 a11 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + loadpage_lo = " 0 1 0 0 0 0 0 0", + " 0 0 x x x x x x", + " x x a5 a4 a3 a2 a1 a0", + " i i i i i i i i"; + + loadpage_hi = " 0 1 0 0 1 0 0 0", + " 0 0 x x x x x x", + " x x a5 a4 a3 a2 a1 a0", + " i i i i i i i i"; + + writepage = " 0 1 0 0 1 1 0 0", + " 0 0 a13 a12 a11 a10 a9 a8", + " a7 a6 x x x x x x", + " x x x x x x x x"; + + mode = 0x21; + delay = 6; + blocksize = 128; + readsize = 256; + ; + + memory "lock" + size = 1; + read = "0 1 0 1 1 0 0 0 0 0 0 0 0 0 0 0", + "x x x x x x x x x x o o o o o o"; + + write = "1 0 1 0 1 1 0 0 1 1 1 x x x x x", + "x x x x x x x x 1 1 i i i i i i"; + min_write_delay = 9000; + max_write_delay = 9000; + ; + + memory "lfuse" + size = 1; + read = "0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0", + "x x x x x x x x o o o o o o o o"; + + write = "1 0 1 0 1 1 0 0 1 0 1 0 0 0 0 0", + "x x x x x x x x i i i i i i i i"; + min_write_delay = 9000; + max_write_delay = 9000; + ; + + memory "hfuse" + size = 1; + read = "0 1 0 1 1 0 0 0 0 0 0 0 1 0 0 0", + "x x x x x x x x o o o o o o o o"; + + write = "1 0 1 0 1 1 0 0 1 0 1 0 1 0 0 0", + "x x x x x x x x i i i i i i i i"; + min_write_delay = 9000; + max_write_delay = 9000; + ; + memory "signature" + size = 3; + read = "0 0 1 1 0 0 0 0 x x x x x x x x", + "x x x x x x a1 a0 o o o o o o o o"; + ; + memory "calibration" + size = 4; + + read = "0 0 1 1 1 0 0 0 0 0 0 x x x x x", + "0 0 0 0 0 0 a1 a0 o o o o o o o o"; + ; + ; + + +#------------------------------------------------------------ +# ATmega164P +#------------------------------------------------------------ + +# close to ATmega16 + +part parent "m16" + id = "m164p"; + desc = "ATmega164P"; + signature = 0x1e 0x94 0x0a; + + progmodedelay = 0; + latchcycles = 5; + togglevtg = 1; + poweroffdelay = 15; + resetdelayms = 1; + allowfullpagebitstream = no; + chip_erase_delay = 55000; + + ocdrev = 3; + ; + + +#------------------------------------------------------------ +# ATmega324P +#------------------------------------------------------------ + +# similar to ATmega164P + +part + id = "m324p"; + desc = "ATmega324P"; + has_jtag = yes; + stk500_devcode = 0x82; # no STK500v1 support, use the ATmega16 one + avr910_devcode = 0x74; + signature = 0x1e 0x95 0x08; + pagel = 0xd7; + bs2 = 0xa0; + chip_erase_delay = 55000; + pgm_enable = "1 0 1 0 1 1 0 0 0 1 0 1 0 0 1 1", + "x x x x x x x x x x x x x x x x"; + + chip_erase = "1 0 1 0 1 1 0 0 1 0 0 x x x x x", + "x x x x x x x x x x x x x x x x"; + + timeout = 200; + stabdelay = 100; + cmdexedelay = 25; + synchloops = 32; + bytedelay = 0; + pollindex = 3; + pollvalue = 0x53; + predelay = 1; + postdelay = 1; + pollmethod = 0; + + pp_controlstack = + 0x0E, 0x1E, 0x0F, 0x1F, 0x2E, 0x3E, 0x2F, 0x3F, + 0x4E, 0x5E, 0x4F, 0x5F, 0x6E, 0x7E, 0x6F, 0x7F, + 0x66, 0x76, 0x67, 0x77, 0x6A, 0x7A, 0x6B, 0x7B, + 0xBE, 0xFD, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00; + hventerstabdelay = 100; + progmodedelay = 0; + latchcycles = 5; + togglevtg = 1; + poweroffdelay = 15; + resetdelayms = 1; + resetdelayus = 0; + hvleavestabdelay = 15; + chiperasepulsewidth = 0; + chiperasepolltimeout = 10; + programfusepulsewidth = 0; + programfusepolltimeout = 5; + programlockpulsewidth = 0; + programlockpolltimeout = 5; + + idr = 0x31; + spmcr = 0x57; + allowfullpagebitstream = no; + + ocdrev = 3; + + memory "eeprom" + paged = no; /* leave this "no" */ + page_size = 4; /* for parallel programming */ + size = 1024; + min_write_delay = 9000; + max_write_delay = 9000; + readback_p1 = 0xff; + readback_p2 = 0xff; + read = " 1 0 1 0 0 0 0 0", + " 0 0 x x x a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + write = " 1 1 0 0 0 0 0 0", + " 0 0 x x x a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " i i i i i i i i"; + + loadpage_lo = " 1 1 0 0 0 0 0 1", + " 0 0 0 0 0 0 0 0", + " 0 0 0 0 0 0 a1 a0", + " i i i i i i i i"; + + writepage = " 1 1 0 0 0 0 1 0", + " 0 0 x x x a10 a9 a8", + " a7 a6 a5 a4 a3 a2 0 0", + " x x x x x x x x"; + + mode = 0x41; + delay = 10; + blocksize = 128; + readsize = 256; + ; + + memory "flash" + paged = yes; + size = 32768; + page_size = 128; + num_pages = 256; + min_write_delay = 4500; + max_write_delay = 4500; + readback_p1 = 0xff; + readback_p2 = 0xff; + read_lo = " 0 0 1 0 0 0 0 0", + " 0 a14 a13 a12 a11 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + read_hi = " 0 0 1 0 1 0 0 0", + " 0 a14 a13 a12 a11 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + loadpage_lo = " 0 1 0 0 0 0 0 0", + " 0 0 x x x x x x", + " x x a5 a4 a3 a2 a1 a0", + " i i i i i i i i"; + + loadpage_hi = " 0 1 0 0 1 0 0 0", + " 0 0 x x x x x x", + " x x a5 a4 a3 a2 a1 a0", + " i i i i i i i i"; + + writepage = " 0 1 0 0 1 1 0 0", + " 0 a14 a13 a12 a11 a10 a9 a8", + " a7 a6 x x x x x x", + " x x x x x x x x"; + + mode = 0x21; + delay = 6; + blocksize = 256; + readsize = 256; + ; + + memory "lock" + size = 1; + read = "0 1 0 1 1 0 0 0 0 0 0 0 0 0 0 0", + "x x x x x x x x x x o o o o o o"; + + write = "1 0 1 0 1 1 0 0 1 1 1 x x x x x", + "x x x x x x x x 1 1 i i i i i i"; + min_write_delay = 9000; + max_write_delay = 9000; + ; + + memory "lfuse" + size = 1; + read = "0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0", + "x x x x x x x x o o o o o o o o"; + + write = "1 0 1 0 1 1 0 0 1 0 1 0 0 0 0 0", + "x x x x x x x x i i i i i i i i"; + min_write_delay = 9000; + max_write_delay = 9000; + ; + + memory "hfuse" + size = 1; + read = "0 1 0 1 1 0 0 0 0 0 0 0 1 0 0 0", + "x x x x x x x x o o o o o o o o"; + + write = "1 0 1 0 1 1 0 0 1 0 1 0 1 0 0 0", + "x x x x x x x x i i i i i i i i"; + min_write_delay = 9000; + max_write_delay = 9000; + ; + + memory "efuse" + size = 1; + + read = "0 1 0 1 0 0 0 0 0 0 0 0 1 0 0 0", + "x x x x x x x x o o o o o o o o"; + + write = "1 0 1 0 1 1 0 0 1 0 1 0 0 1 0 0", + "x x x x x x x x 1 1 1 1 1 i i i"; + min_write_delay = 9000; + max_write_delay = 9000; + ; + + memory "signature" + size = 3; + read = "0 0 1 1 0 0 0 0 x x x x x x x x", + "x x x x x x a1 a0 o o o o o o o o"; + ; + + memory "calibration" + size = 1; + + read = "0 0 1 1 1 0 0 0 0 0 0 x x x x x", + "0 0 0 0 0 0 0 0 o o o o o o o o"; + ; + ; + + +#------------------------------------------------------------ +# ATmega324PA +#------------------------------------------------------------ + +# similar to ATmega324P + +part parent "m324p" + id = "m324pa"; + desc = "ATmega324PA"; + signature = 0x1e 0x95 0x11; + + ocdrev = 3; + ; + + +#------------------------------------------------------------ +# ATmega644 +#------------------------------------------------------------ + +# similar to ATmega164 + +part + id = "m644"; + desc = "ATmega644"; + has_jtag = yes; + stk500_devcode = 0x82; # no STK500v1 support, use the ATmega16 one + avr910_devcode = 0x74; + signature = 0x1e 0x96 0x09; + pagel = 0xd7; + bs2 = 0xa0; + chip_erase_delay = 55000; + pgm_enable = "1 0 1 0 1 1 0 0 0 1 0 1 0 0 1 1", + "x x x x x x x x x x x x x x x x"; + + chip_erase = "1 0 1 0 1 1 0 0 1 0 0 x x x x x", + "x x x x x x x x x x x x x x x x"; + + timeout = 200; + stabdelay = 100; + cmdexedelay = 25; + synchloops = 32; + bytedelay = 0; + pollindex = 3; + pollvalue = 0x53; + predelay = 1; + postdelay = 1; + pollmethod = 0; + + pp_controlstack = + 0x0E, 0x1E, 0x0F, 0x1F, 0x2E, 0x3E, 0x2F, 0x3F, + 0x4E, 0x5E, 0x4F, 0x5F, 0x6E, 0x7E, 0x6F, 0x7F, + 0x66, 0x76, 0x67, 0x77, 0x6A, 0x7A, 0x6B, 0x7B, + 0xBE, 0xFD, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02; + hventerstabdelay = 100; + progmodedelay = 0; + latchcycles = 6; + togglevtg = 0; + poweroffdelay = 0; + resetdelayms = 0; + resetdelayus = 0; + hvleavestabdelay = 15; + chiperasepulsewidth = 0; + chiperasepolltimeout = 10; + programfusepulsewidth = 0; + programfusepolltimeout = 5; + programlockpulsewidth = 0; + programlockpolltimeout = 5; + + idr = 0x31; + spmcr = 0x57; + allowfullpagebitstream = no; + + ocdrev = 3; + + memory "eeprom" + paged = no; /* leave this "no" */ + page_size = 8; /* for parallel programming */ + size = 2048; + min_write_delay = 9000; + max_write_delay = 9000; + readback_p1 = 0xff; + readback_p2 = 0xff; + read = " 1 0 1 0 0 0 0 0", + " 0 0 x x a11 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + write = " 1 1 0 0 0 0 0 0", + " 0 0 x x a11 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " i i i i i i i i"; + + loadpage_lo = " 1 1 0 0 0 0 0 1", + " 0 0 0 0 0 0 0 0", + " 0 0 0 0 0 a2 a1 a0", + " i i i i i i i i"; + + writepage = " 1 1 0 0 0 0 1 0", + " 0 0 x x a11 a10 a9 a8", + " a7 a6 a5 a4 a3 0 0 0", + " x x x x x x x x"; + + mode = 0x41; + delay = 10; + blocksize = 128; + readsize = 256; + ; + + memory "flash" + paged = yes; + size = 65536; + page_size = 256; + num_pages = 256; + min_write_delay = 4500; + max_write_delay = 4500; + readback_p1 = 0xff; + readback_p2 = 0xff; + read_lo = " 0 0 1 0 0 0 0 0", + "a15 a14 a13 a12 a11 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + read_hi = " 0 0 1 0 1 0 0 0", + "a15 a14 a13 a12 a11 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + loadpage_lo = " 0 1 0 0 0 0 0 0", + " 0 0 x x x x x x", + " x a6 a5 a4 a3 a2 a1 a0", + " i i i i i i i i"; + + loadpage_hi = " 0 1 0 0 1 0 0 0", + " 0 0 x x x x x x", + " x a6 a5 a4 a3 a2 a1 a0", + " i i i i i i i i"; + + writepage = " 0 1 0 0 1 1 0 0", + "a15 a14 a13 a12 a11 a10 a9 a8", + " a7 x x x x x x x", + " x x x x x x x x"; + + mode = 0x21; + delay = 6; + blocksize = 256; + readsize = 256; + ; + + memory "lock" + size = 1; + read = "0 1 0 1 1 0 0 0 0 0 0 0 0 0 0 0", + "x x x x x x x x x x o o o o o o"; + + write = "1 0 1 0 1 1 0 0 1 1 1 x x x x x", + "x x x x x x x x 1 1 i i i i i i"; + min_write_delay = 9000; + max_write_delay = 9000; + ; + + memory "lfuse" + size = 1; + read = "0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0", + "x x x x x x x x o o o o o o o o"; + + write = "1 0 1 0 1 1 0 0 1 0 1 0 0 0 0 0", + "x x x x x x x x i i i i i i i i"; + min_write_delay = 9000; + max_write_delay = 9000; + ; + + memory "hfuse" + size = 1; + read = "0 1 0 1 1 0 0 0 0 0 0 0 1 0 0 0", + "x x x x x x x x o o o o o o o o"; + + write = "1 0 1 0 1 1 0 0 1 0 1 0 1 0 0 0", + "x x x x x x x x i i i i i i i i"; + min_write_delay = 9000; + max_write_delay = 9000; + ; + + memory "efuse" + size = 1; + + read = "0 1 0 1 0 0 0 0 0 0 0 0 1 0 0 0", + "x x x x x x x x o o o o o o o o"; + + write = "1 0 1 0 1 1 0 0 1 0 1 0 0 1 0 0", + "x x x x x x x x 1 1 1 1 1 i i i"; + min_write_delay = 9000; + max_write_delay = 9000; + ; + + memory "signature" + size = 3; + read = "0 0 1 1 0 0 0 0 x x x x x x x x", + "x x x x x x a1 a0 o o o o o o o o"; + ; + + memory "calibration" + size = 1; + + read = "0 0 1 1 1 0 0 0 0 0 0 x x x x x", + "0 0 0 0 0 0 0 0 o o o o o o o o"; + ; + ; + +#------------------------------------------------------------ +# ATmega644P +#------------------------------------------------------------ + +# similar to ATmega164p + +part parent "m644" + id = "m644p"; + desc = "ATmega644P"; + signature = 0x1e 0x96 0x0a; + + ocdrev = 3; + ; + + + +#------------------------------------------------------------ +# ATmega1284 +#------------------------------------------------------------ + +# similar to ATmega164 + +part + id = "m1284"; + desc = "ATmega1284"; + has_jtag = yes; + stk500_devcode = 0x82; # no STK500v1 support, use the ATmega16 one + avr910_devcode = 0x74; + signature = 0x1e 0x97 0x06; + pagel = 0xd7; + bs2 = 0xa0; + chip_erase_delay = 55000; + pgm_enable = "1 0 1 0 1 1 0 0 0 1 0 1 0 0 1 1", + "x x x x x x x x x x x x x x x x"; + + chip_erase = "1 0 1 0 1 1 0 0 1 0 0 x x x x x", + "x x x x x x x x x x x x x x x x"; + + timeout = 200; + stabdelay = 100; + cmdexedelay = 25; + synchloops = 32; + bytedelay = 0; + pollindex = 3; + pollvalue = 0x53; + predelay = 1; + postdelay = 1; + pollmethod = 1; + + pp_controlstack = + 0x0E, 0x1E, 0x0F, 0x1F, 0x2E, 0x3E, 0x2F, 0x3F, + 0x4E, 0x5E, 0x4F, 0x5F, 0x6E, 0x7E, 0x6F, 0x7F, + 0x66, 0x76, 0x67, 0x77, 0x6A, 0x7A, 0x6B, 0x7B, + 0xBE, 0xFD, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02; + hventerstabdelay = 100; + progmodedelay = 0; + latchcycles = 6; + togglevtg = 1; + poweroffdelay = 15; + resetdelayms = 1; + resetdelayus = 0; + hvleavestabdelay = 15; + chiperasepulsewidth = 0; + chiperasepolltimeout = 10; + programfusepulsewidth = 0; + programfusepolltimeout = 5; + programlockpulsewidth = 0; + programlockpolltimeout = 5; + + idr = 0x31; + spmcr = 0x57; + allowfullpagebitstream = no; + + ocdrev = 3; + + memory "eeprom" + paged = no; /* leave this "no" */ + page_size = 8; /* for parallel programming */ + size = 4096; + min_write_delay = 9000; + max_write_delay = 9000; + readback_p1 = 0xff; + readback_p2 = 0xff; + read = " 1 0 1 0 0 0 0 0", + " 0 0 x x a11 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + write = " 1 1 0 0 0 0 0 0", + " 0 0 x x a11 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " i i i i i i i i"; + + loadpage_lo = " 1 1 0 0 0 0 0 1", + " 0 0 0 0 0 0 0 0", + " 0 0 0 0 0 a2 a1 a0", + " i i i i i i i i"; + + writepage = " 1 1 0 0 0 0 1 0", + " 0 0 x x a11 a10 a9 a8", + " a7 a6 a5 a4 a3 0 0 0", + " x x x x x x x x"; + + mode = 0x41; + delay = 10; + blocksize = 128; + readsize = 256; + ; + + memory "flash" + paged = yes; + size = 131072; + page_size = 256; + num_pages = 512; + min_write_delay = 4500; + max_write_delay = 4500; + readback_p1 = 0xff; + readback_p2 = 0xff; + read_lo = " 0 0 1 0 0 0 0 0", + "a15 a14 a13 a12 a11 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + read_hi = " 0 0 1 0 1 0 0 0", + "a15 a14 a13 a12 a11 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + loadpage_lo = " 0 1 0 0 0 0 0 0", + " 0 0 x x x x x x", + " x a6 a5 a4 a3 a2 a1 a0", + " i i i i i i i i"; + + loadpage_hi = " 0 1 0 0 1 0 0 0", + " 0 0 x x x x x x", + " x a6 a5 a4 a3 a2 a1 a0", + " i i i i i i i i"; + + writepage = " 0 1 0 0 1 1 0 0", + "a15 a14 a13 a12 a11 a10 a9 a8", + " a7 x x x x x x x", + " x x x x x x x x"; + + mode = 0x41; + delay = 10; + blocksize = 256; + readsize = 256; + ; + + memory "lock" + size = 1; + read = "0 1 0 1 1 0 0 0 0 0 0 0 0 0 0 0", + "x x x x x x x x x x o o o o o o"; + + write = "1 0 1 0 1 1 0 0 1 1 1 x x x x x", + "x x x x x x x x 1 1 i i i i i i"; + min_write_delay = 9000; + max_write_delay = 9000; + ; + + memory "lfuse" + size = 1; + read = "0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0", + "x x x x x x x x o o o o o o o o"; + + write = "1 0 1 0 1 1 0 0 1 0 1 0 0 0 0 0", + "x x x x x x x x i i i i i i i i"; + min_write_delay = 9000; + max_write_delay = 9000; + ; + + memory "hfuse" + size = 1; + read = "0 1 0 1 1 0 0 0 0 0 0 0 1 0 0 0", + "x x x x x x x x o o o o o o o o"; + + write = "1 0 1 0 1 1 0 0 1 0 1 0 1 0 0 0", + "x x x x x x x x i i i i i i i i"; + min_write_delay = 9000; + max_write_delay = 9000; + ; + + memory "efuse" + size = 1; + + read = "0 1 0 1 0 0 0 0 0 0 0 0 1 0 0 0", + "x x x x x x x x o o o o o o o o"; + + write = "1 0 1 0 1 1 0 0 1 0 1 0 0 1 0 0", + "x x x x x x x x 1 1 1 1 1 i i i"; + min_write_delay = 9000; + max_write_delay = 9000; + ; + + memory "signature" + size = 3; + read = "0 0 1 1 0 0 0 0 x x x x x x x x", + "x x x x x x a1 a0 o o o o o o o o"; + ; + + memory "calibration" + size = 1; + + read = "0 0 1 1 1 0 0 0 0 0 0 x x x x x", + "0 0 0 0 0 0 0 0 o o o o o o o o"; + ; + ; + + + +#------------------------------------------------------------ +# ATmega1284P +#------------------------------------------------------------ + +# similar to ATmega164p + +part + id = "m1284p"; + desc = "ATmega1284P"; + has_jtag = yes; + stk500_devcode = 0x82; # no STK500v1 support, use the ATmega16 one + avr910_devcode = 0x74; + signature = 0x1e 0x97 0x05; + pagel = 0xd7; + bs2 = 0xa0; + chip_erase_delay = 55000; + pgm_enable = "1 0 1 0 1 1 0 0 0 1 0 1 0 0 1 1", + "x x x x x x x x x x x x x x x x"; + + chip_erase = "1 0 1 0 1 1 0 0 1 0 0 x x x x x", + "x x x x x x x x x x x x x x x x"; + + timeout = 200; + stabdelay = 100; + cmdexedelay = 25; + synchloops = 32; + bytedelay = 0; + pollindex = 3; + pollvalue = 0x53; + predelay = 1; + postdelay = 1; + pollmethod = 1; + + pp_controlstack = + 0x0E, 0x1E, 0x0F, 0x1F, 0x2E, 0x3E, 0x2F, 0x3F, + 0x4E, 0x5E, 0x4F, 0x5F, 0x6E, 0x7E, 0x6F, 0x7F, + 0x66, 0x76, 0x67, 0x77, 0x6A, 0x7A, 0x6B, 0x7B, + 0xBE, 0xFD, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02; + hventerstabdelay = 100; + progmodedelay = 0; + latchcycles = 6; + togglevtg = 1; + poweroffdelay = 15; + resetdelayms = 1; + resetdelayus = 0; + hvleavestabdelay = 15; + chiperasepulsewidth = 0; + chiperasepolltimeout = 10; + programfusepulsewidth = 0; + programfusepolltimeout = 5; + programlockpulsewidth = 0; + programlockpolltimeout = 5; + + idr = 0x31; + spmcr = 0x57; + allowfullpagebitstream = no; + + ocdrev = 3; + + memory "eeprom" + paged = no; /* leave this "no" */ + page_size = 8; /* for parallel programming */ + size = 4096; + min_write_delay = 9000; + max_write_delay = 9000; + readback_p1 = 0xff; + readback_p2 = 0xff; + read = " 1 0 1 0 0 0 0 0", + " 0 0 x x a11 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + write = " 1 1 0 0 0 0 0 0", + " 0 0 x x a11 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " i i i i i i i i"; + + loadpage_lo = " 1 1 0 0 0 0 0 1", + " 0 0 0 0 0 0 0 0", + " 0 0 0 0 0 a2 a1 a0", + " i i i i i i i i"; + + writepage = " 1 1 0 0 0 0 1 0", + " 0 0 x x a11 a10 a9 a8", + " a7 a6 a5 a4 a3 0 0 0", + " x x x x x x x x"; + + mode = 0x41; + delay = 10; + blocksize = 128; + readsize = 256; + ; + + memory "flash" + paged = yes; + size = 131072; + page_size = 256; + num_pages = 512; + min_write_delay = 4500; + max_write_delay = 4500; + readback_p1 = 0xff; + readback_p2 = 0xff; + read_lo = " 0 0 1 0 0 0 0 0", + "a15 a14 a13 a12 a11 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + read_hi = " 0 0 1 0 1 0 0 0", + "a15 a14 a13 a12 a11 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + loadpage_lo = " 0 1 0 0 0 0 0 0", + " 0 0 x x x x x x", + " x a6 a5 a4 a3 a2 a1 a0", + " i i i i i i i i"; + + loadpage_hi = " 0 1 0 0 1 0 0 0", + " 0 0 x x x x x x", + " x a6 a5 a4 a3 a2 a1 a0", + " i i i i i i i i"; + + writepage = " 0 1 0 0 1 1 0 0", + "a15 a14 a13 a12 a11 a10 a9 a8", + " a7 x x x x x x x", + " x x x x x x x x"; + + mode = 0x41; + delay = 10; + blocksize = 256; + readsize = 256; + ; + + memory "lock" + size = 1; + read = "0 1 0 1 1 0 0 0 0 0 0 0 0 0 0 0", + "x x x x x x x x x x o o o o o o"; + + write = "1 0 1 0 1 1 0 0 1 1 1 x x x x x", + "x x x x x x x x 1 1 i i i i i i"; + min_write_delay = 9000; + max_write_delay = 9000; + ; + + memory "lfuse" + size = 1; + read = "0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0", + "x x x x x x x x o o o o o o o o"; + + write = "1 0 1 0 1 1 0 0 1 0 1 0 0 0 0 0", + "x x x x x x x x i i i i i i i i"; + min_write_delay = 9000; + max_write_delay = 9000; + ; + + memory "hfuse" + size = 1; + read = "0 1 0 1 1 0 0 0 0 0 0 0 1 0 0 0", + "x x x x x x x x o o o o o o o o"; + + write = "1 0 1 0 1 1 0 0 1 0 1 0 1 0 0 0", + "x x x x x x x x i i i i i i i i"; + min_write_delay = 9000; + max_write_delay = 9000; + ; + + memory "efuse" + size = 1; + + read = "0 1 0 1 0 0 0 0 0 0 0 0 1 0 0 0", + "x x x x x x x x o o o o o o o o"; + + write = "1 0 1 0 1 1 0 0 1 0 1 0 0 1 0 0", + "x x x x x x x x 1 1 1 1 1 i i i"; + min_write_delay = 9000; + max_write_delay = 9000; + ; + + memory "signature" + size = 3; + read = "0 0 1 1 0 0 0 0 x x x x x x x x", + "x x x x x x a1 a0 o o o o o o o o"; + ; + + memory "calibration" + size = 1; + + read = "0 0 1 1 1 0 0 0 0 0 0 x x x x x", + "0 0 0 0 0 0 0 0 o o o o o o o o"; + ; + ; + + + +#------------------------------------------------------------ +# ATmega162 +#------------------------------------------------------------ + +part + id = "m162"; + desc = "ATmega162"; + has_jtag = yes; + stk500_devcode = 0x83; + avr910_devcode = 0x63; + signature = 0x1e 0x94 0x04; + chip_erase_delay = 9000; + pagel = 0xd7; + bs2 = 0xa0; + + idr = 0x04; + spmcr = 0x57; + allowfullpagebitstream = yes; + + pgm_enable = "1 0 1 0 1 1 0 0 0 1 0 1 0 0 1 1", + "x x x x x x x x x x x x x x x x"; + + chip_erase = "1 0 1 0 1 1 0 0 1 0 0 x x x x x", + "x x x x x x x x x x x x x x x x"; + + ocdrev = 2; + + memory "flash" + paged = yes; + size = 16384; + page_size = 128; + num_pages = 128; + min_write_delay = 4500; + max_write_delay = 4500; + readback_p1 = 0xff; + readback_p2 = 0xff; + + read_lo = " 0 0 1 0 0 0 0 0", + " 0 0 a13 a12 a11 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + read_hi = " 0 0 1 0 1 0 0 0", + " 0 0 a13 a12 a11 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + loadpage_lo = " 0 1 0 0 0 0 0 0", + " 0 0 x x x x x x", + " x x a5 a4 a3 a2 a1 a0", + " i i i i i i i i"; + + loadpage_hi = " 0 1 0 0 1 0 0 0", + " 0 0 x x x x x x", + " x x a5 a4 a3 a2 a1 a0", + " i i i i i i i i"; + + writepage = " 0 1 0 0 1 1 0 0", + " 0 0 a13 a12 a11 a10 a9 a8", + " a7 a6 x x x x x x", + " x x x x x x x x"; + mode = 0x41; + delay = 10; + blocksize = 128; + readsize = 256; + + ; + + timeout = 200; + stabdelay = 100; + cmdexedelay = 25; + synchloops = 32; + bytedelay = 0; + pollindex = 3; + pollvalue = 0x53; + predelay = 1; + postdelay = 1; + pollmethod = 0; + + pp_controlstack = + 0x0E, 0x1E, 0x0F, 0x1F, 0x2E, 0x3E, 0x2F, 0x3F, + 0x4E, 0x5E, 0x4F, 0x5F, 0x6E, 0x7E, 0x6F, 0x7F, + 0x66, 0x76, 0x67, 0x77, 0x6A, 0x7A, 0x6B, 0x7B, + 0xBE, 0xFD, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00; + hventerstabdelay = 100; + progmodedelay = 0; + latchcycles = 6; + togglevtg = 0; + poweroffdelay = 0; + resetdelayms = 0; + resetdelayus = 0; + hvleavestabdelay = 15; + chiperasepulsewidth = 0; + chiperasepolltimeout = 10; + programfusepulsewidth = 0; + programfusepolltimeout = 5; + programlockpulsewidth = 0; + programlockpolltimeout = 5; + + memory "eeprom" + paged = no; /* leave this "no" */ + page_size = 4; /* for parallel programming */ + size = 512; + min_write_delay = 9000; + max_write_delay = 9000; + readback_p1 = 0xff; + readback_p2 = 0xff; + + read = " 1 0 1 0 0 0 0 0", + " 0 0 x x x x a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + write = " 1 1 0 0 0 0 0 0", + " 0 0 x x x x a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " i i i i i i i i"; + + loadpage_lo = " 1 1 0 0 0 0 0 1", + " 0 0 0 0 0 0 0 0", + " 0 0 0 0 0 0 a1 a0", + " i i i i i i i i"; + + writepage = " 1 1 0 0 0 0 1 0", + " 0 0 x x x x a9 a8", + " a7 a6 a5 a4 a3 a2 0 0", + " x x x x x x x x"; + + mode = 0x41; + delay = 20; + blocksize = 4; + readsize = 256; + ; + + memory "lfuse" + size = 1; + min_write_delay = 16000; + max_write_delay = 16000; + read = "0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0", + "x x x x x x x x o o o o o o o o"; + + write = "1 0 1 0 1 1 0 0 1 0 1 0 0 0 0 0", + "x x x x x x x x i i i i i i i i"; + ; + + memory "hfuse" + size = 1; + min_write_delay = 16000; + max_write_delay = 16000; + + read = "0 1 0 1 1 0 0 0 0 0 0 0 1 0 0 0", + "x x x x x x x x o o o o o o o o"; + + write = "1 0 1 0 1 1 0 0 1 0 1 0 1 0 0 0", + "x x x x x x x x i i i i i i i i"; + ; + + memory "efuse" + size = 1; + min_write_delay = 16000; + max_write_delay = 16000; + + read = "0 1 0 1 0 0 0 0 0 0 0 0 1 0 0 0", + "x x x x x x x x o o o o o o o o"; + + write = "1 0 1 0 1 1 0 0 1 0 1 0 0 1 0 0", + "x x x x x x x x 1 1 1 1 1 i i i"; + ; + + memory "lock" + size = 1; + min_write_delay = 16000; + max_write_delay = 16000; + + read = "0 1 0 1 1 0 0 0 0 0 0 0 0 0 0 0", + "x x x x x x x x x x o o o o o o"; + + write = "1 0 1 0 1 1 0 0 1 1 1 x x x x x", + "x x x x x x x x 1 1 i i i i i i"; + ; + + memory "signature" + size = 3; + + read = "0 0 1 1 0 0 0 0 0 0 x x x x x x", + "x x x x x x a1 a0 o o o o o o o o"; + ; + + memory "calibration" + size = 1; + + read = "0 0 1 1 1 0 0 0 0 0 x x x x x x", + "0 0 0 0 0 0 0 0 o o o o o o o o"; + ; +; + + + +#------------------------------------------------------------ +# ATmega163 +#------------------------------------------------------------ + +part + id = "m163"; + desc = "ATmega163"; + stk500_devcode = 0x81; + avr910_devcode = 0x64; + signature = 0x1e 0x94 0x02; + chip_erase_delay = 32000; + pagel = 0xd7; + bs2 = 0xa0; + pgm_enable = "1 0 1 0 1 1 0 0 0 1 0 1 0 0 1 1", + "x x x x x x x x x x x x x x x x"; + + chip_erase = "1 0 1 0 1 1 0 0 1 0 0 0 0 0 0 0", + "x x x x x x x x x x x x x x x x"; + + timeout = 200; + stabdelay = 100; + cmdexedelay = 25; + synchloops = 32; + bytedelay = 0; + pollindex = 3; + pollvalue = 0x53; + predelay = 1; + postdelay = 1; + pollmethod = 0; + + pp_controlstack = + 0x0E, 0x1E, 0x0F, 0x1F, 0x2E, 0x3E, 0x2F, 0x3F, + 0x4E, 0x5E, 0x4F, 0x5F, 0x6E, 0x7E, 0x6F, 0x7F, + 0x66, 0x76, 0x67, 0x77, 0x6A, 0x7A, 0x6B, 0x7B, + 0xBE, 0xFD, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00; + hventerstabdelay = 100; + progmodedelay = 0; + latchcycles = 0; + togglevtg = 0; + poweroffdelay = 0; + resetdelayms = 0; + resetdelayus = 0; + hvleavestabdelay = 15; + chiperasepulsewidth = 0; + chiperasepolltimeout = 30; + programfusepulsewidth = 0; + programfusepolltimeout = 2; + programlockpulsewidth = 0; + programlockpolltimeout = 2; + + + memory "eeprom" + size = 512; + min_write_delay = 4000; + max_write_delay = 4000; + readback_p1 = 0xff; + readback_p2 = 0xff; + read = " 1 0 1 0 0 0 0 0", + " x x x x x x x a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + write = " 1 1 0 0 0 0 0 0", + " x x x x x x x a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " i i i i i i i i"; + mode = 0x41; + delay = 20; + blocksize = 4; + readsize = 256; + ; + + memory "flash" + paged = yes; + size = 16384; + page_size = 128; + num_pages = 128; + min_write_delay = 16000; + max_write_delay = 16000; + readback_p1 = 0xff; + readback_p2 = 0xff; + read_lo = " 0 0 1 0 0 0 0 0", + " x x x a12 a11 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + read_hi = " 0 0 1 0 1 0 0 0", + " x x x a12 a11 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + loadpage_lo = " 0 1 0 0 0 0 0 0", + " x x x x x x x x", + " x x a5 a4 a3 a2 a1 a0", + " i i i i i i i i"; + + loadpage_hi = " 0 1 0 0 1 0 0 0", + " x x x x x x x x", + " x x a5 a4 a3 a2 a1 a0", + " i i i i i i i i"; + + writepage = " 0 1 0 0 1 1 0 0", + " x x x a12 a11 a10 a9 a8", + " a7 a6 x x x x x x", + " x x x x x x x x"; + + mode = 0x11; + delay = 20; + blocksize = 128; + readsize = 256; + ; + + memory "lfuse" + size = 1; + min_write_delay = 2000; + max_write_delay = 2000; + read = "0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0", + "x x x x x x x x o o x x o o o o"; + + write = "1 0 1 0 1 1 0 0 1 0 1 0 0 0 0 0", + "x x x x x x x x i i 1 1 i i i i"; + ; + + memory "hfuse" + size = 1; + min_write_delay = 2000; + max_write_delay = 2000; + read = "0 1 0 1 1 0 0 0 0 0 0 0 1 0 0 0", + "x x x x x x x x x x x x 1 o o o"; + + write = "1 0 1 0 1 1 0 0 1 0 1 0 1 0 0 0", + "x x x x x x x x 1 1 1 1 1 i i i"; + ; + + memory "lock" + size = 1; + min_write_delay = 2000; + max_write_delay = 2000; + read = "0 1 0 1 1 0 0 0 0 0 0 0 0 0 0 0", + "x x x x 0 x x x x x o o o o o o"; + + write = "1 0 1 0 1 1 0 0 1 1 1 x x x x x", + "x x x x x x x x 1 1 i i i i i i"; + ; + + memory "signature" + size = 3; + read = "0 0 1 1 0 0 0 0 x x x x x x x x", + "x x x x x x a1 a0 o o o o o o o o"; + ; + + memory "calibration" + size = 1; + read = "0 0 1 1 1 0 0 0 x x x x x x x x", + "0 0 0 0 0 0 0 0 o o o o o o o o"; + ; + ; + +#------------------------------------------------------------ +# ATmega169 +#------------------------------------------------------------ + +part + id = "m169"; + desc = "ATmega169"; + has_jtag = yes; + stk500_devcode = 0x85; + avr910_devcode = 0x78; + signature = 0x1e 0x94 0x05; + chip_erase_delay = 9000; + pgm_enable = "1 0 1 0 1 1 0 0 0 1 0 1 0 0 1 1", + "x x x x x x x x x x x x x x x x"; + + chip_erase = "1 0 1 0 1 1 0 0 1 0 0 0 0 0 0 0", + "x x x x x x x x x x x x x x x x"; + timeout = 200; + stabdelay = 100; + cmdexedelay = 25; + synchloops = 32; + bytedelay = 0; + pollindex = 3; + pollvalue = 0x53; + predelay = 1; + postdelay = 1; + pollmethod = 1; + + pp_controlstack = + 0x0E, 0x1E, 0x0F, 0x1F, 0x2E, 0x3E, 0x2F, 0x3F, + 0x4E, 0x5E, 0x4F, 0x5F, 0x6E, 0x7E, 0x6F, 0x7F, + 0x66, 0x76, 0x67, 0x77, 0x6A, 0x7A, 0x6B, 0x7B, + 0xBE, 0xFD, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00; + hventerstabdelay = 100; + progmodedelay = 0; + latchcycles = 5; + togglevtg = 1; + poweroffdelay = 15; + resetdelayms = 1; + resetdelayus = 0; + hvleavestabdelay = 15; + chiperasepulsewidth = 0; + chiperasepolltimeout = 10; + programfusepulsewidth = 0; + programfusepolltimeout = 5; + programlockpulsewidth = 0; + programlockpolltimeout = 5; + + idr = 0x31; + spmcr = 0x57; + + ocdrev = 2; + + memory "eeprom" + paged = no; /* leave this "no" */ + page_size = 4; /* for parallel programming */ + size = 512; + min_write_delay = 9000; + max_write_delay = 9000; + readback_p1 = 0xff; + readback_p2 = 0xff; + read = " 1 0 1 0 0 0 0 0", + " x x x x x x x a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + write = " 1 1 0 0 0 0 0 0", + " x x x x x x x a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " i i i i i i i i"; + + loadpage_lo = " 1 1 0 0 0 0 0 1", + " 0 0 0 0 0 0 0 0", + " 0 0 0 0 0 0 a1 a0", + " i i i i i i i i"; + + writepage = " 1 1 0 0 0 0 1 0", + " 0 0 x x x x x a8", + " a7 a6 a5 a4 a3 a2 0 0", + " x x x x x x x x"; + + mode = 0x41; + delay = 20; + blocksize = 4; + readsize = 256; + ; + + memory "flash" + paged = yes; + size = 16384; + page_size = 128; + num_pages = 128; + min_write_delay = 4500; + max_write_delay = 4500; + readback_p1 = 0xff; + readback_p2 = 0xff; + read_lo = " 0 0 1 0 0 0 0 0", + " x x x a12 a11 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + read_hi = " 0 0 1 0 1 0 0 0", + " x x x a12 a11 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + loadpage_lo = " 0 1 0 0 0 0 0 0", + " x x x x x x x x", + " x x a5 a4 a3 a2 a1 a0", + " i i i i i i i i"; + + loadpage_hi = " 0 1 0 0 1 0 0 0", + " x x x x x x x x", + " x x a5 a4 a3 a2 a1 a0", + " i i i i i i i i"; + + writepage = " 0 1 0 0 1 1 0 0", + " x x x a12 a11 a10 a9 a8", + " a7 a6 x x x x x x", + " x x x x x x x x"; + + mode = 0x41; + delay = 6; + blocksize = 128; + readsize = 256; + ; + + memory "lfuse" + size = 1; + min_write_delay = 2000; + max_write_delay = 2000; + read = "0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0", + "x x x x x x x x o o o o o o o o"; + + write = "1 0 1 0 1 1 0 0 1 0 1 0 0 0 0 0", + "x x x x x x x x i i i i i i i i"; + ; + + memory "hfuse" + size = 1; + min_write_delay = 2000; + max_write_delay = 2000; + read = "0 1 0 1 1 0 0 0 0 0 0 0 1 0 0 0", + "x x x x x x x x o o o o o o o o"; + + write = "1 0 1 0 1 1 0 0 1 0 1 0 1 0 0 0", + "x x x x x x x x i i i i i i i i"; + ; + + memory "efuse" + size = 1; + write = "1 0 1 0 1 1 0 0 1 0 1 0 0 1 0 0", + "x x x x x x x x x x x x i i i i"; + + read = "0 1 0 1 0 0 0 0 0 0 0 0 1 0 0 0", + "x x x x x x x x o o o o o o o o"; + ; + + memory "lock" + size = 1; + min_write_delay = 2000; + max_write_delay = 2000; + read = "0 1 0 1 1 0 0 0 0 0 0 0 0 0 0 0", + "x x x x x x x x x x o o o o o o"; + + write = "1 0 1 0 1 1 0 0 1 1 1 x x x x x", + "x x x x x x x x 1 1 i i i i i i"; + ; + + memory "signature" + size = 3; + read = "0 0 1 1 0 0 0 0 0 0 0 x x x x x", + "x x x x x x a1 a0 o o o o o o o o"; + ; + + memory "calibration" + size = 1; + read = "0 0 1 1 1 0 0 0 0 0 0 x x x x x", + "0 0 0 0 0 0 0 0 o o o o o o o o"; + ; + ; + +#------------------------------------------------------------ +# ATmega329 +#------------------------------------------------------------ + +part + id = "m329"; + desc = "ATmega329"; + has_jtag = yes; +# stk500_devcode = 0x85; # no STK500 support, only STK500v2 +# avr910_devcode = 0x?; # try the ATmega169 one: + avr910_devcode = 0x75; + signature = 0x1e 0x95 0x03; + chip_erase_delay = 9000; + pgm_enable = "1 0 1 0 1 1 0 0 0 1 0 1 0 0 1 1", + "x x x x x x x x x x x x x x x x"; + + chip_erase = "1 0 1 0 1 1 0 0 1 0 0 0 0 0 0 0", + "x x x x x x x x x x x x x x x x"; + timeout = 200; + stabdelay = 100; + cmdexedelay = 25; + synchloops = 32; + bytedelay = 0; + pollindex = 3; + pollvalue = 0x53; + predelay = 1; + postdelay = 1; + pollmethod = 1; + + pp_controlstack = + 0x0E, 0x1E, 0x0F, 0x1F, 0x2E, 0x3E, 0x2F, 0x3F, + 0x4E, 0x5E, 0x4F, 0x5F, 0x6E, 0x7E, 0x6F, 0x7F, + 0x66, 0x76, 0x67, 0x77, 0x6A, 0x7A, 0x6B, 0x7B, + 0xBE, 0xFD, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00; + hventerstabdelay = 100; + progmodedelay = 0; + latchcycles = 5; + togglevtg = 1; + poweroffdelay = 15; + resetdelayms = 1; + resetdelayus = 0; + hvleavestabdelay = 15; + chiperasepulsewidth = 0; + chiperasepolltimeout = 10; + programfusepulsewidth = 0; + programfusepolltimeout = 5; + programlockpulsewidth = 0; + programlockpolltimeout = 5; + + idr = 0x31; + spmcr = 0x57; + + ocdrev = 3; + + memory "eeprom" + paged = no; /* leave this "no" */ + page_size = 4; /* for parallel programming */ + size = 1024; + min_write_delay = 9000; + max_write_delay = 9000; + readback_p1 = 0xff; + readback_p2 = 0xff; + read = " 1 0 1 0 0 0 0 0", + " x x x x x x a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + write = " 1 1 0 0 0 0 0 0", + " x x x x x x a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " i i i i i i i i"; + + loadpage_lo = " 1 1 0 0 0 0 0 1", + " 0 0 0 0 0 0 0 0", + " 0 0 0 0 0 0 a1 a0", + " i i i i i i i i"; + + writepage = " 1 1 0 0 0 0 1 0", + " 0 0 x x x x a9 a8", + " a7 a6 a5 a4 a3 a2 0 0", + " x x x x x x x x"; + + mode = 0x41; + delay = 20; + blocksize = 8; + readsize = 256; + ; + + memory "flash" + paged = yes; + size = 32768; + page_size = 128; + num_pages = 256; + min_write_delay = 4500; + max_write_delay = 4500; + readback_p1 = 0xff; + readback_p2 = 0xff; + read_lo = " 0 0 1 0 0 0 0 0", + " x a14 a13 a12 a11 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + read_hi = " 0 0 1 0 1 0 0 0", + " x a14 a13 a12 a11 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + loadpage_lo = " 0 1 0 0 0 0 0 0", + " x x x x x x x x", + " x x a5 a4 a3 a2 a1 a0", + " i i i i i i i i"; + + loadpage_hi = " 0 1 0 0 1 0 0 0", + " x x x x x x x x", + " x x a5 a4 a3 a2 a1 a0", + " i i i i i i i i"; + + writepage = " 0 1 0 0 1 1 0 0", + " x x x a12 a11 a10 a9 a8", + " a7 a6 x x x x x x", + " x x x x x x x x"; + + mode = 0x41; + delay = 6; + blocksize = 256; + readsize = 256; + ; + + memory "lfuse" + size = 1; + min_write_delay = 4500; + max_write_delay = 4500; + read = "0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0", + "x x x x x x x x o o o o o o o o"; + + write = "1 0 1 0 1 1 0 0 1 0 1 0 0 0 0 0", + "x x x x x x x x i i i i i i i i"; + ; + + memory "hfuse" + size = 1; + min_write_delay = 4500; + max_write_delay = 4500; + read = "0 1 0 1 1 0 0 0 0 0 0 0 1 0 0 0", + "x x x x x x x x o o o o o o o o"; + + write = "1 0 1 0 1 1 0 0 1 0 1 0 1 0 0 0", + "x x x x x x x x i i i i i i i i"; + ; + + memory "efuse" + size = 1; + min_write_delay = 4500; + max_write_delay = 4500; + read = "0 1 0 1 0 0 0 0 0 0 0 0 1 0 0 0", + "x x x x x x x x o o o o o o o o"; + + write = "1 0 1 0 1 1 0 0 1 0 1 0 0 1 0 0", + "x x x x x x x x x x x x x i i i"; + ; + + memory "lock" + size = 1; + min_write_delay = 4500; + max_write_delay = 4500; + read = "0 1 0 1 1 0 0 0 0 0 0 0 0 0 0 0", + "x x x x x x x x x x o o o o o o"; + + write = "1 0 1 0 1 1 0 0 1 1 1 x x x x x", + "x x x x x x x x 1 1 i i i i i i"; + ; + + memory "signature" + size = 3; + read = "0 0 1 1 0 0 0 0 0 0 0 x x x x x", + "x x x x x x a1 a0 o o o o o o o o"; + ; + + memory "calibration" + size = 1; + read = "0 0 1 1 1 0 0 0 0 0 0 x x x x x", + "0 0 0 0 0 0 0 0 o o o o o o o o"; + ; + ; + +#------------------------------------------------------------ +# ATmega329P +#------------------------------------------------------------ +# Identical to ATmega329 except of the signature + +part parent "m329" + id = "m329p"; + desc = "ATmega329P"; + signature = 0x1e 0x95 0x0b; + + ocdrev = 3; + ; + +#------------------------------------------------------------ +# ATmega3290 +#------------------------------------------------------------ + +# identical to ATmega329 + +part parent "m329" + id = "m3290"; + desc = "ATmega3290"; + signature = 0x1e 0x95 0x04; + + ocdrev = 3; + ; + +#------------------------------------------------------------ +# ATmega3290P +#------------------------------------------------------------ + +# identical to ATmega3290 except of the signature + +part parent "m3290" + id = "m3290p"; + desc = "ATmega3290P"; + signature = 0x1e 0x95 0x0c; + + ocdrev = 3; + ; + +#------------------------------------------------------------ +# ATmega649 +#------------------------------------------------------------ + +part + id = "m649"; + desc = "ATmega649"; + has_jtag = yes; +# stk500_devcode = 0x85; # no STK500 support, only STK500v2 +# avr910_devcode = 0x?; # try the ATmega169 one: + avr910_devcode = 0x75; + signature = 0x1e 0x96 0x03; + chip_erase_delay = 9000; + pgm_enable = "1 0 1 0 1 1 0 0 0 1 0 1 0 0 1 1", + "x x x x x x x x x x x x x x x x"; + + chip_erase = "1 0 1 0 1 1 0 0 1 0 0 0 0 0 0 0", + "x x x x x x x x x x x x x x x x"; + timeout = 200; + stabdelay = 100; + cmdexedelay = 25; + synchloops = 32; + bytedelay = 0; + pollindex = 3; + pollvalue = 0x53; + predelay = 1; + postdelay = 1; + pollmethod = 1; + + pp_controlstack = + 0x0E, 0x1E, 0x0F, 0x1F, 0x2E, 0x3E, 0x2F, 0x3F, + 0x4E, 0x5E, 0x4F, 0x5F, 0x6E, 0x7E, 0x6F, 0x7F, + 0x66, 0x76, 0x67, 0x77, 0x6A, 0x7A, 0x6B, 0x7B, + 0xBE, 0xFD, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00; + hventerstabdelay = 100; + progmodedelay = 0; + latchcycles = 5; + togglevtg = 1; + poweroffdelay = 15; + resetdelayms = 1; + resetdelayus = 0; + hvleavestabdelay = 15; + chiperasepulsewidth = 0; + chiperasepolltimeout = 10; + programfusepulsewidth = 0; + programfusepolltimeout = 5; + programlockpulsewidth = 0; + programlockpolltimeout = 5; + + idr = 0x31; + spmcr = 0x57; + + ocdrev = 3; + + memory "eeprom" + paged = no; /* leave this "no" */ + page_size = 8; /* for parallel programming */ + size = 2048; + min_write_delay = 9000; + max_write_delay = 9000; + readback_p1 = 0xff; + readback_p2 = 0xff; + read = " 1 0 1 0 0 0 0 0", + " x x x x x a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + write = " 1 1 0 0 0 0 0 0", + " x x x x x a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " i i i i i i i i"; + + loadpage_lo = " 1 1 0 0 0 0 0 1", + " 0 0 0 0 0 0 0 0", + " 0 0 0 0 0 a2 a1 a0", + " i i i i i i i i"; + + writepage = " 1 1 0 0 0 0 1 0", + " 0 0 x x x a10 a9 a8", + " a7 a6 a5 a4 a3 0 0 0", + " x x x x x x x x"; + + mode = 0x41; + delay = 20; + blocksize = 8; + readsize = 256; + ; + + memory "flash" + paged = yes; + size = 65536; + page_size = 256; + num_pages = 256; + min_write_delay = 4500; + max_write_delay = 4500; + readback_p1 = 0xff; + readback_p2 = 0xff; + read_lo = " 0 0 1 0 0 0 0 0", + "a15 a14 a13 a12 a11 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + read_hi = " 0 0 1 0 1 0 0 0", + "a15 a14 a13 a12 a11 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + loadpage_lo = " 0 1 0 0 0 0 0 0", + " x x x x x x x x", + " x a6 a5 a4 a3 a2 a1 a0", + " i i i i i i i i"; + + loadpage_hi = " 0 1 0 0 1 0 0 0", + " x x x x x x x x", + " x a6 a5 a4 a3 a2 a1 a0", + " i i i i i i i i"; + + writepage = " 0 1 0 0 1 1 0 0", + " x x x a12 a11 a10 a9 a8", + " a7 x x x x x x x", + " x x x x x x x x"; + + mode = 0x41; + delay = 6; + blocksize = 256; + readsize = 256; + ; + + memory "lfuse" + size = 1; + min_write_delay = 4500; + max_write_delay = 4500; + read = "0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0", + "x x x x x x x x o o o o o o o o"; + + write = "1 0 1 0 1 1 0 0 1 0 1 0 0 0 0 0", + "x x x x x x x x i i i i i i i i"; + ; + + memory "hfuse" + size = 1; + min_write_delay = 4500; + max_write_delay = 4500; + read = "0 1 0 1 1 0 0 0 0 0 0 0 1 0 0 0", + "x x x x x x x x o o o o o o o o"; + + write = "1 0 1 0 1 1 0 0 1 0 1 0 1 0 0 0", + "x x x x x x x x i i i i i i i i"; + ; + + memory "efuse" + size = 1; + min_write_delay = 4500; + max_write_delay = 4500; + read = "0 1 0 1 0 0 0 0 0 0 0 0 1 0 0 0", + "x x x x x x x x o o o o o o o o"; + + write = "1 0 1 0 1 1 0 0 1 0 1 0 0 1 0 0", + "x x x x x x x x x x x x x i i i"; + ; + + memory "lock" + size = 1; + min_write_delay = 4500; + max_write_delay = 4500; + read = "0 1 0 1 1 0 0 0 0 0 0 0 0 0 0 0", + "x x x x x x x x x x o o o o o o"; + + write = "1 0 1 0 1 1 0 0 1 1 1 x x x x x", + "x x x x x x x x 1 1 i i i i i i"; + ; + + memory "signature" + size = 3; + read = "0 0 1 1 0 0 0 0 0 0 0 x x x x x", + "x x x x x x a1 a0 o o o o o o o o"; + ; + + memory "calibration" + size = 1; + read = "0 0 1 1 1 0 0 0 0 0 0 x x x x x", + "0 0 0 0 0 0 0 0 o o o o o o o o"; + ; + ; + +#------------------------------------------------------------ +# ATmega6490 +#------------------------------------------------------------ + +# identical to ATmega649 + +part parent "m649" + id = "m6490"; + desc = "ATmega6490"; + signature = 0x1e 0x96 0x04; + + ocdrev = 3; + ; + +#------------------------------------------------------------ +# ATmega32 +#------------------------------------------------------------ + +part + id = "m32"; + desc = "ATmega32"; + has_jtag = yes; + stk500_devcode = 0x91; + avr910_devcode = 0x72; + signature = 0x1e 0x95 0x02; + chip_erase_delay = 9000; + pagel = 0xd7; + bs2 = 0xa0; + reset = dedicated; + pgm_enable = "1 0 1 0 1 1 0 0 0 1 0 1 0 0 1 1", + "x x x x x x x x x x x x x x x x"; + + chip_erase = "1 0 1 0 1 1 0 0 1 0 0 0 0 0 0 0", + "x x x x x x x x x x x x x x x x"; + timeout = 200; + stabdelay = 100; + cmdexedelay = 25; + synchloops = 32; + bytedelay = 0; + pollindex = 3; + pollvalue = 0x53; + predelay = 1; + postdelay = 1; + pollmethod = 0; + + pp_controlstack = + 0x0E, 0x1E, 0x0F, 0x1F, 0x2E, 0x3E, 0x2F, 0x3F, + 0x4E, 0x5E, 0x4F, 0x5F, 0x6E, 0x7E, 0x6F, 0x7F, + 0x66, 0x76, 0x67, 0x77, 0x6A, 0x7A, 0x6B, 0x7B, + 0xBE, 0xFD, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00; + hventerstabdelay = 100; + progmodedelay = 0; + latchcycles = 6; + togglevtg = 0; + poweroffdelay = 0; + resetdelayms = 0; + resetdelayus = 0; + hvleavestabdelay = 15; + chiperasepulsewidth = 0; + chiperasepolltimeout = 10; + programfusepulsewidth = 0; + programfusepolltimeout = 5; + programlockpulsewidth = 0; + programlockpolltimeout = 5; + + idr = 0x31; + spmcr = 0x57; + allowfullpagebitstream = yes; + + ocdrev = 2; + + memory "eeprom" + paged = no; /* leave this "no" */ + page_size = 4; /* for parallel programming */ + size = 1024; + min_write_delay = 9000; + max_write_delay = 9000; + readback_p1 = 0xff; + readback_p2 = 0xff; + read = " 1 0 1 0 0 0 0 0", + " 0 0 x x x x a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + write = " 1 1 0 0 0 0 0 0", + " 0 0 x x x x a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " i i i i i i i i"; + + loadpage_lo = " 1 1 0 0 0 0 0 1", + " 0 0 0 0 0 0 0 0", + " 0 0 0 0 0 0 a1 a0", + " i i i i i i i i"; + + writepage = " 1 1 0 0 0 0 1 0", + " 0 0 x x x x a9 a8", + " a7 a6 a5 a4 a3 a2 0 0", + " x x x x x x x x"; + + mode = 0x04; + delay = 10; + blocksize = 64; + readsize = 256; + ; + + memory "flash" + paged = yes; + size = 32768; + page_size = 128; + num_pages = 256; + min_write_delay = 4500; + max_write_delay = 4500; + readback_p1 = 0xff; + readback_p2 = 0xff; + read_lo = " 0 0 1 0 0 0 0 0", + " 0 0 a13 a12 a11 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + read_hi = " 0 0 1 0 1 0 0 0", + " 0 0 a13 a12 a11 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + loadpage_lo = " 0 1 0 0 0 0 0 0", + " 0 0 x x x x x x", + " x x a5 a4 a3 a2 a1 a0", + " i i i i i i i i"; + + loadpage_hi = " 0 1 0 0 1 0 0 0", + " 0 0 x x x x x x", + " x x a5 a4 a3 a2 a1 a0", + " i i i i i i i i"; + + writepage = " 0 1 0 0 1 1 0 0", + " 0 0 a13 a12 a11 a10 a9 a8", + " a7 a6 x x x x x x", + " x x x x x x x x"; + + mode = 0x21; + delay = 6; + blocksize = 64; + readsize = 256; + ; + + memory "lfuse" + size = 1; + min_write_delay = 2000; + max_write_delay = 2000; + read = "0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0", + "x x x x x x x x o o o o o o o o"; + + write = "1 0 1 0 1 1 0 0 1 0 1 0 0 0 0 0", + "x x x x x x x x i i i i i i i i"; + ; + + memory "hfuse" + size = 1; + min_write_delay = 2000; + max_write_delay = 2000; + read = "0 1 0 1 1 0 0 0 0 0 0 0 1 0 0 0", + "x x x x x x x x o o o o o o o o"; + + write = "1 0 1 0 1 1 0 0 1 0 1 0 1 0 0 0", + "x x x x x x x x i i i i i i i i"; + ; + + memory "lock" + size = 1; + min_write_delay = 2000; + max_write_delay = 2000; + read = "0 1 0 1 1 0 0 0 0 0 0 0 0 0 0 0", + "x x x x x x x x x x o o o o o o"; + + write = "1 0 1 0 1 1 0 0 1 1 1 x x x x x", + "x x x x x x x x 1 1 i i i i i i"; + ; + + memory "signature" + size = 3; + read = "0 0 1 1 0 0 0 0 x x x x x x x x", + "x x x x x x a1 a0 o o o o o o o o"; + ; + + memory "calibration" + size = 4; + read = "0 0 1 1 1 0 0 0 0 0 x x x x x x", + "0 0 0 0 0 0 a1 a0 o o o o o o o o"; + ; + ; + +#------------------------------------------------------------ +# ATmega161 +#------------------------------------------------------------ + +part + id = "m161"; + desc = "ATmega161"; + stk500_devcode = 0x80; + avr910_devcode = 0x60; + signature = 0x1e 0x94 0x01; + chip_erase_delay = 28000; + pagel = 0xd7; + bs2 = 0xa0; + pgm_enable = "1 0 1 0 1 1 0 0 0 1 0 1 0 0 1 1", + "x x x x x x x x x x x x x x x x"; + + chip_erase = "1 0 1 0 1 1 0 0 1 0 0 0 0 0 0 0", + "x x x x x x x x x x x x x x x x"; + timeout = 200; + stabdelay = 100; + cmdexedelay = 25; + synchloops = 32; + bytedelay = 0; + pollindex = 3; + pollvalue = 0x53; + predelay = 1; + postdelay = 1; + pollmethod = 0; + + pp_controlstack = + 0x0E, 0x1E, 0x0F, 0x1F, 0x2E, 0x3E, 0x2F, 0x3F, + 0x4E, 0x5E, 0x4F, 0x5F, 0x6E, 0x7E, 0x6F, 0x7F, + 0x66, 0x76, 0x67, 0x77, 0x6A, 0x7A, 0x6B, 0x7B, + 0xBE, 0xFD, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00; + hventerstabdelay = 100; + progmodedelay = 0; + latchcycles = 0; + togglevtg = 0; + poweroffdelay = 0; + resetdelayms = 0; + resetdelayus = 0; + hvleavestabdelay = 15; + chiperasepulsewidth = 0; + chiperasepolltimeout = 30; + programfusepulsewidth = 0; + programfusepolltimeout = 2; + programlockpulsewidth = 0; + programlockpolltimeout = 2; + + memory "eeprom" + size = 512; + min_write_delay = 3400; + max_write_delay = 3400; + readback_p1 = 0xff; + readback_p2 = 0xff; + read = " 1 0 1 0 0 0 0 0", + " x x x x x x x a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + write = " 1 1 0 0 0 0 0 0", + " x x x x x x x a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " i i i i i i i i"; + + mode = 0x04; + delay = 5; + blocksize = 128; + readsize = 256; + ; + + memory "flash" + paged = yes; + size = 16384; + page_size = 128; + num_pages = 128; + min_write_delay = 14000; + max_write_delay = 14000; + readback_p1 = 0xff; + readback_p2 = 0xff; + read_lo = " 0 0 1 0 0 0 0 0", + " x x x a12 a11 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + read_hi = " 0 0 1 0 1 0 0 0", + " x x x a12 a11 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + loadpage_lo = " 0 1 0 0 0 0 0 0", + " x x x x x x x x", + " x x a5 a4 a3 a2 a1 a0", + " i i i i i i i i"; + + loadpage_hi = " 0 1 0 0 1 0 0 0", + " x x x x x x x x", + " x x a5 a4 a3 a2 a1 a0", + " i i i i i i i i"; + + writepage = " 0 1 0 0 1 1 0 0", + " x x x a12 a11 a10 a9 a8", + " a7 a6 x x x x x x", + " x x x x x x x x"; + + mode = 0x21; + delay = 16; + blocksize = 128; + readsize = 256; + ; + + memory "fuse" + size = 1; + min_write_delay = 2000; + max_write_delay = 2000; + read = "0 1 0 1 0 0 0 0 x x x x x x x x", + "x x x x x x x x x o x o o o o o"; + + write = "1 0 1 0 1 1 0 0 1 0 1 x x x x x", + "x x x x x x x x 1 i 1 i i i i i"; + ; + + memory "lock" + size = 1; + min_write_delay = 2000; + max_write_delay = 2000; + read = "0 1 0 1 1 0 0 0 0 0 0 0 0 0 0 0", + "x x x x x x x x x x o o o o o o"; + + write = "1 0 1 0 1 1 0 0 1 1 1 x x x x x", + "x x x x x x x x 1 1 i i i i i i"; + ; + memory "signature" + size = 3; + read = "0 0 1 1 0 0 0 0 x x x x x x x x", + "x x x x x x a1 a0 o o o o o o o o"; + ; + ; + + +#------------------------------------------------------------ +# ATmega8 +#------------------------------------------------------------ + +part + id = "m8"; + desc = "ATmega8"; + stk500_devcode = 0x70; + avr910_devcode = 0x76; + signature = 0x1e 0x93 0x07; + pagel = 0xd7; + bs2 = 0xc2; + chip_erase_delay = 10000; + pgm_enable = "1 0 1 0 1 1 0 0 0 1 0 1 0 0 1 1", + "x x x x x x x x x x x x x x x x"; + + chip_erase = "1 0 1 0 1 1 0 0 1 0 0 x x x x x", + "x x x x x x x x x x x x x x x x"; + + timeout = 200; + stabdelay = 100; + cmdexedelay = 25; + synchloops = 32; + bytedelay = 0; + pollindex = 3; + pollvalue = 0x53; + predelay = 1; + postdelay = 1; + pollmethod = 0; + + pp_controlstack = + 0x0E, 0x1E, 0x0F, 0x1F, 0x2E, 0x3E, 0x2F, 0x3F, + 0x4E, 0x5E, 0x4F, 0x5F, 0x6E, 0x7E, 0x6F, 0x7F, + 0x66, 0x76, 0x67, 0x77, 0x6A, 0x7A, 0x6B, 0x7B, + 0xBE, 0xFD, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00; + hventerstabdelay = 100; + progmodedelay = 0; + latchcycles = 5; + togglevtg = 1; + poweroffdelay = 15; + resetdelayms = 2; + resetdelayus = 0; + hvleavestabdelay = 15; + resetdelay = 15; + chiperasepulsewidth = 0; + chiperasepolltimeout = 10; + programfusepulsewidth = 0; + programfusepolltimeout = 5; + programlockpulsewidth = 0; + programlockpolltimeout = 5; + + memory "eeprom" + size = 512; + page_size = 4; + min_write_delay = 9000; + max_write_delay = 9000; + readback_p1 = 0xff; + readback_p2 = 0xff; + read = " 1 0 1 0 0 0 0 0", + " 0 0 x x x x x a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + write = " 1 1 0 0 0 0 0 0", + " 0 0 x x x x x a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " i i i i i i i i"; + + mode = 0x04; + delay = 20; + blocksize = 128; + readsize = 256; + ; + memory "flash" + paged = yes; + size = 8192; + page_size = 64; + num_pages = 128; + min_write_delay = 4500; + max_write_delay = 4500; + readback_p1 = 0xff; + readback_p2 = 0x00; + read_lo = " 0 0 1 0 0 0 0 0", + " 0 0 0 0 a11 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + read_hi = " 0 0 1 0 1 0 0 0", + " 0 0 0 0 a11 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + loadpage_lo = " 0 1 0 0 0 0 0 0", + " 0 0 0 0 x x x x", + " x x x a4 a3 a2 a1 a0", + " i i i i i i i i"; + + loadpage_hi = " 0 1 0 0 1 0 0 0", + " 0 0 0 0 x x x x", + " x x x a4 a3 a2 a1 a0", + " i i i i i i i i"; + + writepage = " 0 1 0 0 1 1 0 0", + " 0 0 0 0 a11 a10 a9 a8", + " a7 a6 a5 x x x x x", + " x x x x x x x x"; + + mode = 0x21; + delay = 10; + blocksize = 64; + readsize = 256; + ; + + memory "lfuse" + size = 1; + min_write_delay = 2000; + max_write_delay = 2000; + read = "0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0", + "x x x x x x x x o o o o o o o o"; + + write = "1 0 1 0 1 1 0 0 1 0 1 0 0 0 0 0", + "x x x x x x x x i i i i i i i i"; + ; + + memory "hfuse" + size = 1; + min_write_delay = 2000; + max_write_delay = 2000; + read = "0 1 0 1 1 0 0 0 0 0 0 0 1 0 0 0", + "x x x x x x x x o o o o o o o o"; + + write = "1 0 1 0 1 1 0 0 1 0 1 0 1 0 0 0", + "x x x x x x x x i i i i i i i i"; + ; + + memory "lock" + size = 1; + min_write_delay = 2000; + max_write_delay = 2000; + read = "0 1 0 1 1 0 0 0 0 0 0 0 0 0 0 0", + "x x x x x x x x x x o o o o o o"; + + write = "1 0 1 0 1 1 0 0 1 1 1 x x x x x", + "x x x x x x x x 1 1 i i i i i i"; + ; + + memory "calibration" + size = 4; + read = "0 0 1 1 1 0 0 0 0 0 x x x x x x", + "0 0 0 0 0 0 a1 a0 o o o o o o o o"; + ; + + memory "signature" + size = 3; + read = "0 0 1 1 0 0 0 0 x x x x x x x x", + "x x x x x x a1 a0 o o o o o o o o"; + ; + ; + + + +#------------------------------------------------------------ +# ATmega8515 +#------------------------------------------------------------ + +part + id = "m8515"; + desc = "ATmega8515"; + stk500_devcode = 0x63; + avr910_devcode = 0x3A; + signature = 0x1e 0x93 0x06; + chip_erase_delay = 9000; + pgm_enable = "1 0 1 0 1 1 0 0 0 1 0 1 0 0 1 1", + "x x x x x x x x x x x x x x x x"; + + chip_erase = "1 0 1 0 1 1 0 0 1 0 0 x x x x x", + "x x x x x x x x x x x x x x x x"; + + timeout = 200; + stabdelay = 100; + cmdexedelay = 25; + synchloops = 32; + bytedelay = 0; + pollindex = 3; + pollvalue = 0x53; + predelay = 1; + postdelay = 1; + pollmethod = 0; + + pp_controlstack = + 0x0E, 0x1E, 0x0F, 0x1F, 0x2E, 0x3E, 0x2F, 0x3F, + 0x4E, 0x5E, 0x4F, 0x5F, 0x6E, 0x7E, 0x6F, 0x7F, + 0x66, 0x76, 0x67, 0x77, 0x6A, 0x7A, 0x6B, 0x7B, + 0xBE, 0xFD, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00; + hventerstabdelay = 100; + progmodedelay = 0; + latchcycles = 6; + togglevtg = 0; + poweroffdelay = 0; + resetdelayms = 0; + resetdelayus = 0; + hvleavestabdelay = 15; + chiperasepulsewidth = 0; + chiperasepolltimeout = 10; + programfusepulsewidth = 0; + programfusepolltimeout = 5; + programlockpulsewidth = 0; + programlockpolltimeout = 5; + + memory "eeprom" + size = 512; + min_write_delay = 9000; + max_write_delay = 9000; + readback_p1 = 0xff; + readback_p2 = 0xff; + read = " 1 0 1 0 0 0 0 0", + " 0 0 x x x x x a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + write = " 1 1 0 0 0 0 0 0", + " 0 0 x x x x x a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " i i i i i i i i"; + + mode = 0x04; + delay = 20; + blocksize = 128; + readsize = 256; + ; + memory "flash" + paged = yes; + size = 8192; + page_size = 64; + num_pages = 128; + min_write_delay = 4500; + max_write_delay = 4500; + readback_p1 = 0xff; + readback_p2 = 0xff; + read_lo = " 0 0 1 0 0 0 0 0", + " 0 0 0 0 a11 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + read_hi = " 0 0 1 0 1 0 0 0", + " 0 0 0 0 a11 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + loadpage_lo = " 0 1 0 0 0 0 0 0", + " 0 0 0 0 x x x x", + " x x x a4 a3 a2 a1 a0", + " i i i i i i i i"; + + loadpage_hi = " 0 1 0 0 1 0 0 0", + " 0 0 0 0 x x x x", + " x x x a4 a3 a2 a1 a0", + " i i i i i i i i"; + + writepage = " 0 1 0 0 1 1 0 0", + " 0 0 0 0 a11 a10 a9 a8", + " a7 a6 a5 x x x x x", + " x x x x x x x x"; + + mode = 0x21; + delay = 6; + blocksize = 64; + readsize = 256; + ; + + memory "lfuse" + size = 1; + min_write_delay = 4500; + max_write_delay = 4500; + read = "0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0", + "x x x x x x x x o o o o o o o o"; + + write = "1 0 1 0 1 1 0 0 1 0 1 0 0 0 0 0", + "x x x x x x x x i i i i i i i i"; + ; + + memory "hfuse" + size = 1; + min_write_delay = 4500; + max_write_delay = 4500; + read = "0 1 0 1 1 0 0 0 0 0 0 0 1 0 0 0", + "x x x x x x x x o o o o o o o o"; + + write = "1 0 1 0 1 1 0 0 1 0 1 0 1 0 0 0", + "x x x x x x x x i i i i i i i i"; + ; + + memory "lock" + size = 1; + min_write_delay = 4500; + max_write_delay = 4500; + read = "0 1 0 1 1 0 0 0 0 0 0 0 0 0 0 0", + "x x x x x x x x x x o o o o o o"; + + write = "1 0 1 0 1 1 0 0 1 1 1 x x x x x", + "x x x x x x x x 1 1 i i i i i i"; + ; + + memory "calibration" + size = 4; + read = "0 0 1 1 1 0 0 0 0 0 x x x x x x", + "0 0 0 0 0 0 a1 a0 o o o o o o o o"; + ; + + memory "signature" + size = 3; + read = "0 0 1 1 0 0 0 0 x x x x x x x x", + "x x x x x x a1 a0 o o o o o o o o"; + ; + ; + + + + +#------------------------------------------------------------ +# ATmega8535 +#------------------------------------------------------------ + +part + id = "m8535"; + desc = "ATmega8535"; + stk500_devcode = 0x64; + avr910_devcode = 0x69; + signature = 0x1e 0x93 0x08; + pagel = 0xd7; + bs2 = 0xa0; + chip_erase_delay = 9000; + pgm_enable = "1 0 1 0 1 1 0 0 0 1 0 1 0 0 1 1", + "x x x x x x x x x x x x x x x x"; + + chip_erase = "1 0 1 0 1 1 0 0 1 0 0 x x x x x", + "x x x x x x x x x x x x x x x x"; + + timeout = 200; + stabdelay = 100; + cmdexedelay = 25; + synchloops = 32; + bytedelay = 0; + pollindex = 3; + pollvalue = 0x53; + predelay = 1; + postdelay = 1; + pollmethod = 0; + + pp_controlstack = + 0x0E, 0x1E, 0x0F, 0x1F, 0x2E, 0x3E, 0x2F, 0x3F, + 0x4E, 0x5E, 0x4F, 0x5F, 0x6E, 0x7E, 0x6F, 0x7F, + 0x66, 0x76, 0x67, 0x77, 0x6A, 0x7A, 0x6B, 0x7B, + 0xBE, 0xFD, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00; + hventerstabdelay = 100; + progmodedelay = 0; + latchcycles = 6; + togglevtg = 0; + poweroffdelay = 0; + resetdelayms = 0; + resetdelayus = 0; + hvleavestabdelay = 15; + chiperasepulsewidth = 0; + chiperasepolltimeout = 10; + programfusepulsewidth = 0; + programfusepolltimeout = 5; + programlockpulsewidth = 0; + programlockpolltimeout = 5; + + memory "eeprom" + size = 512; + min_write_delay = 9000; + max_write_delay = 9000; + readback_p1 = 0xff; + readback_p2 = 0xff; + read = " 1 0 1 0 0 0 0 0", + " 0 0 x x x x x a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + write = " 1 1 0 0 0 0 0 0", + " 0 0 x x x x x a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " i i i i i i i i"; + + mode = 0x04; + delay = 20; + blocksize = 128; + readsize = 256; + ; + memory "flash" + paged = yes; + size = 8192; + page_size = 64; + num_pages = 128; + min_write_delay = 4500; + max_write_delay = 4500; + readback_p1 = 0xff; + readback_p2 = 0xff; + read_lo = " 0 0 1 0 0 0 0 0", + " 0 0 0 0 a11 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + read_hi = " 0 0 1 0 1 0 0 0", + " 0 0 0 0 a11 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + loadpage_lo = " 0 1 0 0 0 0 0 0", + " 0 0 0 0 x x x x", + " x x x a4 a3 a2 a1 a0", + " i i i i i i i i"; + + loadpage_hi = " 0 1 0 0 1 0 0 0", + " 0 0 0 0 x x x x", + " x x x a4 a3 a2 a1 a0", + " i i i i i i i i"; + + writepage = " 0 1 0 0 1 1 0 0", + " 0 0 0 0 a11 a10 a9 a8", + " a7 a6 a5 x x x x x", + " x x x x x x x x"; + + mode = 0x21; + delay = 6; + blocksize = 64; + readsize = 256; + ; + + memory "lfuse" + size = 1; + min_write_delay = 2000; + max_write_delay = 2000; + read = "0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0", + "x x x x x x x x o o o o o o o o"; + + write = "1 0 1 0 1 1 0 0 1 0 1 0 0 0 0 0", + "x x x x x x x x i i i i i i i i"; + ; + + memory "hfuse" + size = 1; + min_write_delay = 2000; + max_write_delay = 2000; + read = "0 1 0 1 1 0 0 0 0 0 0 0 1 0 0 0", + "x x x x x x x x o o o o o o o o"; + + write = "1 0 1 0 1 1 0 0 1 0 1 0 1 0 0 0", + "x x x x x x x x i i i i i i i i"; + ; + + memory "lock" + size = 1; + min_write_delay = 2000; + max_write_delay = 2000; + read = "0 1 0 1 1 0 0 0 0 0 0 0 0 0 0 0", + "x x x x x x x x x x o o o o o o"; + + write = "1 0 1 0 1 1 0 0 1 1 1 x x x x x", + "x x x x x x x x 1 1 i i i i i i"; + ; + + memory "calibration" + size = 4; + read = "0 0 1 1 1 0 0 0 0 0 x x x x x x", + "0 0 0 0 0 0 a1 a0 o o o o o o o o"; + ; + + memory "signature" + size = 3; + read = "0 0 1 1 0 0 0 0 x x x x x x x x", + "x x x x x x a1 a0 o o o o o o o o"; + ; + ; + + +#------------------------------------------------------------ +# ATtiny26 +#------------------------------------------------------------ + +part + id = "t26"; + desc = "ATtiny26"; + stk500_devcode = 0x21; + avr910_devcode = 0x5e; + signature = 0x1e 0x91 0x09; + pagel = 0xb3; + bs2 = 0xb2; + chip_erase_delay = 9000; + pgm_enable = "1 0 1 0 1 1 0 0 0 1 0 1 0 0 1 1", + "x x x x x x x x x x x x x x x x"; + + chip_erase = "1 0 1 0 1 1 0 0 1 0 0 x x x x x", + "x x x x x x x x x x x x x x x x"; + + timeout = 200; + stabdelay = 100; + cmdexedelay = 25; + synchloops = 32; + bytedelay = 0; + pollindex = 3; + pollvalue = 0x53; + predelay = 1; + postdelay = 1; + pollmethod = 0; + + pp_controlstack = + 0xC4, 0xE4, 0xC4, 0xE4, 0xCC, 0xEC, 0xCC, 0xEC, + 0xD4, 0xF4, 0xD4, 0xF4, 0xDC, 0xFC, 0xDC, 0xFC, + 0xC8, 0xE8, 0xD8, 0xF8, 0x4C, 0x6C, 0x5C, 0x7C, + 0xEC, 0xBC, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00; + hventerstabdelay = 100; + progmodedelay = 0; + latchcycles = 5; + togglevtg = 1; + poweroffdelay = 15; + resetdelayms = 2; + resetdelayus = 0; + hvleavestabdelay = 15; + chiperasepulsewidth = 0; + chiperasepolltimeout = 10; + programfusepulsewidth = 0; + programfusepolltimeout = 5; + programlockpulsewidth = 0; + programlockpolltimeout = 5; + + memory "eeprom" + size = 128; + min_write_delay = 9000; + max_write_delay = 9000; + readback_p1 = 0xff; + readback_p2 = 0xff; + read = "1 0 1 0 0 0 0 0 x x x x x x x x", + "x a6 a5 a4 a3 a2 a1 a0 o o o o o o o o"; + + write = "1 1 0 0 0 0 0 0 x x x x x x x x", + "x a6 a5 a4 a3 a2 a1 a0 i i i i i i i i"; + + mode = 0x04; + delay = 10; + blocksize = 64; + readsize = 256; + ; + + memory "flash" + paged = yes; + size = 2048; + page_size = 32; + num_pages = 64; + min_write_delay = 4500; + max_write_delay = 4500; + readback_p1 = 0xff; + readback_p2 = 0xff; + read_lo = " 0 0 1 0 0 0 0 0", + " x x x x x x a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + read_hi = " 0 0 1 0 1 0 0 0", + " x x x x x x a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + loadpage_lo = " 0 1 0 0 0 0 0 0", + " x x x x x x x x", + " x x x x a3 a2 a1 a0", + " i i i i i i i i"; + + loadpage_hi = " 0 1 0 0 1 0 0 0", + " x x x x x x x x", + " x x x x a3 a2 a1 a0", + " i i i i i i i i"; + + writepage = " 0 1 0 0 1 1 0 0", + " x x x x x x a9 a8", + " a7 a6 a5 a4 x x x x", + " x x x x x x x x"; + + mode = 0x21; + delay = 6; + blocksize = 16; + readsize = 256; + ; + + memory "signature" + size = 3; + read = "0 0 1 1 0 0 0 0 x x x x x x x x", + "0 0 0 0 0 0 a1 a0 o o o o o o o o"; + ; + + memory "lock" + size = 1; + read = "0 1 0 1 1 0 0 0 x x x x x x x x", + "x x x x x x x x x x x x x x o o"; + + write = "1 0 1 0 1 1 0 0 1 1 1 1 1 1 i i", + "x x x x x x x x x x x x x x x x"; + min_write_delay = 9000; + max_write_delay = 9000; + ; + + memory "lfuse" + size = 1; + write = "1 0 1 0 1 1 0 0 1 0 1 0 0 0 0 0", + "x x x x x x x x i i i i i i i i"; + + read = "0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0", + "x x x x x x x x o o o o o o o o"; + min_write_delay = 9000; + max_write_delay = 9000; + ; + + memory "hfuse" + size = 1; + write = "1 0 1 0 1 1 0 0 1 0 1 0 1 0 0 0", + "x x x x x x x x x x x i i i i i"; + + read = "0 1 0 1 1 0 0 0 0 0 0 0 1 0 0 0", + "x x x x x x x x o o o o o o o o"; + min_write_delay = 9000; + max_write_delay = 9000; + ; + + memory "calibration" + size = 4; + read = "0 0 1 1 1 0 0 0 x x x x x x x x", + "0 0 0 0 0 0 a1 a0 o o o o o o o o"; + ; + +; + + +#------------------------------------------------------------ +# ATtiny261 +#------------------------------------------------------------ +# Close to ATtiny26 + +part + id = "t261"; + desc = "ATtiny261"; + has_debugwire = yes; + flash_instr = 0xB4, 0x00, 0x10; + eeprom_instr = 0xBB, 0xFF, 0xBB, 0xEE, 0xBB, 0xCC, 0xB2, 0x0D, + 0xBC, 0x00, 0xB4, 0x00, 0xBA, 0x0D, 0xBB, 0xBC, + 0x99, 0xE1, 0xBB, 0xAC; +# stk500_devcode = 0x21; +# avr910_devcode = 0x5e; + signature = 0x1e 0x91 0x0c; + pagel = 0xb3; + bs2 = 0xb2; + chip_erase_delay = 4000; + + pgm_enable = "1 0 1 0 1 1 0 0 0 1 0 1 0 0 1 1", + "x x x x x x x x x x x x x x x x"; + + chip_erase = "1 0 1 0 1 1 0 0 1 0 0 x x x x x", + "x x x x x x x x x x x x x x x x"; + + timeout = 200; + stabdelay = 100; + cmdexedelay = 25; + synchloops = 32; + bytedelay = 0; + pollindex = 3; + pollvalue = 0x53; + predelay = 1; + postdelay = 1; + pollmethod = 0; + + pp_controlstack = + 0xC4, 0xE4, 0xC4, 0xE4, 0xCC, 0xEC, 0xCC, 0xEC, + 0xD4, 0xF4, 0xD4, 0xF4, 0xDC, 0xFC, 0xDC, 0xFC, + 0xC8, 0xE8, 0xD8, 0xF8, 0x4C, 0x6C, 0x5C, 0x7C, + 0xEC, 0xBC, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00; + hventerstabdelay = 100; + progmodedelay = 0; + latchcycles = 5; + togglevtg = 1; + poweroffdelay = 15; + resetdelayms = 2; + resetdelayus = 0; + hvleavestabdelay = 15; + chiperasepulsewidth = 0; + chiperasepolltimeout = 10; + programfusepulsewidth = 0; + programfusepolltimeout = 5; + programlockpulsewidth = 0; + programlockpolltimeout = 5; + + ocdrev = 1; + + memory "eeprom" + paged = no; + size = 128; + page_size = 4; + num_pages = 32; + min_write_delay = 4000; + max_write_delay = 4000; + readback_p1 = 0xff; + readback_p2 = 0xff; + + read = "1 0 1 0 0 0 0 0 x x x x x x x x", + "x a6 a5 a4 a3 a2 a1 a0 o o o o o o o o"; + + write = "1 1 0 0 0 0 0 0 x x x x x x x x", + "x a6 a5 a4 a3 a2 a1 a0 i i i i i i i i"; + + loadpage_lo = " 1 1 0 0 0 0 0 1", + " 0 0 0 0 0 0 0 0", + " 0 0 0 0 0 0 a1 a0", + " i i i i i i i i"; + + writepage = " 1 1 0 0 0 0 1 0", + " 0 0 x x x x x x", + " x a6 a5 a4 a3 a2 0 0", + " x x x x x x x x"; + + mode = 0x41; + delay = 10; + blocksize = 4; + readsize = 256; + ; + + memory "flash" + paged = yes; + size = 2048; + page_size = 32; + num_pages = 64; + min_write_delay = 4500; + max_write_delay = 4500; + readback_p1 = 0xff; + readback_p2 = 0xff; + + read_lo = " 0 0 1 0 0 0 0 0", + " x x x x x x a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + read_hi = " 0 0 1 0 1 0 0 0", + " x x x x x x a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + loadpage_lo = " 0 1 0 0 0 0 0 0", + " x x x x x x x x", + " x x x x a3 a2 a1 a0", + " i i i i i i i i"; + + loadpage_hi = " 0 1 0 0 1 0 0 0", + " x x x x x x x x", + " x x x x a3 a2 a1 a0", + " i i i i i i i i"; + + writepage = " 0 1 0 0 1 1 0 0", + " x x x x x x a9 a8", + " a7 a6 a5 a4 x x x x", + " x x x x x x x x"; + + mode = 0x41; + delay = 6; + blocksize = 32; + readsize = 256; + ; + + memory "signature" + size = 3; + read = "0 0 1 1 0 0 0 0 x x x x x x x x", + "0 0 0 0 0 0 a1 a0 o o o o o o o o"; + ; + + memory "lock" + size = 1; + read = "0 1 0 1 1 0 0 0 x x x x x x x x", + "x x x x x x x x x x x x x x o o"; + + write = "1 0 1 0 1 1 0 0 1 1 1 1 1 1 i i", + "x x x x x x x x x x x x x x x x"; + min_write_delay = 4500; + max_write_delay = 4500; + ; + + memory "lfuse" + size = 1; + write = "1 0 1 0 1 1 0 0 1 0 1 0 0 0 0 0", + "x x x x x x x x i i i i i i i i"; + + read = "0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0", + "x x x x x x x x o o o o o o o o"; + min_write_delay = 4500; + max_write_delay = 4500; + ; + + memory "hfuse" + size = 1; + write = "1 0 1 0 1 1 0 0 1 0 1 0 1 0 0 0", + "x x x x x x x x i i i i i i i i"; + + read = "0 1 0 1 1 0 0 0 0 0 0 0 1 0 0 0", + "x x x x x x x x o o o o o o o o"; + min_write_delay = 4500; + max_write_delay = 4500; + ; + + memory "efuse" + size = 1; + write = "1 0 1 0 1 1 0 0 1 0 1 0 0 1 0 0", + "x x x x x x x x x x x x x x x i"; + + read = "0 1 0 1 0 0 0 0 0 0 0 0 1 0 0 0", + "x x x x x x x x o o o o o o o o"; + min_write_delay = 4500; + max_write_delay = 4500; + ; + + memory "calibration" + size = 1; + read = "0 0 1 1 1 0 0 0 x x x x x x x x", + "0 0 0 0 0 0 0 0 o o o o o o o o"; + ; + +; + + +#------------------------------------------------------------ +# ATtiny461 +#------------------------------------------------------------ +# Close to ATtiny261 + +part + id = "t461"; + desc = "ATtiny461"; + has_debugwire = yes; + flash_instr = 0xB4, 0x00, 0x10; + eeprom_instr = 0xBB, 0xFF, 0xBB, 0xEE, 0xBB, 0xCC, 0xB2, 0x0D, + 0xBC, 0x00, 0xB4, 0x00, 0xBA, 0x0D, 0xBB, 0xBC, + 0x99, 0xE1, 0xBB, 0xAC; +# stk500_devcode = 0x21; +# avr910_devcode = 0x5e; + signature = 0x1e 0x92 0x08; + pagel = 0xb3; + bs2 = 0xb2; + chip_erase_delay = 4000; + + pgm_enable = "1 0 1 0 1 1 0 0 0 1 0 1 0 0 1 1", + "x x x x x x x x x x x x x x x x"; + + chip_erase = "1 0 1 0 1 1 0 0 1 0 0 x x x x x", + "x x x x x x x x x x x x x x x x"; + + timeout = 200; + stabdelay = 100; + cmdexedelay = 25; + synchloops = 32; + bytedelay = 0; + pollindex = 3; + pollvalue = 0x53; + predelay = 1; + postdelay = 1; + pollmethod = 0; + + pp_controlstack = + 0xC4, 0xE4, 0xC4, 0xE4, 0xCC, 0xEC, 0xCC, 0xEC, + 0xD4, 0xF4, 0xD4, 0xF4, 0xDC, 0xFC, 0xDC, 0xFC, + 0xC8, 0xE8, 0xD8, 0xF8, 0x4C, 0x6C, 0x5C, 0x7C, + 0xEC, 0xBC, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00; + hventerstabdelay = 100; + progmodedelay = 0; + latchcycles = 5; + togglevtg = 1; + poweroffdelay = 15; + resetdelayms = 2; + resetdelayus = 0; + hvleavestabdelay = 15; + chiperasepulsewidth = 0; + chiperasepolltimeout = 10; + programfusepulsewidth = 0; + programfusepolltimeout = 5; + programlockpulsewidth = 0; + programlockpolltimeout = 5; + + ocdrev = 1; + + memory "eeprom" + paged = no; + size = 256; + page_size = 4; + num_pages = 64; + min_write_delay = 4000; + max_write_delay = 4000; + readback_p1 = 0xff; + readback_p2 = 0xff; + + read = " 1 0 1 0 0 0 0 0 x x x x x x x x", + "a7 a6 a5 a4 a3 a2 a1 a0 o o o o o o o o"; + + write = " 1 1 0 0 0 0 0 0 x x x x x x x x", + "a7 a6 a5 a4 a3 a2 a1 a0 i i i i i i i i"; + + loadpage_lo = " 1 1 0 0 0 0 0 1", + " 0 0 0 0 0 0 0 0", + " 0 0 0 0 0 0 a1 a0", + " i i i i i i i i"; + + writepage = " 1 1 0 0 0 0 1 0", + " 0 0 x x x x x x", + " a7 a6 a5 a4 a3 a2 0 0", + " x x x x x x x x"; + + mode = 0x41; + delay = 10; + blocksize = 4; + readsize = 256; + ; + + memory "flash" + paged = yes; + size = 4096; + page_size = 64; + num_pages = 64; + min_write_delay = 4500; + max_write_delay = 4500; + readback_p1 = 0xff; + readback_p2 = 0xff; + + read_lo = " 0 0 1 0 0 0 0 0", + " x x x x x a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + read_hi = " 0 0 1 0 1 0 0 0", + " x x x x x a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + loadpage_lo = " 0 1 0 0 0 0 0 0", + " x x x x x x x x", + " x x x a4 a3 a2 a1 a0", + " i i i i i i i i"; + + loadpage_hi = " 0 1 0 0 1 0 0 0", + " x x x x x x x x", + " x x x a4 a3 a2 a1 a0", + " i i i i i i i i"; + + writepage = " 0 1 0 0 1 1 0 0", + " x x x x x a10 a9 a8", + " a7 a6 a5 x x x x x", + " x x x x x x x x"; + + mode = 0x41; + delay = 6; + blocksize = 64; + readsize = 256; + ; + + memory "signature" + size = 3; + read = "0 0 1 1 0 0 0 0 x x x x x x x x", + "0 0 0 0 0 0 a1 a0 o o o o o o o o"; + ; + + memory "lock" + size = 1; + read = "0 1 0 1 1 0 0 0 x x x x x x x x", + "x x x x x x x x x x x x x x o o"; + + write = "1 0 1 0 1 1 0 0 1 1 1 1 1 1 i i", + "x x x x x x x x x x x x x x x x"; + min_write_delay = 4500; + max_write_delay = 4500; + ; + + memory "lfuse" + size = 1; + write = "1 0 1 0 1 1 0 0 1 0 1 0 0 0 0 0", + "x x x x x x x x i i i i i i i i"; + + read = "0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0", + "x x x x x x x x o o o o o o o o"; + min_write_delay = 4500; + max_write_delay = 4500; + ; + + memory "hfuse" + size = 1; + write = "1 0 1 0 1 1 0 0 1 0 1 0 1 0 0 0", + "x x x x x x x x i i i i i i i i"; + + read = "0 1 0 1 1 0 0 0 0 0 0 0 1 0 0 0", + "x x x x x x x x o o o o o o o o"; + min_write_delay = 4500; + max_write_delay = 4500; + ; + + memory "efuse" + size = 1; + write = "1 0 1 0 1 1 0 0 1 0 1 0 0 1 0 0", + "x x x x x x x x x x x x x x x i"; + + read = "0 1 0 1 0 0 0 0 0 0 0 0 1 0 0 0", + "x x x x x x x x o o o o o o o o"; + min_write_delay = 4500; + max_write_delay = 4500; + ; + + memory "calibration" + size = 1; + read = "0 0 1 1 1 0 0 0 x x x x x x x x", + "0 0 0 0 0 0 0 0 o o o o o o o o"; + ; + +; + + +#------------------------------------------------------------ +# ATtiny861 +#------------------------------------------------------------ +# Close to ATtiny461 + +part + id = "t861"; + desc = "ATtiny861"; + has_debugwire = yes; + flash_instr = 0xB4, 0x00, 0x10; + eeprom_instr = 0xBB, 0xFF, 0xBB, 0xEE, 0xBB, 0xCC, 0xB2, 0x0D, + 0xBC, 0x00, 0xB4, 0x00, 0xBA, 0x0D, 0xBB, 0xBC, + 0x99, 0xE1, 0xBB, 0xAC; +# stk500_devcode = 0x21; +# avr910_devcode = 0x5e; + signature = 0x1e 0x93 0x0d; + pagel = 0xb3; + bs2 = 0xb2; + chip_erase_delay = 4000; + + pgm_enable = "1 0 1 0 1 1 0 0 0 1 0 1 0 0 1 1", + "x x x x x x x x x x x x x x x x"; + + chip_erase = "1 0 1 0 1 1 0 0 1 0 0 x x x x x", + "x x x x x x x x x x x x x x x x"; + + timeout = 200; + stabdelay = 100; + cmdexedelay = 25; + synchloops = 32; + bytedelay = 0; + pollindex = 3; + pollvalue = 0x53; + predelay = 1; + postdelay = 1; + pollmethod = 0; + + pp_controlstack = + 0xC4, 0xE4, 0xC4, 0xE4, 0xCC, 0xEC, 0xCC, 0xEC, + 0xD4, 0xF4, 0xD4, 0xF4, 0xDC, 0xFC, 0xDC, 0xFC, + 0xC8, 0xE8, 0xD8, 0xF8, 0x4C, 0x6C, 0x5C, 0x7C, + 0xEC, 0xBC, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00; + hventerstabdelay = 100; + progmodedelay = 0; + latchcycles = 5; + togglevtg = 1; + poweroffdelay = 15; + resetdelayms = 2; + resetdelayus = 0; + hvleavestabdelay = 15; + chiperasepulsewidth = 0; + chiperasepolltimeout = 10; + programfusepulsewidth = 0; + programfusepolltimeout = 5; + programlockpulsewidth = 0; + programlockpolltimeout = 5; + + ocdrev = 1; + + memory "eeprom" + paged = no; + size = 512; + num_pages = 128; + page_size = 4; + min_write_delay = 4000; + max_write_delay = 4000; + readback_p1 = 0xff; + readback_p2 = 0xff; + + read = " 1 0 1 0 0 0 0 0 x x x x x x x a8", + "a7 a6 a5 a4 a3 a2 a1 a0 o o o o o o o o"; + + write = " 1 1 0 0 0 0 0 0 x x x x x x x a8", + "a7 a6 a5 a4 a3 a2 a1 a0 i i i i i i i i"; + + loadpage_lo = " 1 1 0 0 0 0 0 1", + " 0 0 0 0 0 0 0 0", + " 0 0 0 0 0 0 a1 a0", + " i i i i i i i i"; + + writepage = " 1 1 0 0 0 0 1 0", + " 0 0 x x x x x a8", + " a7 a6 a5 a4 a3 a2 0 0", + " x x x x x x x x"; + + mode = 0x41; + delay = 10; + blocksize = 4; + readsize = 256; + ; + + memory "flash" + paged = yes; + size = 8192; + page_size = 64; + num_pages = 128; + min_write_delay = 4500; + max_write_delay = 4500; + readback_p1 = 0xff; + readback_p2 = 0xff; + + read_lo = " 0 0 1 0 0 0 0 0", + " x x x x a11 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + read_hi = " 0 0 1 0 1 0 0 0", + " x x x x a11 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + loadpage_lo = " 0 1 0 0 0 0 0 0", + " x x x x x x x x", + " x x x a4 a3 a2 a1 a0", + " i i i i i i i i"; + + loadpage_hi = " 0 1 0 0 1 0 0 0", + " x x x x x x x x", + " x x x a4 a3 a2 a1 a0", + " i i i i i i i i"; + + writepage = " 0 1 0 0 1 1 0 0", + " x x x x a11 a10 a9 a8", + " a7 a6 a5 x x x x x", + " x x x x x x x x"; + + mode = 0x41; + delay = 6; + blocksize = 64; + readsize = 256; + ; + + memory "signature" + size = 3; + read = "0 0 1 1 0 0 0 0 x x x x x x x x", + "0 0 0 0 0 0 a1 a0 o o o o o o o o"; + ; + + memory "lock" + size = 1; + read = "0 1 0 1 1 0 0 0 x x x x x x x x", + "x x x x x x x x x x x x x x o o"; + + write = "1 0 1 0 1 1 0 0 1 1 1 1 1 1 i i", + "x x x x x x x x x x x x x x x x"; + min_write_delay = 4500; + max_write_delay = 4500; + ; + + memory "lfuse" + size = 1; + write = "1 0 1 0 1 1 0 0 1 0 1 0 0 0 0 0", + "x x x x x x x x i i i i i i i i"; + + read = "0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0", + "x x x x x x x x o o o o o o o o"; + min_write_delay = 4500; + max_write_delay = 4500; + ; + + memory "hfuse" + size = 1; + write = "1 0 1 0 1 1 0 0 1 0 1 0 1 0 0 0", + "x x x x x x x x i i i i i i i i"; + + read = "0 1 0 1 1 0 0 0 0 0 0 0 1 0 0 0", + "x x x x x x x x o o o o o o o o"; + min_write_delay = 4500; + max_write_delay = 4500; + ; + + memory "efuse" + size = 1; + write = "1 0 1 0 1 1 0 0 1 0 1 0 0 1 0 0", + "x x x x x x x x x x x x x x x i"; + + read = "0 1 0 1 0 0 0 0 0 0 0 0 1 0 0 0", + "x x x x x x x x o o o o o o o o"; + min_write_delay = 4500; + max_write_delay = 4500; + ; + + memory "calibration" + size = 1; + read = "0 0 1 1 1 0 0 0 x x x x x x x x", + "0 0 0 0 0 0 0 0 o o o o o o o o"; + ; + +; + + +#------------------------------------------------------------ +# ATtiny28 +#------------------------------------------------------------ + +# This is an HVPP-only device. + +part + id = "t28"; + desc = "ATtiny28"; + stk500_devcode = 0x22; + avr910_devcode = 0x5c; + signature = 0x1e 0x91 0x07; + + pp_controlstack = + 0x0E, 0x1E, 0x0F, 0x1F, 0x2E, 0x3E, 0x2F, 0x3F, + 0x4E, 0x5E, 0x4F, 0x5F, 0x6E, 0x7E, 0x6F, 0x7F, + 0x66, 0x76, 0x67, 0x77, 0x6A, 0x7A, 0x6B, 0x7B, + 0xBE, 0xFD, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00; + hventerstabdelay = 100; + progmodedelay = 0; + latchcycles = 0; + togglevtg = 0; + poweroffdelay = 0; + resetdelayms = 0; + resetdelayus = 0; + hvleavestabdelay = 15; + resetdelay = 15; + chiperasepulsewidth = 0; + chiperasepolltimeout = 10; + programfusepulsewidth = 0; + programfusepolltimeout = 5; + programlockpulsewidth = 0; + programlockpolltimeout = 5; + + memory "flash" + size = 2048; + page_size = 2; + readsize = 256; + delay = 5; + ; + + memory "signature" + size = 3; + ; + + memory "lock" + size = 1; + ; + + memory "calibration" + size = 1; + ; + + memory "fuse" + size = 1; + ; +; + + + +#------------------------------------------------------------ +# ATmega48 +#------------------------------------------------------------ + +part + id = "m48"; + desc = "ATmega48"; + has_debugwire = yes; + flash_instr = 0xB6, 0x01, 0x11; + eeprom_instr = 0xBD, 0xF2, 0xBD, 0xE1, 0xBB, 0xCF, 0xB4, 0x00, + 0xBE, 0x01, 0xB6, 0x01, 0xBC, 0x00, 0xBB, 0xBF, + 0x99, 0xF9, 0xBB, 0xAF; + stk500_devcode = 0x59; +# avr910_devcode = 0x; + signature = 0x1e 0x92 0x05; + pagel = 0xd7; + bs2 = 0xc2; + chip_erase_delay = 45000; + pgm_enable = "1 0 1 0 1 1 0 0 0 1 0 1 0 0 1 1", + "x x x x x x x x x x x x x x x x"; + + chip_erase = "1 0 1 0 1 1 0 0 1 0 0 x x x x x", + "x x x x x x x x x x x x x x x x"; + + timeout = 200; + stabdelay = 100; + cmdexedelay = 25; + synchloops = 32; + bytedelay = 0; + pollindex = 3; + pollvalue = 0x53; + predelay = 1; + postdelay = 1; + pollmethod = 1; + + pp_controlstack = + 0x0E, 0x1E, 0x0F, 0x1F, 0x2E, 0x3E, 0x2F, 0x3F, + 0x4E, 0x5E, 0x4F, 0x5F, 0x6E, 0x7E, 0x6F, 0x7F, + 0x66, 0x76, 0x67, 0x77, 0x6A, 0x7A, 0x6B, 0x7B, + 0xBE, 0xFD, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00; + hventerstabdelay = 100; + progmodedelay = 0; + latchcycles = 5; + togglevtg = 1; + poweroffdelay = 15; + resetdelayms = 1; + resetdelayus = 0; + hvleavestabdelay = 15; + resetdelay = 15; + chiperasepulsewidth = 0; + chiperasepolltimeout = 10; + programfusepulsewidth = 0; + programfusepolltimeout = 5; + programlockpulsewidth = 0; + programlockpolltimeout = 5; + + ocdrev = 1; + + memory "eeprom" + paged = no; + page_size = 4; + size = 256; + min_write_delay = 3600; + max_write_delay = 3600; + readback_p1 = 0xff; + readback_p2 = 0xff; + read = " 1 0 1 0 0 0 0 0", + " 0 0 0 x x x x x", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + write = " 1 1 0 0 0 0 0 0", + " 0 0 0 x x x x x", + " a7 a6 a5 a4 a3 a2 a1 a0", + " i i i i i i i i"; + + loadpage_lo = " 1 1 0 0 0 0 0 1", + " 0 0 0 0 0 0 0 0", + " 0 0 0 0 0 0 a1 a0", + " i i i i i i i i"; + + writepage = " 1 1 0 0 0 0 1 0", + " 0 0 x x x x x x", + " a7 a6 a5 a4 a3 a2 0 0", + " x x x x x x x x"; + + mode = 0x41; + delay = 20; + blocksize = 4; + readsize = 256; + ; + memory "flash" + paged = yes; + size = 4096; + page_size = 64; + num_pages = 64; + min_write_delay = 4500; + max_write_delay = 4500; + readback_p1 = 0x00; + readback_p2 = 0x00; + read_lo = " 0 0 1 0 0 0 0 0", + " 0 0 0 0 0 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + read_hi = " 0 0 1 0 1 0 0 0", + " 0 0 0 0 0 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + loadpage_lo = " 0 1 0 0 0 0 0 0", + " 0 0 0 x x x x x", + " x x x a4 a3 a2 a1 a0", + " i i i i i i i i"; + + loadpage_hi = " 0 1 0 0 1 0 0 0", + " 0 0 0 x x x x x", + " x x x a4 a3 a2 a1 a0", + " i i i i i i i i"; + + writepage = " 0 1 0 0 1 1 0 0", + " 0 0 0 0 0 a10 a9 a8", + " a7 a6 a5 x x x x x", + " x x x x x x x x"; + + mode = 0x41; + delay = 6; + blocksize = 64; + readsize = 256; + ; + + memory "lfuse" + size = 1; + min_write_delay = 4500; + max_write_delay = 4500; + read = "0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0", + "x x x x x x x x o o o o o o o o"; + + write = "1 0 1 0 1 1 0 0 1 0 1 0 0 0 0 0", + "x x x x x x x x i i i i i i i i"; + ; + + memory "hfuse" + size = 1; + min_write_delay = 4500; + max_write_delay = 4500; + read = "0 1 0 1 1 0 0 0 0 0 0 0 1 0 0 0", + "x x x x x x x x o o o o o o o o"; + + write = "1 0 1 0 1 1 0 0 1 0 1 0 1 0 0 0", + "x x x x x x x x i i i i i i i i"; + ; + + memory "efuse" + size = 1; + min_write_delay = 4500; + max_write_delay = 4500; + read = "0 1 0 1 0 0 0 0 0 0 0 0 1 0 0 0", + "x x x x x x x x o o o o o o o o"; + + write = "1 0 1 0 1 1 0 0 1 0 1 0 0 1 0 0", + "x x x x x x x x x x x x x x x i"; + ; + + memory "lock" + size = 1; + min_write_delay = 4500; + max_write_delay = 4500; + read = "0 1 0 1 1 0 0 0 0 0 0 0 0 0 0 0", + "x x x x x x x x x x o o o o o o"; + + write = "1 0 1 0 1 1 0 0 1 1 1 x x x x x", + "x x x x x x x x 1 1 i i i i i i"; + ; + + memory "calibration" + size = 1; + read = "0 0 1 1 1 0 0 0 0 0 0 x x x x x", + "0 0 0 0 0 0 0 0 o o o o o o o o"; + ; + + memory "signature" + size = 3; + read = "0 0 1 1 0 0 0 0 0 0 0 x x x x x", + "x x x x x x a1 a0 o o o o o o o o"; + ; + ; + +#------------------------------------------------------------ +# ATmega48P +#------------------------------------------------------------ + +part parent "m48" + id = "m48p"; + desc = "ATmega48P"; + signature = 0x1e 0x92 0x0a; + + ocdrev = 1; + ; + +#------------------------------------------------------------ +# ATmega48PB +#------------------------------------------------------------ + +part parent "m48" + id = "m48pb"; + desc = "ATmega48PB"; + signature = 0x1e 0x92 0x10; + + ocdrev = 1; + ; + +#------------------------------------------------------------ +# ATmega88 +#------------------------------------------------------------ + +part + id = "m88"; + desc = "ATmega88"; + has_debugwire = yes; + flash_instr = 0xB6, 0x01, 0x11; + eeprom_instr = 0xBD, 0xF2, 0xBD, 0xE1, 0xBB, 0xCF, 0xB4, 0x00, + 0xBE, 0x01, 0xB6, 0x01, 0xBC, 0x00, 0xBB, 0xBF, + 0x99, 0xF9, 0xBB, 0xAF; + stk500_devcode = 0x73; +# avr910_devcode = 0x; + signature = 0x1e 0x93 0x0a; + pagel = 0xd7; + bs2 = 0xc2; + chip_erase_delay = 9000; + pgm_enable = "1 0 1 0 1 1 0 0 0 1 0 1 0 0 1 1", + "x x x x x x x x x x x x x x x x"; + + chip_erase = "1 0 1 0 1 1 0 0 1 0 0 x x x x x", + "x x x x x x x x x x x x x x x x"; + + timeout = 200; + stabdelay = 100; + cmdexedelay = 25; + synchloops = 32; + bytedelay = 0; + pollindex = 3; + pollvalue = 0x53; + predelay = 1; + postdelay = 1; + pollmethod = 1; + + pp_controlstack = + 0x0E, 0x1E, 0x0F, 0x1F, 0x2E, 0x3E, 0x2F, 0x3F, + 0x4E, 0x5E, 0x4F, 0x5F, 0x6E, 0x7E, 0x6F, 0x7F, + 0x66, 0x76, 0x67, 0x77, 0x6A, 0x7A, 0x6B, 0x7B, + 0xBE, 0xFD, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00; + hventerstabdelay = 100; + progmodedelay = 0; + latchcycles = 5; + togglevtg = 1; + poweroffdelay = 15; + resetdelayms = 1; + resetdelayus = 0; + hvleavestabdelay = 15; + resetdelay = 15; + chiperasepulsewidth = 0; + chiperasepolltimeout = 10; + programfusepulsewidth = 0; + programfusepolltimeout = 5; + programlockpulsewidth = 0; + programlockpolltimeout = 5; + + ocdrev = 1; + + memory "eeprom" + paged = no; + page_size = 4; + size = 512; + min_write_delay = 3600; + max_write_delay = 3600; + readback_p1 = 0xff; + readback_p2 = 0xff; + read = " 1 0 1 0 0 0 0 0", + " 0 0 0 x x x x a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + write = " 1 1 0 0 0 0 0 0", + " 0 0 0 x x x x a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " i i i i i i i i"; + + loadpage_lo = " 1 1 0 0 0 0 0 1", + " 0 0 0 0 0 0 0 0", + " 0 0 0 0 0 0 a1 a0", + " i i i i i i i i"; + + writepage = " 1 1 0 0 0 0 1 0", + " 0 0 x x x x x a8", + " a7 a6 a5 a4 a3 a2 0 0", + " x x x x x x x x"; + + mode = 0x41; + delay = 20; + blocksize = 4; + readsize = 256; + ; + memory "flash" + paged = yes; + size = 8192; + page_size = 64; + num_pages = 128; + min_write_delay = 4500; + max_write_delay = 4500; + readback_p1 = 0xff; + readback_p2 = 0xff; + read_lo = " 0 0 1 0 0 0 0 0", + " 0 0 0 0 a11 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + read_hi = " 0 0 1 0 1 0 0 0", + " 0 0 0 0 a11 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + loadpage_lo = " 0 1 0 0 0 0 0 0", + " 0 0 0 x x x x x", + " x x x a4 a3 a2 a1 a0", + " i i i i i i i i"; + + loadpage_hi = " 0 1 0 0 1 0 0 0", + " 0 0 0 x x x x x", + " x x x a4 a3 a2 a1 a0", + " i i i i i i i i"; + + writepage = " 0 1 0 0 1 1 0 0", + " 0 0 0 0 a11 a10 a9 a8", + " a7 a6 a5 x x x x x", + " x x x x x x x x"; + + mode = 0x41; + delay = 6; + blocksize = 64; + readsize = 256; + ; + + memory "lfuse" + size = 1; + min_write_delay = 4500; + max_write_delay = 4500; + read = "0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0", + "x x x x x x x x o o o o o o o o"; + + write = "1 0 1 0 1 1 0 0 1 0 1 0 0 0 0 0", + "x x x x x x x x i i i i i i i i"; + ; + + memory "hfuse" + size = 1; + min_write_delay = 4500; + max_write_delay = 4500; + read = "0 1 0 1 1 0 0 0 0 0 0 0 1 0 0 0", + "x x x x x x x x o o o o o o o o"; + + write = "1 0 1 0 1 1 0 0 1 0 1 0 1 0 0 0", + "x x x x x x x x i i i i i i i i"; + ; + + memory "efuse" + size = 1; + min_write_delay = 4500; + max_write_delay = 4500; + read = "0 1 0 1 0 0 0 0 0 0 0 0 1 0 0 0", + "x x x x x x x x o o o o o o o o"; + + write = "1 0 1 0 1 1 0 0 1 0 1 0 0 1 0 0", + "x x x x x x x x x x x x x i i i"; + ; + + memory "lock" + size = 1; + min_write_delay = 4500; + max_write_delay = 4500; + read = "0 1 0 1 1 0 0 0 0 0 0 0 0 0 0 0", + "x x x x x x x x x x o o o o o o"; + + write = "1 0 1 0 1 1 0 0 1 1 1 x x x x x", + "x x x x x x x x 1 1 i i i i i i"; + ; + + memory "calibration" + size = 1; + read = "0 0 1 1 1 0 0 0 0 0 0 x x x x x", + "0 0 0 0 0 0 0 0 o o o o o o o o"; + ; + + memory "signature" + size = 3; + read = "0 0 1 1 0 0 0 0 0 0 0 x x x x x", + "x x x x x x a1 a0 o o o o o o o o"; + ; + ; + +#------------------------------------------------------------ +# ATmega88P +#------------------------------------------------------------ + +part parent "m88" + id = "m88p"; + desc = "ATmega88P"; + signature = 0x1e 0x93 0x0f; + + ocdrev = 1; + ; + +#------------------------------------------------------------ +# ATmega88PB +#------------------------------------------------------------ + +part parent "m88" + id = "m88pb"; + desc = "ATmega88PB"; + signature = 0x1e 0x93 0x16; + + ocdrev = 1; + ; + +#------------------------------------------------------------ +# ATmega168 +#------------------------------------------------------------ + +part + id = "m168"; + desc = "ATmega168"; + has_debugwire = yes; + flash_instr = 0xB6, 0x01, 0x11; + eeprom_instr = 0xBD, 0xF2, 0xBD, 0xE1, 0xBB, 0xCF, 0xB4, 0x00, + 0xBE, 0x01, 0xB6, 0x01, 0xBC, 0x00, 0xBB, 0xBF, + 0x99, 0xF9, 0xBB, 0xAF; + stk500_devcode = 0x86; + # avr910_devcode = 0x; + signature = 0x1e 0x94 0x06; + pagel = 0xd7; + bs2 = 0xc2; + chip_erase_delay = 9000; + pgm_enable = "1 0 1 0 1 1 0 0 0 1 0 1 0 0 1 1", + "x x x x x x x x x x x x x x x x"; + + chip_erase = "1 0 1 0 1 1 0 0 1 0 0 x x x x x", + "x x x x x x x x x x x x x x x x"; + + timeout = 200; + stabdelay = 100; + cmdexedelay = 25; + synchloops = 32; + bytedelay = 0; + pollindex = 3; + pollvalue = 0x53; + predelay = 1; + postdelay = 1; + pollmethod = 1; + + pp_controlstack = + 0x0E, 0x1E, 0x0F, 0x1F, 0x2E, 0x3E, 0x2F, 0x3F, + 0x4E, 0x5E, 0x4F, 0x5F, 0x6E, 0x7E, 0x6F, 0x7F, + 0x66, 0x76, 0x67, 0x77, 0x6A, 0x7A, 0x6B, 0x7B, + 0xBE, 0xFD, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00; + hventerstabdelay = 100; + progmodedelay = 0; + latchcycles = 5; + togglevtg = 1; + poweroffdelay = 15; + resetdelayms = 1; + resetdelayus = 0; + hvleavestabdelay = 15; + resetdelay = 15; + chiperasepulsewidth = 0; + chiperasepolltimeout = 10; + programfusepulsewidth = 0; + programfusepolltimeout = 5; + programlockpulsewidth = 0; + programlockpolltimeout = 5; + + ocdrev = 1; + + memory "eeprom" + paged = no; + page_size = 4; + size = 512; + min_write_delay = 3600; + max_write_delay = 3600; + readback_p1 = 0xff; + readback_p2 = 0xff; + read = " 1 0 1 0 0 0 0 0", + " 0 0 0 x x x x a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + write = " 1 1 0 0 0 0 0 0", + " 0 0 0 x x x x a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " i i i i i i i i"; + + loadpage_lo = " 1 1 0 0 0 0 0 1", + " 0 0 0 0 0 0 0 0", + " 0 0 0 0 0 0 a1 a0", + " i i i i i i i i"; + + writepage = " 1 1 0 0 0 0 1 0", + " 0 0 x x x x x a8", + " a7 a6 a5 a4 a3 a2 0 0", + " x x x x x x x x"; + + mode = 0x41; + delay = 20; + blocksize = 4; + readsize = 256; + ; + + memory "flash" + paged = yes; + size = 16384; + page_size = 128; + num_pages = 128; + min_write_delay = 4500; + max_write_delay = 4500; + readback_p1 = 0xff; + readback_p2 = 0xff; + read_lo = " 0 0 1 0 0 0 0 0", + " 0 0 0 a12 a11 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + read_hi = " 0 0 1 0 1 0 0 0", + " 0 0 0 a12 a11 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + loadpage_lo = " 0 1 0 0 0 0 0 0", + " 0 0 0 x x x x x", + " x x a5 a4 a3 a2 a1 a0", + " i i i i i i i i"; + + loadpage_hi = " 0 1 0 0 1 0 0 0", + " 0 0 0 x x x x x", + " x x a5 a4 a3 a2 a1 a0", + " i i i i i i i i"; + + writepage = " 0 1 0 0 1 1 0 0", + " 0 0 0 a12 a11 a10 a9 a8", + " a7 a6 x x x x x x", + " x x x x x x x x"; + + mode = 0x41; + delay = 6; + blocksize = 128; + readsize = 256; + + ; + + memory "lfuse" + size = 1; + min_write_delay = 4500; + max_write_delay = 4500; + read = "0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0", + "x x x x x x x x o o o o o o o o"; + + write = "1 0 1 0 1 1 0 0 1 0 1 0 0 0 0 0", + "x x x x x x x x i i i i i i i i"; + ; + + memory "hfuse" + size = 1; + min_write_delay = 4500; + max_write_delay = 4500; + read = "0 1 0 1 1 0 0 0 0 0 0 0 1 0 0 0", + "x x x x x x x x o o o o o o o o"; + + write = "1 0 1 0 1 1 0 0 1 0 1 0 1 0 0 0", + "x x x x x x x x i i i i i i i i"; + ; + + memory "efuse" + size = 1; + min_write_delay = 4500; + max_write_delay = 4500; + read = "0 1 0 1 0 0 0 0 0 0 0 0 1 0 0 0", + "x x x x x x x x o o o o o o o o"; + + write = "1 0 1 0 1 1 0 0 1 0 1 0 0 1 0 0", + "x x x x x x x x x x x x x i i i"; + ; + + memory "lock" + size = 1; + min_write_delay = 4500; + max_write_delay = 4500; + read = "0 1 0 1 1 0 0 0 0 0 0 0 0 0 0 0", + "x x x x x x x x x x o o o o o o"; + + write = "1 0 1 0 1 1 0 0 1 1 1 x x x x x", + "x x x x x x x x 1 1 i i i i i i"; + ; + + memory "calibration" + size = 1; + read = "0 0 1 1 1 0 0 0 0 0 0 x x x x x", + "0 0 0 0 0 0 0 0 o o o o o o o o"; + ; + + memory "signature" + size = 3; + read = "0 0 1 1 0 0 0 0 0 0 0 x x x x x", + "x x x x x x a1 a0 o o o o o o o o"; + ; +; + +#------------------------------------------------------------ +# ATmega168P +#------------------------------------------------------------ + +part parent "m168" + id = "m168p"; + desc = "ATmega168P"; + signature = 0x1e 0x94 0x0b; + + ocdrev = 1; +; + +#------------------------------------------------------------ +# ATmega168PB +#------------------------------------------------------------ + +part parent "m168" + id = "m168pb"; + desc = "ATmega168PB"; + signature = 0x1e 0x94 0x15; + + ocdrev = 1; +; + +#------------------------------------------------------------ +# ATtiny88 +#------------------------------------------------------------ + +part + id = "t88"; + desc = "ATtiny88"; + has_debugwire = yes; + flash_instr = 0xB6, 0x01, 0x11; + eeprom_instr = 0xBD, 0xF2, 0xBD, 0xE1, 0xBB, 0xCF, 0xB4, 0x00, + 0xBE, 0x01, 0xB6, 0x01, 0xBC, 0x00, 0xBB, 0xBF, + 0x99, 0xF9, 0xBB, 0xAF; + stk500_devcode = 0x73; +# avr910_devcode = 0x; + signature = 0x1e 0x93 0x11; + pagel = 0xd7; + bs2 = 0xc2; + chip_erase_delay = 9000; + pgm_enable = "1 0 1 0 1 1 0 0 0 1 0 1 0 0 1 1", + "x x x x x x x x x x x x x x x x"; + + chip_erase = "1 0 1 0 1 1 0 0 1 0 0 x x x x x", + "x x x x x x x x x x x x x x x x"; + + timeout = 200; + stabdelay = 100; + cmdexedelay = 25; + synchloops = 32; + bytedelay = 0; + pollindex = 3; + pollvalue = 0x53; + predelay = 1; + postdelay = 1; + pollmethod = 1; + + pp_controlstack = + 0x0E, 0x1E, 0x0F, 0x1F, 0x2E, 0x3E, 0x2F, 0x3F, + 0x4E, 0x5E, 0x4F, 0x5F, 0x6E, 0x7E, 0x6F, 0x7F, + 0x66, 0x76, 0x67, 0x77, 0x6A, 0x7A, 0x6B, 0x7B, + 0xBE, 0xFD, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00; + hventerstabdelay = 100; + progmodedelay = 0; + latchcycles = 5; + togglevtg = 1; + poweroffdelay = 15; + resetdelayms = 1; + resetdelayus = 0; + hvleavestabdelay = 15; + resetdelay = 15; + chiperasepulsewidth = 0; + chiperasepolltimeout = 10; + programfusepulsewidth = 0; + programfusepolltimeout = 5; + programlockpulsewidth = 0; + programlockpolltimeout = 5; + + ocdrev = 1; + + memory "eeprom" + paged = no; + page_size = 4; + size = 64; + min_write_delay = 3600; + max_write_delay = 3600; + readback_p1 = 0xff; + readback_p2 = 0xff; + read = " 1 0 1 0 0 0 0 0", + " 0 0 0 x x x x x", + " x a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + write = " 1 1 0 0 0 0 0 0", + " 0 0 0 x x x x x", + " x a6 a5 a4 a3 a2 a1 a0", + " i i i i i i i i"; + + loadpage_lo = " 1 1 0 0 0 0 0 1", + " 0 0 0 0 0 0 0 0", + " 0 0 0 0 0 0 a1 a0", + " i i i i i i i i"; + + writepage = " 1 1 0 0 0 0 1 0", + " 0 0 x x x x x x", + " x a6 a5 a4 a3 a2 0 0", + " x x x x x x x x"; + + mode = 0x41; + delay = 20; + blocksize = 4; + readsize = 64; + ; + memory "flash" + paged = yes; + size = 8192; + page_size = 64; + num_pages = 128; + min_write_delay = 4500; + max_write_delay = 4500; + readback_p1 = 0xff; + readback_p2 = 0xff; + read_lo = " 0 0 1 0 0 0 0 0", + " 0 0 0 0 a11 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + read_hi = " 0 0 1 0 1 0 0 0", + " 0 0 0 0 a11 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + loadpage_lo = " 0 1 0 0 0 0 0 0", + " 0 0 0 x x x x x", + " x x x a4 a3 a2 a1 a0", + " i i i i i i i i"; + + loadpage_hi = " 0 1 0 0 1 0 0 0", + " 0 0 0 x x x x x", + " x x x a4 a3 a2 a1 a0", + " i i i i i i i i"; + + writepage = " 0 1 0 0 1 1 0 0", + " 0 0 0 0 a11 a10 a9 a8", + " a7 a6 a5 x x x x x", + " x x x x x x x x"; + + mode = 0x41; + delay = 6; + blocksize = 64; + readsize = 256; + ; + + memory "lfuse" + size = 1; + min_write_delay = 4500; + max_write_delay = 4500; + read = "0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0", + "x x x x x x x x o o o o o o o o"; + + write = "1 0 1 0 1 1 0 0 1 0 1 0 0 0 0 0", + "x x x x x x x x i i i i i i i i"; + ; + + memory "hfuse" + size = 1; + min_write_delay = 4500; + max_write_delay = 4500; + read = "0 1 0 1 1 0 0 0 0 0 0 0 1 0 0 0", + "x x x x x x x x o o o o o o o o"; + + write = "1 0 1 0 1 1 0 0 1 0 1 0 1 0 0 0", + "x x x x x x x x i i i i i i i i"; + ; + + memory "efuse" + size = 1; + min_write_delay = 4500; + max_write_delay = 4500; + read = "0 1 0 1 0 0 0 0 0 0 0 0 1 0 0 0", + "x x x x x x x x o o o o o o o o"; + + write = "1 0 1 0 1 1 0 0 1 0 1 0 0 1 0 0", + "x x x x x x x x x x x x x x x i"; + ; + + memory "lock" + size = 1; + min_write_delay = 4500; + max_write_delay = 4500; + read = "0 1 0 1 1 0 0 0 0 0 0 0 0 0 0 0", + "x x x x x x x x x x o o o o o o"; + + write = "1 0 1 0 1 1 0 0 1 1 1 x x x x x", + "x x x x x x x x 1 1 i i i i i i"; + ; + + memory "calibration" + size = 1; + read = "0 0 1 1 1 0 0 0 0 0 0 x x x x x", + "0 0 0 0 0 0 0 0 o o o o o o o o"; + ; + + memory "signature" + size = 3; + read = "0 0 1 1 0 0 0 0 0 0 0 x x x x x", + "x x x x x x a1 a0 o o o o o o o o"; + ; + ; + +#------------------------------------------------------------ +# ATmega328 +#------------------------------------------------------------ + +part + id = "m328"; + desc = "ATmega328"; + has_debugwire = yes; + flash_instr = 0xB6, 0x01, 0x11; + eeprom_instr = 0xBD, 0xF2, 0xBD, 0xE1, 0xBB, 0xCF, 0xB4, 0x00, + 0xBE, 0x01, 0xB6, 0x01, 0xBC, 0x00, 0xBB, 0xBF, + 0x99, 0xF9, 0xBB, 0xAF; + stk500_devcode = 0x86; + # avr910_devcode = 0x; + signature = 0x1e 0x95 0x14; + pagel = 0xd7; + bs2 = 0xc2; + chip_erase_delay = 9000; + pgm_enable = "1 0 1 0 1 1 0 0 0 1 0 1 0 0 1 1", + "x x x x x x x x x x x x x x x x"; + + chip_erase = "1 0 1 0 1 1 0 0 1 0 0 x x x x x", + "x x x x x x x x x x x x x x x x"; + + timeout = 200; + stabdelay = 100; + cmdexedelay = 25; + synchloops = 32; + bytedelay = 0; + pollindex = 3; + pollvalue = 0x53; + predelay = 1; + postdelay = 1; + pollmethod = 1; + + pp_controlstack = + 0x0E, 0x1E, 0x0F, 0x1F, 0x2E, 0x3E, 0x2F, 0x3F, + 0x4E, 0x5E, 0x4F, 0x5F, 0x6E, 0x7E, 0x6F, 0x7F, + 0x66, 0x76, 0x67, 0x77, 0x6A, 0x7A, 0x6B, 0x7B, + 0xBE, 0xFD, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00; + hventerstabdelay = 100; + progmodedelay = 0; + latchcycles = 5; + togglevtg = 1; + poweroffdelay = 15; + resetdelayms = 1; + resetdelayus = 0; + hvleavestabdelay = 15; + resetdelay = 15; + chiperasepulsewidth = 0; + chiperasepolltimeout = 10; + programfusepulsewidth = 0; + programfusepolltimeout = 5; + programlockpulsewidth = 0; + programlockpolltimeout = 5; + + ocdrev = 1; + + memory "eeprom" + paged = no; + page_size = 4; + size = 1024; + min_write_delay = 3600; + max_write_delay = 3600; + readback_p1 = 0xff; + readback_p2 = 0xff; + read = " 1 0 1 0 0 0 0 0", + " 0 0 0 x x x a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + write = " 1 1 0 0 0 0 0 0", + " 0 0 0 x x x a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " i i i i i i i i"; + + loadpage_lo = " 1 1 0 0 0 0 0 1", + " 0 0 0 0 0 0 0 0", + " 0 0 0 0 0 0 a1 a0", + " i i i i i i i i"; + + writepage = " 1 1 0 0 0 0 1 0", + " 0 0 x x x x a9 a8", + " a7 a6 a5 a4 a3 a2 0 0", + " x x x x x x x x"; + + mode = 0x41; + delay = 20; + blocksize = 4; + readsize = 256; + ; + + memory "flash" + paged = yes; + size = 32768; + page_size = 128; + num_pages = 256; + min_write_delay = 4500; + max_write_delay = 4500; + readback_p1 = 0xff; + readback_p2 = 0xff; + read_lo = " 0 0 1 0 0 0 0 0", + " 0 0 a13 a12 a11 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + read_hi = " 0 0 1 0 1 0 0 0", + " 0 0 a13 a12 a11 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + loadpage_lo = " 0 1 0 0 0 0 0 0", + " 0 0 0 x x x x x", + " x x a5 a4 a3 a2 a1 a0", + " i i i i i i i i"; + + loadpage_hi = " 0 1 0 0 1 0 0 0", + " 0 0 0 x x x x x", + " x x a5 a4 a3 a2 a1 a0", + " i i i i i i i i"; + + writepage = " 0 1 0 0 1 1 0 0", + " 0 0 a13 a12 a11 a10 a9 a8", + " a7 a6 x x x x x x", + " x x x x x x x x"; + + mode = 0x41; + delay = 6; + blocksize = 128; + readsize = 256; + + ; + + memory "lfuse" + size = 1; + min_write_delay = 4500; + max_write_delay = 4500; + read = "0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0", + "x x x x x x x x o o o o o o o o"; + + write = "1 0 1 0 1 1 0 0 1 0 1 0 0 0 0 0", + "x x x x x x x x i i i i i i i i"; + ; + + memory "hfuse" + size = 1; + min_write_delay = 4500; + max_write_delay = 4500; + read = "0 1 0 1 1 0 0 0 0 0 0 0 1 0 0 0", + "x x x x x x x x o o o o o o o o"; + + write = "1 0 1 0 1 1 0 0 1 0 1 0 1 0 0 0", + "x x x x x x x x i i i i i i i i"; + ; + + memory "efuse" + size = 1; + min_write_delay = 4500; + max_write_delay = 4500; + read = "0 1 0 1 0 0 0 0 0 0 0 0 1 0 0 0", + "x x x x x x x x o o o o o o o o"; + + write = "1 0 1 0 1 1 0 0 1 0 1 0 0 1 0 0", + "x x x x x x x x x x x x x i i i"; + ; + + memory "lock" + size = 1; + min_write_delay = 4500; + max_write_delay = 4500; + read = "0 1 0 1 1 0 0 0 0 0 0 0 0 0 0 0", + "x x x x x x x x x x o o o o o o"; + + write = "1 0 1 0 1 1 0 0 1 1 1 x x x x x", + "x x x x x x x x 1 1 i i i i i i"; + ; + + memory "calibration" + size = 1; + read = "0 0 1 1 1 0 0 0 0 0 0 x x x x x", + "0 0 0 0 0 0 0 0 o o o o o o o o"; + ; + + memory "signature" + size = 3; + read = "0 0 1 1 0 0 0 0 0 0 0 x x x x x", + "x x x x x x a1 a0 o o o o o o o o"; + ; +; + +part parent "m328" + id = "m328p"; + desc = "ATmega328P"; + signature = 0x1e 0x95 0x0F; + + ocdrev = 1; +; + +#------------------------------------------------------------ +# ATmega32m1 +#------------------------------------------------------------ + +part parent "m328" + id = "m32m1"; + desc = "ATmega32M1"; + # stk500_devcode = 0x; + # avr910_devcode = 0x; + signature = 0x1e 0x95 0x84; + bs2 = 0xe2; + + memory "efuse" + read = "0 1 0 1 0 0 0 0 0 0 0 0 1 0 0 0", + "x x x x x x x x o o o o o o o o"; + write = "1 0 1 0 1 1 0 0 1 0 1 0 0 1 0 0", + "x x x x x x x x x x i i i i i i"; + ; +; + +#------------------------------------------------------------ +# ATtiny2313 +#------------------------------------------------------------ + +part + id = "t2313"; + desc = "ATtiny2313"; + has_debugwire = yes; + flash_instr = 0xB2, 0x0F, 0x1F; + eeprom_instr = 0xBB, 0xFE, 0xBB, 0xEE, 0xBB, 0xCC, 0xB2, 0x0D, + 0xBA, 0x0F, 0xB2, 0x0F, 0xBA, 0x0D, 0xBB, 0xBC, + 0x99, 0xE1, 0xBB, 0xAC; + stk500_devcode = 0x23; +## Use the ATtiny26 devcode: + avr910_devcode = 0x5e; + signature = 0x1e 0x91 0x0a; + pagel = 0xD4; + bs2 = 0xD6; + reset = io; + chip_erase_delay = 9000; + + pgm_enable = "1 0 1 0 1 1 0 0 0 1 0 1 0 0 1 1", + "x x x x x x x x x x x x x x x x"; + + chip_erase = "1 0 1 0 1 1 0 0 1 0 0 x x x x x", + "x x x x x x x x x x x x x x x x"; + + timeout = 200; + stabdelay = 100; + cmdexedelay = 25; + synchloops = 32; + bytedelay = 0; + pollindex = 3; + pollvalue = 0x53; + predelay = 1; + postdelay = 1; + pollmethod = 1; + + pp_controlstack = + 0x0E, 0x1E, 0x0E, 0x1E, 0x2E, 0x3E, 0x2E, 0x3E, + 0x4E, 0x5E, 0x4E, 0x5E, 0x6E, 0x7E, 0x6E, 0x7E, + 0x26, 0x36, 0x66, 0x76, 0x2A, 0x3A, 0x6A, 0x7A, + 0x2E, 0xFD, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00; + hventerstabdelay = 100; + progmodedelay = 0; + latchcycles = 5; + togglevtg = 1; + poweroffdelay = 15; + resetdelayms = 1; + resetdelayus = 0; + hvleavestabdelay = 15; + chiperasepulsewidth = 0; + chiperasepolltimeout = 10; + programfusepulsewidth = 0; + programfusepolltimeout = 5; + programlockpulsewidth = 0; + programlockpolltimeout = 5; + + ocdrev = 0; + + memory "eeprom" + size = 128; + paged = no; + page_size = 4; + min_write_delay = 4000; + max_write_delay = 4500; + readback_p1 = 0xff; + readback_p2 = 0xff; + read = "1 0 1 0 0 0 0 0 0 0 0 x x x x x", + "x a6 a5 a4 a3 a2 a1 a0 o o o o o o o o"; + + write = "1 1 0 0 0 0 0 0 0 0 0 x x x x x", + "x a6 a5 a4 a3 a2 a1 a0 i i i i i i i i"; + + loadpage_lo = " 1 1 0 0 0 0 0 1", + " 0 0 0 0 0 0 0 0", + " 0 0 0 0 0 0 a1 a0", + " i i i i i i i i"; + + writepage = " 1 1 0 0 0 0 1 0", + " 0 0 x x x x x x", + " x a6 a5 a4 a3 a2 0 0", + " x x x x x x x x"; + + mode = 0x41; + delay = 6; + blocksize = 4; + readsize = 256; + ; + memory "flash" + paged = yes; + size = 2048; + page_size = 32; + num_pages = 64; + min_write_delay = 4500; + max_write_delay = 4500; + readback_p1 = 0xff; + readback_p2 = 0xff; + read_lo = " 0 0 1 0 0 0 0 0", + " 0 0 0 0 0 0 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + read_hi = " 0 0 1 0 1 0 0 0", + " 0 0 0 0 0 0 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + +# The information in the data sheet of April/2004 is wrong, this works: + loadpage_lo = " 0 1 0 0 0 0 0 0", + " 0 0 0 x x x x x", + " x x x x a3 a2 a1 a0", + " i i i i i i i i"; + +# The information in the data sheet of April/2004 is wrong, this works: + loadpage_hi = " 0 1 0 0 1 0 0 0", + " 0 0 0 x x x x x", + " x x x x a3 a2 a1 a0", + " i i i i i i i i"; + +# The information in the data sheet of April/2004 is wrong, this works: + writepage = " 0 1 0 0 1 1 0 0", + " 0 0 0 0 0 0 a9 a8", + " a7 a6 a5 a4 x x x x", + " x x x x x x x x"; + + mode = 0x41; + delay = 6; + blocksize = 32; + readsize = 256; + ; +# ATtiny2313 has Signature Bytes: 0x1E 0x91 0x0A. + memory "signature" + size = 3; + read = "0 0 1 1 0 0 0 0 0 0 0 x x x x x", + "x x x x x x a1 a0 o o o o o o o o"; + ; + memory "lock" + size = 1; + write = "1 0 1 0 1 1 0 0 1 1 1 x x x x x", + "x x x x x x x x 1 1 i i i i i i"; + read = "0 1 0 1 1 0 0 0 0 0 0 0 0 0 0 0", + "x x x x x x x x x x o o o o o o"; + min_write_delay = 9000; + max_write_delay = 9000; + ; + + memory "lfuse" + size = 1; + write = "1 0 1 0 1 1 0 0 1 0 1 0 0 0 0 0", + "x x x x x x x x i i i i i i i i"; + + read = "0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0", + "x x x x x x x x o o o o o o o o"; + min_write_delay = 9000; + max_write_delay = 9000; + ; + + memory "hfuse" + size = 1; + write = "1 0 1 0 1 1 0 0 1 0 1 0 1 0 0 0", + "x x x x x x x x i i i i i i i i"; + + read = "0 1 0 1 1 0 0 0 0 0 0 0 1 0 0 0", + "x x x x x x x x o o o o o o o o"; + min_write_delay = 9000; + max_write_delay = 9000; + ; + + memory "efuse" + size = 1; + write = "1 0 1 0 1 1 0 0 1 0 1 0 0 1 0 0", + "x x x x x x x x x x x x x x x i"; + + read = "0 1 0 1 0 0 0 0 0 0 0 0 1 0 0 0", + "x x x x x x x x o o o o o o o o"; + min_write_delay = 9000; + max_write_delay = 9000; + ; +# The Tiny2313 has calibration data for both 4 MHz and 8 MHz. +# The information in the data sheet of April/2004 is wrong, this works: + + memory "calibration" + size = 2; + read = "0 0 1 1 1 0 0 0 0 0 0 x x x x x", + "0 0 0 0 0 0 0 a0 o o o o o o o o"; + ; + ; + +#------------------------------------------------------------ +# ATtiny4313 +#------------------------------------------------------------ + +part + id = "t4313"; + desc = "ATtiny4313"; + has_debugwire = yes; + flash_instr = 0xB2, 0x0F, 0x1F; + eeprom_instr = 0xBB, 0xFE, 0xBB, 0xEE, 0xBB, 0xCC, 0xB2, 0x0D, + 0xBA, 0x0F, 0xB2, 0x0F, 0xBA, 0x0D, 0xBB, 0xBC, + 0x99, 0xE1, 0xBB, 0xAC; + stk500_devcode = 0x23; +## Use the ATtiny26 devcode: + avr910_devcode = 0x5e; + signature = 0x1e 0x92 0x0d; + pagel = 0xD4; + bs2 = 0xD6; + reset = io; + chip_erase_delay = 9000; + + pgm_enable = "1 0 1 0 1 1 0 0 0 1 0 1 0 0 1 1", + "x x x x x x x x x x x x x x x x"; + + chip_erase = "1 0 1 0 1 1 0 0 1 0 0 x x x x x", + "x x x x x x x x x x x x x x x x"; + + timeout = 200; + stabdelay = 100; + cmdexedelay = 25; + synchloops = 32; + bytedelay = 0; + pollindex = 3; + pollvalue = 0x53; + predelay = 1; + postdelay = 1; + pollmethod = 1; + + pp_controlstack = + 0x0E, 0x1E, 0x0E, 0x1E, 0x2E, 0x3E, 0x2E, 0x3E, + 0x4E, 0x5E, 0x4E, 0x5E, 0x6E, 0x7E, 0x6E, 0x7E, + 0x26, 0x36, 0x66, 0x76, 0x2A, 0x3A, 0x6A, 0x7A, + 0x2E, 0xFD, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00; + hventerstabdelay = 100; + progmodedelay = 0; + latchcycles = 5; + togglevtg = 1; + poweroffdelay = 15; + resetdelayms = 1; + resetdelayus = 0; + hvleavestabdelay = 15; + chiperasepulsewidth = 0; + chiperasepolltimeout = 10; + programfusepulsewidth = 0; + programfusepolltimeout = 5; + programlockpulsewidth = 0; + programlockpolltimeout = 5; + + ocdrev = 0; + + memory "eeprom" + size = 256; + paged = no; + page_size = 4; + min_write_delay = 4000; + max_write_delay = 4500; + readback_p1 = 0xff; + readback_p2 = 0xff; + read = "1 0 1 0 0 0 0 0 0 0 0 x x x x x", + "a7 a6 a5 a4 a3 a2 a1 a0 o o o o o o o o"; + + write = "1 1 0 0 0 0 0 0 0 0 0 x x x x x", + "a7 a6 a5 a4 a3 a2 a1 a0 i i i i i i i i"; + + loadpage_lo = " 1 1 0 0 0 0 0 1", + " 0 0 0 0 0 0 0 0", + " 0 0 0 0 0 0 a1 a0", + " i i i i i i i i"; + + writepage = " 1 1 0 0 0 0 1 0", + " 0 0 x x x x x x", + " a7 a6 a5 a4 a3 a2 0 0", + " x x x x x x x x"; + + mode = 0x41; + delay = 6; + blocksize = 4; + readsize = 256; + ; + memory "flash" + paged = yes; + size = 4096; + page_size = 64; + num_pages = 64; + min_write_delay = 4500; + max_write_delay = 4500; + readback_p1 = 0xff; + readback_p2 = 0xff; + read_lo = " 0 0 1 0 0 0 0 0", + " 0 0 0 0 0 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + read_hi = " 0 0 1 0 1 0 0 0", + " 0 0 0 0 0 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + loadpage_lo = " 0 1 0 0 0 0 0 0", + " 0 0 0 x x x x x", + " x x x a4 a3 a2 a1 a0", + " i i i i i i i i"; + + loadpage_hi = " 0 1 0 0 1 0 0 0", + " 0 0 0 x x x x x", + " x x x a4 a3 a2 a1 a0", + " i i i i i i i i"; + + writepage = " 0 1 0 0 1 1 0 0", + " 0 0 0 0 0 a10 a9 a8", + " a7 a6 a5 x x x x x", + " x x x x x x x x"; + + mode = 0x41; + delay = 6; + blocksize = 32; + readsize = 256; + ; +# ATtiny4313 has Signature Bytes: 0x1E 0x92 0x0D. + memory "signature" + size = 3; + read = "0 0 1 1 0 0 0 0 0 0 0 x x x x x", + "x x x x x x a1 a0 o o o o o o o o"; + ; + memory "lock" + size = 1; + write = "1 0 1 0 1 1 0 0 1 1 1 x x x x x", + "x x x x x x x x 1 1 i i i i i i"; + read = "0 1 0 1 1 0 0 0 0 0 0 0 0 0 0 0", + "x x x x x x x x x x o o o o o o"; + min_write_delay = 9000; + max_write_delay = 9000; + ; + + memory "lfuse" + size = 1; + write = "1 0 1 0 1 1 0 0 1 0 1 0 0 0 0 0", + "x x x x x x x x i i i i i i i i"; + + read = "0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0", + "x x x x x x x x o o o o o o o o"; + min_write_delay = 9000; + max_write_delay = 9000; + ; + + memory "hfuse" + size = 1; + write = "1 0 1 0 1 1 0 0 1 0 1 0 1 0 0 0", + "x x x x x x x x i i i i i i i i"; + + read = "0 1 0 1 1 0 0 0 0 0 0 0 1 0 0 0", + "x x x x x x x x o o o o o o o o"; + min_write_delay = 9000; + max_write_delay = 9000; + ; + + memory "efuse" + size = 1; + write = "1 0 1 0 1 1 0 0 1 0 1 0 0 1 0 0", + "x x x x x x x x x x x x x x x i"; + + read = "0 1 0 1 0 0 0 0 0 0 0 0 1 0 0 0", + "x x x x x x x x o o o o o o o o"; + min_write_delay = 9000; + max_write_delay = 9000; + ; + + memory "calibration" + size = 2; + read = "0 0 1 1 1 0 0 0 0 0 0 x x x x x", + "0 0 0 0 0 0 0 a0 o o o o o o o o"; + ; + ; + +#------------------------------------------------------------ +# AT90PWM2 +#------------------------------------------------------------ + +part + id = "pwm2"; + desc = "AT90PWM2"; + has_debugwire = yes; + flash_instr = 0xB6, 0x01, 0x11; + eeprom_instr = 0xBD, 0xF2, 0xBD, 0xE1, 0xBB, 0xCF, 0xB4, 0x00, + 0xBE, 0x01, 0xB6, 0x01, 0xBC, 0x00, 0xBB, 0xBF, + 0x99, 0xF9, 0xBB, 0xAF; + stk500_devcode = 0x65; +## avr910_devcode = ?; + signature = 0x1e 0x93 0x81; + pagel = 0xD8; + bs2 = 0xE2; + reset = io; + chip_erase_delay = 9000; + + pgm_enable = "1 0 1 0 1 1 0 0 0 1 0 1 0 0 1 1", + "x x x x x x x x x x x x x x x x"; + + chip_erase = "1 0 1 0 1 1 0 0 1 0 0 x x x x x", + "x x x x x x x x x x x x x x x x"; + + timeout = 200; + stabdelay = 100; + cmdexedelay = 25; + synchloops = 32; + bytedelay = 0; + pollindex = 3; + pollvalue = 0x53; + predelay = 1; + postdelay = 1; + pollmethod = 1; + + pp_controlstack = + 0x0E, 0x1E, 0x0F, 0x1F, 0x2E, 0x3E, 0x2F, 0x3F, + 0x4E, 0x5E, 0x4F, 0x5F, 0x6E, 0x7E, 0x6F, 0x7F, + 0x66, 0x76, 0x67, 0x77, 0x6A, 0x7A, 0x6B, 0x7B, + 0xBE, 0xFD, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00; + hventerstabdelay = 100; + progmodedelay = 0; + latchcycles = 5; + togglevtg = 1; + poweroffdelay = 15; + resetdelayms = 1; + resetdelayus = 0; + hvleavestabdelay = 15; + chiperasepulsewidth = 0; + chiperasepolltimeout = 10; + programfusepulsewidth = 0; + programfusepolltimeout = 5; + programlockpulsewidth = 0; + programlockpolltimeout = 5; + + memory "eeprom" + size = 512; + paged = no; + page_size = 4; + min_write_delay = 4000; + max_write_delay = 4500; + readback_p1 = 0xff; + readback_p2 = 0xff; + read = "1 0 1 0 0 0 0 0 0 0 0 x x x x a8", + "a7 a6 a5 a4 a3 a2 a1 a0 o o o o o o o o"; + + write = "1 1 0 0 0 0 0 0 0 0 0 x x x x a8", + "a7 a6 a5 a4 a3 a2 a1 a0 i i i i i i i i"; + + loadpage_lo = " 1 1 0 0 0 0 0 1", + " 0 0 0 0 0 0 0 0", + " 0 0 0 0 0 0 a1 a0", + " i i i i i i i i"; + + writepage = " 1 1 0 0 0 0 1 0", + " 0 0 x x x x x x", + " a7 a6 a5 a4 a3 a2 0 0", + " x x x x x x x x"; + + mode = 0x41; + delay = 6; + blocksize = 4; + readsize = 256; + ; + memory "flash" + paged = yes; + size = 8192; + page_size = 64; + num_pages = 128; + min_write_delay = 4500; + max_write_delay = 4500; + readback_p1 = 0xff; + readback_p2 = 0xff; + read_lo = " 0 0 1 0 0 0 0 0", + " 0 0 0 0 a11 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + read_hi = " 0 0 1 0 1 0 0 0", + " 0 0 0 0 a11 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + loadpage_lo = " 0 1 0 0 0 0 0 0", + " 0 0 0 x x x x x", + " x x x a4 a3 a2 a1 a0", + " i i i i i i i i"; + + loadpage_hi = " 0 1 0 0 1 0 0 0", + " 0 0 0 x x x x x", + " x x x a4 a3 a2 a1 a0", + " i i i i i i i i"; + + writepage = " 0 1 0 0 1 1 0 0", + " 0 0 0 0 a11 a10 a9 a8", + " a7 a6 a5 x x x x x", + " x x x x x x x x"; + + mode = 0x41; + delay = 6; + blocksize = 64; + readsize = 256; + ; +# AT90PWM2 has Signature Bytes: 0x1E 0x93 0x81. + memory "signature" + size = 3; + read = "0 0 1 1 0 0 0 0 0 0 x x x x x x", + "x x x x x x a1 a0 o o o o o o o o"; + ; + memory "lock" + size = 1; + write = "1 0 1 0 1 1 0 0 1 1 1 x x x x x", + "x x x x x x x x 1 1 i i i i i i"; + + read = "0 1 0 1 1 0 0 0 0 0 0 0 0 0 0 0", + "x x x x x x x x x x o o o o o o"; + min_write_delay = 9000; + max_write_delay = 9000; + ; + + memory "lfuse" + size = 1; + write = "1 0 1 0 1 1 0 0 1 0 1 0 0 0 0 0", + "x x x x x x x x i i i i i i i i"; + + read = "0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0", + "x x x x x x x x o o o o o o o o"; + min_write_delay = 9000; + max_write_delay = 9000; + ; + + memory "hfuse" + size = 1; + write = "1 0 1 0 1 1 0 0 1 0 1 0 1 0 0 0", + "x x x x x x x x i i i i i i i i"; + + read = "0 1 0 1 1 0 0 0 0 0 0 0 1 0 0 0", + "x x x x x x x x o o o o o o o o"; + min_write_delay = 9000; + max_write_delay = 9000; + ; + + memory "efuse" + size = 1; + write = "1 0 1 0 1 1 0 0 1 0 1 0 0 1 0 0", + "x x x x x x x x i i i i i i i i"; + + read = "0 1 0 1 0 0 0 0 0 0 0 0 1 0 0 0", + "x x x x x x x x o o o o o o o o"; + min_write_delay = 9000; + max_write_delay = 9000; + ; + + memory "calibration" + size = 1; + read = "0 0 1 1 1 0 0 0 0 0 0 x x x x x", + "0 0 0 0 0 0 0 0 o o o o o o o o"; + ; + ; + +#------------------------------------------------------------ +# AT90PWM3 +#------------------------------------------------------------ + +# Completely identical to AT90PWM2 (including the signature!) + +part parent "pwm2" + id = "pwm3"; + desc = "AT90PWM3"; + ; + +#------------------------------------------------------------ +# AT90PWM2B +#------------------------------------------------------------ +# Same as AT90PWM2 but different signature. + +part parent "pwm2" + id = "pwm2b"; + desc = "AT90PWM2B"; + signature = 0x1e 0x93 0x83; + + ocdrev = 1; + ; + +#------------------------------------------------------------ +# AT90PWM3B +#------------------------------------------------------------ + +# Completely identical to AT90PWM2B (including the signature!) + +part parent "pwm2b" + id = "pwm3b"; + desc = "AT90PWM3B"; + + ocdrev = 1; + ; + +#------------------------------------------------------------ +# AT90PWM316 +#------------------------------------------------------------ + +# Similar to AT90PWM3B, but with 16 kiB flash, 512 B EEPROM, and 1024 B SRAM. + +part parent "pwm3b" + id = "pwm316"; + desc = "AT90PWM316"; + signature = 0x1e 0x94 0x83; + + ocdrev = 1; + + memory "flash" + paged = yes; + size = 16384; + page_size = 128; + num_pages = 128; + min_write_delay = 4500; + max_write_delay = 4500; + readback_p1 = 0xff; + readback_p2 = 0xff; + read_lo = " 0 0 1 0 0 0 0 0", + " 0 0 a13 a12 a11 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + read_hi = " 0 0 1 0 1 0 0 0", + " 0 0 a13 a12 a11 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + loadpage_lo = " 0 1 0 0 0 0 0 0", + " 0 0 x x x x x x", + " x x a5 a4 a3 a2 a1 a0", + " i i i i i i i i"; + + loadpage_hi = " 0 1 0 0 1 0 0 0", + " 0 0 x x x x x x", + " x x a5 a4 a3 a2 a1 a0", + " i i i i i i i i"; + + writepage = " 0 1 0 0 1 1 0 0", + " 0 0 a13 a12 a11 a10 a9 a8", + " a7 a6 x x x x x x", + " x x x x x x x x"; + + mode = 0x21; + delay = 6; + blocksize = 128; + readsize = 256; + ; + ; + +#------------------------------------------------------------ +# AT90PWM216 +#------------------------------------------------------------ +# Completely identical to AT90PWM316 (including the signature!) + +part parent "pwm316" + id = "pwm216"; + desc = "AT90PWM216"; + ; + +#------------------------------------------------------------ +# ATtiny25 +#------------------------------------------------------------ + +part + id = "t25"; + desc = "ATtiny25"; + has_debugwire = yes; + flash_instr = 0xB4, 0x02, 0x12; + eeprom_instr = 0xBB, 0xFF, 0xBB, 0xEE, 0xBB, 0xCC, 0xB2, 0x0D, + 0xBC, 0x02, 0xB4, 0x02, 0xBA, 0x0D, 0xBB, 0xBC, + 0x99, 0xE1, 0xBB, 0xAC; +## no STK500 devcode in XML file, use the ATtiny45 one + stk500_devcode = 0x14; +## avr910_devcode = ?; +## Try the AT90S2313 devcode: + avr910_devcode = 0x20; + signature = 0x1e 0x91 0x08; + reset = io; + chip_erase_delay = 4500; + + pgm_enable = "1 0 1 0 1 1 0 0 0 1 0 1 0 0 1 1", + "x x x x x x x x x x x x x x x x"; + + chip_erase = "1 0 1 0 1 1 0 0 1 0 0 x x x x x", + "x x x x x x x x x x x x x x x x"; + + timeout = 200; + stabdelay = 100; + cmdexedelay = 25; + synchloops = 32; + bytedelay = 0; + pollindex = 3; + pollvalue = 0x53; + predelay = 1; + postdelay = 1; + pollmethod = 1; + + hvsp_controlstack = + 0x4C, 0x0C, 0x1C, 0x2C, 0x3C, 0x64, 0x74, 0x66, + 0x68, 0x78, 0x68, 0x68, 0x7A, 0x6A, 0x68, 0x78, + 0x78, 0x7D, 0x6D, 0x0C, 0x80, 0x40, 0x20, 0x10, + 0x11, 0x08, 0x04, 0x02, 0x03, 0x08, 0x04, 0x00; + hventerstabdelay = 100; + hvspcmdexedelay = 0; + synchcycles = 6; + latchcycles = 1; + togglevtg = 1; + poweroffdelay = 25; + resetdelayms = 1; + resetdelayus = 0; + hvleavestabdelay = 100; + resetdelay = 25; + chiperasepolltimeout = 40; + chiperasetime = 0; + programfusepolltimeout = 25; + programlockpolltimeout = 25; + + ocdrev = 1; + + memory "eeprom" + size = 128; + paged = no; + page_size = 4; + min_write_delay = 4000; + max_write_delay = 4500; + readback_p1 = 0xff; + readback_p2 = 0xff; + read = "1 0 1 0 0 0 0 0 0 0 0 x x x x x", + "x a6 a5 a4 a3 a2 a1 a0 o o o o o o o o"; + + write = "1 1 0 0 0 0 0 0 0 0 0 x x x x x", + "x a6 a5 a4 a3 a2 a1 a0 i i i i i i i i"; + + loadpage_lo = " 1 1 0 0 0 0 0 1", + " 0 0 0 0 0 0 0 0", + " 0 0 0 0 0 0 a1 a0", + " i i i i i i i i"; + + writepage = " 1 1 0 0 0 0 1 0", + " 0 0 x x x x x x", + " x a6 a5 a4 a3 a2 0 0", + " x x x x x x x x"; + + mode = 0x41; + delay = 6; + blocksize = 4; + readsize = 256; + ; + memory "flash" + paged = yes; + size = 2048; + page_size = 32; + num_pages = 64; + min_write_delay = 4500; + max_write_delay = 4500; + readback_p1 = 0xff; + readback_p2 = 0xff; + read_lo = " 0 0 1 0 0 0 0 0", + " 0 0 0 0 0 0 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + read_hi = " 0 0 1 0 1 0 0 0", + " 0 0 0 0 0 0 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + loadpage_lo = " 0 1 0 0 0 0 0 0", + " 0 0 0 x x x x x", + " x x x x a3 a2 a1 a0", + " i i i i i i i i"; + + loadpage_hi = " 0 1 0 0 1 0 0 0", + " 0 0 0 x x x x x", + " x x x x a3 a2 a1 a0", + " i i i i i i i i"; + + writepage = " 0 1 0 0 1 1 0 0", + " 0 0 0 0 0 0 a9 a8", + " a7 a6 a5 a4 x x x x", + " x x x x x x x x"; + + mode = 0x41; + delay = 6; + blocksize = 32; + readsize = 256; + ; +# ATtiny25 has Signature Bytes: 0x1E 0x91 0x08. + memory "signature" + size = 3; + read = "0 0 1 1 0 0 0 0 0 0 0 x x x x x", + "x x x x x x a1 a0 o o o o o o o o"; + ; + memory "lock" + size = 1; + write = "1 0 1 0 1 1 0 0 1 1 1 x x x x x", + "x x x x x x x x 1 1 i i i i i i"; + read = "0 1 0 1 1 0 0 0 0 0 0 0 0 0 0 0", + "0 0 0 0 0 0 0 0 o o o o o o o o"; + min_write_delay = 9000; + max_write_delay = 9000; + ; + + memory "lfuse" + size = 1; + write = "1 0 1 0 1 1 0 0 1 0 1 0 0 0 0 0", + "x x x x x x x x i i i i i i i i"; + + read = "0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0", + "x x x x x x x x o o o o o o o o"; + min_write_delay = 9000; + max_write_delay = 9000; + ; + + memory "hfuse" + size = 1; + write = "1 0 1 0 1 1 0 0 1 0 1 0 1 0 0 0", + "x x x x x x x x i i i i i i i i"; + + read = "0 1 0 1 1 0 0 0 0 0 0 0 1 0 0 0", + "x x x x x x x x o o o o o o o o"; + min_write_delay = 9000; + max_write_delay = 9000; + ; + + memory "efuse" + size = 1; + write = "1 0 1 0 1 1 0 0 1 0 1 0 0 1 0 0", + "x x x x x x x x x x x x x x x i"; + + read = "0 1 0 1 0 0 0 0 0 0 0 0 1 0 0 0", + "x x x x x x x x o o o o o o o o"; + min_write_delay = 9000; + max_write_delay = 9000; + ; + + memory "calibration" + size = 1; + read = "0 0 1 1 1 0 0 0 0 0 0 x x x x x", + "0 0 0 0 0 0 0 a0 o o o o o o o o"; + ; + ; + +#------------------------------------------------------------ +# ATtiny45 +#------------------------------------------------------------ + +part + id = "t45"; + desc = "ATtiny45"; + has_debugwire = yes; + flash_instr = 0xB4, 0x02, 0x12; + eeprom_instr = 0xBB, 0xFF, 0xBB, 0xEE, 0xBB, 0xCC, 0xB2, 0x0D, + 0xBC, 0x02, 0xB4, 0x02, 0xBA, 0x0D, 0xBB, 0xBC, + 0x99, 0xE1, 0xBB, 0xAC; + stk500_devcode = 0x14; +## avr910_devcode = ?; +## Try the AT90S2313 devcode: + avr910_devcode = 0x20; + signature = 0x1e 0x92 0x06; + reset = io; + chip_erase_delay = 4500; + + pgm_enable = "1 0 1 0 1 1 0 0 0 1 0 1 0 0 1 1", + "x x x x x x x x x x x x x x x x"; + + chip_erase = "1 0 1 0 1 1 0 0 1 0 0 x x x x x", + "x x x x x x x x x x x x x x x x"; + + timeout = 200; + stabdelay = 100; + cmdexedelay = 25; + synchloops = 32; + bytedelay = 0; + pollindex = 3; + pollvalue = 0x53; + predelay = 1; + postdelay = 1; + pollmethod = 1; + + hvsp_controlstack = + 0x4C, 0x0C, 0x1C, 0x2C, 0x3C, 0x64, 0x74, 0x66, + 0x68, 0x78, 0x68, 0x68, 0x7A, 0x6A, 0x68, 0x78, + 0x78, 0x7D, 0x6D, 0x0C, 0x80, 0x40, 0x20, 0x10, + 0x11, 0x08, 0x04, 0x02, 0x03, 0x08, 0x04, 0x00; + hventerstabdelay = 100; + progmodedelay = 0; + hvspcmdexedelay = 0; + synchcycles = 6; + latchcycles = 1; + togglevtg = 1; + poweroffdelay = 25; + resetdelayms = 1; + resetdelayus = 0; + hvleavestabdelay = 100; + resetdelay = 25; + chiperasepolltimeout = 40; + chiperasetime = 0; + programfusepolltimeout = 25; + programlockpolltimeout = 25; + + ocdrev = 1; + + memory "eeprom" + size = 256; + page_size = 4; + min_write_delay = 4000; + max_write_delay = 4500; + readback_p1 = 0xff; + readback_p2 = 0xff; + read = "1 0 1 0 0 0 0 0 0 0 0 x x x x x", + "a7 a6 a5 a4 a3 a2 a1 a0 o o o o o o o o"; + + write = "1 1 0 0 0 0 0 0 0 0 0 x x x x x", + "a7 a6 a5 a4 a3 a2 a1 a0 i i i i i i i i"; + + loadpage_lo = " 1 1 0 0 0 0 0 1", + " 0 0 0 0 0 0 0 0", + " 0 0 0 0 0 0 a1 a0", + " i i i i i i i i"; + + writepage = " 1 1 0 0 0 0 1 0", + " 0 0 x x x x x x", + " a7 a6 a5 a4 a3 a2 0 0", + " x x x x x x x x"; + + mode = 0x41; + delay = 6; + blocksize = 4; + readsize = 256; + ; + memory "flash" + paged = yes; + size = 4096; + page_size = 64; + num_pages = 64; + min_write_delay = 4500; + max_write_delay = 4500; + readback_p1 = 0xff; + readback_p2 = 0xff; + read_lo = " 0 0 1 0 0 0 0 0", + " 0 0 0 0 0 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + read_hi = " 0 0 1 0 1 0 0 0", + " 0 0 0 0 0 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + loadpage_lo = " 0 1 0 0 0 0 0 0", + " 0 0 0 x x x x x", + " x x x a4 a3 a2 a1 a0", + " i i i i i i i i"; + + loadpage_hi = " 0 1 0 0 1 0 0 0", + " 0 0 0 x x x x x", + " x x x a4 a3 a2 a1 a0", + " i i i i i i i i"; + + writepage = " 0 1 0 0 1 1 0 0", + " 0 0 0 0 0 a10 a9 a8", + " a7 a6 a5 x x x x x", + " x x x x x x x x"; + + mode = 0x41; + delay = 6; + blocksize = 32; + readsize = 256; + ; +# ATtiny45 has Signature Bytes: 0x1E 0x92 0x08. (Data sheet 2586C-AVR-06/05 (doc2586.pdf) indicates otherwise!) + memory "signature" + size = 3; + read = "0 0 1 1 0 0 0 0 0 0 0 x x x x x", + "x x x x x x a1 a0 o o o o o o o o"; + ; + memory "lock" + size = 1; + write = "1 0 1 0 1 1 0 0 1 1 1 x x x x x", + "x x x x x x x x 1 1 i i i i i i"; + read = "0 1 0 1 1 0 0 0 0 0 0 0 0 0 0 0", + "0 0 0 0 0 0 0 0 o o o o o o o o"; + min_write_delay = 9000; + max_write_delay = 9000; + ; + + memory "lfuse" + size = 1; + write = "1 0 1 0 1 1 0 0 1 0 1 0 0 0 0 0", + "x x x x x x x x i i i i i i i i"; + + read = "0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0", + "x x x x x x x x o o o o o o o o"; + min_write_delay = 9000; + max_write_delay = 9000; + ; + + memory "hfuse" + size = 1; + write = "1 0 1 0 1 1 0 0 1 0 1 0 1 0 0 0", + "x x x x x x x x i i i i i i i i"; + + read = "0 1 0 1 1 0 0 0 0 0 0 0 1 0 0 0", + "x x x x x x x x o o o o o o o o"; + min_write_delay = 9000; + max_write_delay = 9000; + ; + + memory "efuse" + size = 1; + write = "1 0 1 0 1 1 0 0 1 0 1 0 0 1 0 0", + "x x x x x x x x x x x x x x x i"; + + read = "0 1 0 1 0 0 0 0 0 0 0 0 1 0 0 0", + "x x x x x x x x o o o o o o o o"; + min_write_delay = 9000; + max_write_delay = 9000; + ; + + memory "calibration" + size = 1; + read = "0 0 1 1 1 0 0 0 0 0 0 x x x x x", + "0 0 0 0 0 0 0 a0 o o o o o o o o"; + ; + ; + +#------------------------------------------------------------ +# ATtiny85 +#------------------------------------------------------------ + +part + id = "t85"; + desc = "ATtiny85"; + has_debugwire = yes; + flash_instr = 0xB4, 0x02, 0x12; + eeprom_instr = 0xBB, 0xFF, 0xBB, 0xEE, 0xBB, 0xCC, 0xB2, 0x0D, + 0xBC, 0x02, 0xB4, 0x02, 0xBA, 0x0D, 0xBB, 0xBC, + 0x99, 0xE1, 0xBB, 0xAC; +## no STK500 devcode in XML file, use the ATtiny45 one + stk500_devcode = 0x14; +## avr910_devcode = ?; +## Try the AT90S2313 devcode: + avr910_devcode = 0x20; + signature = 0x1e 0x93 0x0b; + reset = io; + chip_erase_delay = 4500; + + pgm_enable = "1 0 1 0 1 1 0 0 0 1 0 1 0 0 1 1", + "x x x x x x x x x x x x x x x x"; + + chip_erase = "1 0 1 0 1 1 0 0 1 0 0 x x x x x", + "x x x x x x x x x x x x x x x x"; + + timeout = 200; + stabdelay = 100; + cmdexedelay = 25; + synchloops = 32; + bytedelay = 0; + pollindex = 3; + pollvalue = 0x53; + predelay = 1; + postdelay = 1; + pollmethod = 1; + + hvsp_controlstack = + 0x4C, 0x0C, 0x1C, 0x2C, 0x3C, 0x64, 0x74, 0x66, + 0x68, 0x78, 0x68, 0x68, 0x7A, 0x6A, 0x68, 0x78, + 0x78, 0x7D, 0x6D, 0x0C, 0x80, 0x40, 0x20, 0x10, + 0x11, 0x08, 0x04, 0x02, 0x03, 0x08, 0x04, 0x00; + hventerstabdelay = 100; + hvspcmdexedelay = 0; + synchcycles = 6; + latchcycles = 1; + togglevtg = 1; + poweroffdelay = 25; + resetdelayms = 1; + resetdelayus = 0; + hvleavestabdelay = 100; + resetdelay = 25; + chiperasepolltimeout = 40; + chiperasetime = 0; + programfusepolltimeout = 25; + programlockpolltimeout = 25; + + ocdrev = 1; + + memory "eeprom" + size = 512; + paged = no; + page_size = 4; + min_write_delay = 4000; + max_write_delay = 4500; + readback_p1 = 0xff; + readback_p2 = 0xff; + read = "1 0 1 0 0 0 0 0 0 0 0 x x x x a8", + "a7 a6 a5 a4 a3 a2 a1 a0 o o o o o o o o"; + + write = "1 1 0 0 0 0 0 0 0 0 0 x x x x a8", + "a7 a6 a5 a4 a3 a2 a1 a0 i i i i i i i i"; + + loadpage_lo = " 1 1 0 0 0 0 0 1", + " 0 0 0 0 0 0 0 0", + " 0 0 0 0 0 0 a1 a0", + " i i i i i i i i"; + + writepage = " 1 1 0 0 0 0 1 0", + " 0 0 x x x x x a8", + " a7 a6 a5 a4 a3 a2 0 0", + " x x x x x x x x"; + + mode = 0x41; + delay = 6; + blocksize = 4; + readsize = 256; + ; + memory "flash" + paged = yes; + size = 8192; + page_size = 64; + num_pages = 128; + min_write_delay = 4500; + max_write_delay = 4500; + readback_p1 = 0xff; + readback_p2 = 0xff; + read_lo = " 0 0 1 0 0 0 0 0", + " 0 0 0 0 a11 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + read_hi = " 0 0 1 0 1 0 0 0", + " 0 0 0 0 a11 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + loadpage_lo = " 0 1 0 0 0 0 0 0", + " 0 0 0 x x x x x", + " x x x a4 a3 a2 a1 a0", + " i i i i i i i i"; + + loadpage_hi = " 0 1 0 0 1 0 0 0", + " 0 0 0 x x x x x", + " x x x a4 a3 a2 a1 a0", + " i i i i i i i i"; + + writepage = " 0 1 0 0 1 1 0 0", + " 0 0 0 0 a11 a10 a9 a8", + " a7 a6 a5 x x x x x", + " x x x x x x x x"; + + mode = 0x41; + delay = 6; + blocksize = 32; + readsize = 256; + ; +# ATtiny85 has Signature Bytes: 0x1E 0x93 0x08. + memory "signature" + size = 3; + read = "0 0 1 1 0 0 0 0 0 0 0 x x x x x", + "x x x x x x a1 a0 o o o o o o o o"; + ; + memory "lock" + size = 1; + write = "1 0 1 0 1 1 0 0 1 1 1 x x x x x", + "x x x x x x x x 1 1 i i i i i i"; + read = "0 1 0 1 1 0 0 0 0 0 0 0 0 0 0 0", + "0 0 0 0 0 0 0 0 o o o o o o o o"; + min_write_delay = 9000; + max_write_delay = 9000; + ; + + memory "lfuse" + size = 1; + write = "1 0 1 0 1 1 0 0 1 0 1 0 0 0 0 0", + "x x x x x x x x i i i i i i i i"; + + read = "0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0", + "x x x x x x x x o o o o o o o o"; + min_write_delay = 9000; + max_write_delay = 9000; + ; + + memory "hfuse" + size = 1; + write = "1 0 1 0 1 1 0 0 1 0 1 0 1 0 0 0", + "x x x x x x x x i i i i i i i i"; + + read = "0 1 0 1 1 0 0 0 0 0 0 0 1 0 0 0", + "x x x x x x x x o o o o o o o o"; + min_write_delay = 9000; + max_write_delay = 9000; + ; + + memory "efuse" + size = 1; + write = "1 0 1 0 1 1 0 0 1 0 1 0 0 1 0 0", + "x x x x x x x x x x x x x x x i"; + + read = "0 1 0 1 0 0 0 0 0 0 0 0 1 0 0 0", + "x x x x x x x x o o o o o o o o"; + min_write_delay = 9000; + max_write_delay = 9000; + ; + + memory "calibration" + size = 1; + read = "0 0 1 1 1 0 0 0 0 0 0 x x x x x", + "0 0 0 0 0 0 0 a0 o o o o o o o o"; + ; + ; + +#------------------------------------------------------------ +# ATmega640 +#------------------------------------------------------------ +# Almost same as ATmega1280, except for different memory sizes + +part + id = "m640"; + desc = "ATmega640"; + signature = 0x1e 0x96 0x08; + has_jtag = yes; +# stk500_devcode = 0xB2; +# avr910_devcode = 0x43; + chip_erase_delay = 9000; + pagel = 0xD7; + bs2 = 0xA0; + reset = dedicated; + pgm_enable = "1 0 1 0 1 1 0 0 0 1 0 1 0 0 1 1", + "x x x x x x x x x x x x x x x x"; + + chip_erase = "1 0 1 0 1 1 0 0 1 0 0 0 0 0 0 0", + "x x x x x x x x x x x x x x x x"; + + timeout = 200; + stabdelay = 100; + cmdexedelay = 25; + synchloops = 32; + bytedelay = 0; + pollindex = 3; + pollvalue = 0x53; + predelay = 1; + postdelay = 1; + pollmethod = 1; + + pp_controlstack = + 0x0E, 0x1E, 0x0F, 0x1F, 0x2E, 0x3E, 0x2F, 0x3F, + 0x4E, 0x5E, 0x4F, 0x5F, 0x6E, 0x7E, 0x6F, 0x7F, + 0x66, 0x76, 0x67, 0x77, 0x6A, 0x7A, 0x6B, 0x7B, + 0xBE, 0xFD, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00; + hventerstabdelay = 100; + progmodedelay = 0; + latchcycles = 5; + togglevtg = 1; + poweroffdelay = 15; + resetdelayms = 1; + resetdelayus = 0; + hvleavestabdelay = 15; + chiperasepulsewidth = 0; + chiperasepolltimeout = 10; + programfusepulsewidth = 0; + programfusepolltimeout = 5; + programlockpulsewidth = 0; + programlockpolltimeout = 5; + + idr = 0x31; + spmcr = 0x57; + rampz = 0x3b; + allowfullpagebitstream = no; + + ocdrev = 3; + + memory "eeprom" + paged = no; /* leave this "no" */ + page_size = 8; /* for parallel programming */ + size = 4096; + min_write_delay = 9000; + max_write_delay = 9000; + readback_p1 = 0x00; + readback_p2 = 0x00; + read = " 1 0 1 0 0 0 0 0", + " x x x x a11 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + write = " 1 1 0 0 0 0 0 0", + " x x x x a11 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " i i i i i i i i"; + + loadpage_lo = " 1 1 0 0 0 0 0 1", + " 0 0 0 0 0 0 0 0", + " 0 0 0 0 0 a2 a1 a0", + " i i i i i i i i"; + + writepage = " 1 1 0 0 0 0 1 0", + " 0 0 x x a11 a10 a9 a8", + " a7 a6 a5 a4 a3 0 0 0", + " x x x x x x x x"; + + mode = 0x41; + delay = 10; + blocksize = 8; + readsize = 256; + ; + + memory "flash" + paged = yes; + size = 65536; + page_size = 256; + num_pages = 256; + min_write_delay = 4500; + max_write_delay = 4500; + readback_p1 = 0x00; + readback_p2 = 0x00; + read_lo = " 0 0 1 0 0 0 0 0", + " 0 a14 a13 a12 a11 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + read_hi = " 0 0 1 0 1 0 0 0", + " 0 a14 a13 a12 a11 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + loadpage_lo = " 0 1 0 0 0 0 0 0", + " x x x x x x x x", + " x a6 a5 a4 a3 a2 a1 a0", + " i i i i i i i i"; + + loadpage_hi = " 0 1 0 0 1 0 0 0", + " x x x x x x x x", + " x a6 a5 a4 a3 a2 a1 a0", + " i i i i i i i i"; + + writepage = " 0 1 0 0 1 1 0 0", + " 0 a14 a13 a12 a11 a10 a9 a8", + " a7 x x x x x x x", + " x x x x x x x x"; + + mode = 0x41; + delay = 10; + blocksize = 256; + readsize = 256; + ; + + memory "lfuse" + size = 1; + write = "1 0 1 0 1 1 0 0 1 0 1 0 0 0 0 0", + "x x x x x x x x i i i i i i i i"; + + read = "0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0", + "x x x x x x x x o o o o o o o o"; + min_write_delay = 9000; + max_write_delay = 9000; + ; + + memory "hfuse" + size = 1; + write = "1 0 1 0 1 1 0 0 1 0 1 0 1 0 0 0", + "x x x x x x x x i i i i i i i i"; + + read = "0 1 0 1 1 0 0 0 0 0 0 0 1 0 0 0", + "x x x x x x x x o o o o o o o o"; + min_write_delay = 9000; + max_write_delay = 9000; + ; + + memory "efuse" + size = 1; + write = "1 0 1 0 1 1 0 0 1 0 1 0 0 1 0 0", + "x x x x x x x x x x x x x i i i"; + + read = "0 1 0 1 0 0 0 0 0 0 0 0 1 0 0 0", + "x x x x x x x x o o o o o o o o"; + min_write_delay = 9000; + max_write_delay = 9000; + ; + + memory "lock" + size = 1; + read = "0 1 0 1 1 0 0 0 0 0 0 0 0 0 0 0", + "x x x x x x x x x x o o o o o o"; + + write = "1 0 1 0 1 1 0 0 1 1 1 x x x x x", + "x x x x x x x x 1 1 i i i i i i"; + min_write_delay = 9000; + max_write_delay = 9000; + ; + + memory "calibration" + size = 1; + read = "0 0 1 1 1 0 0 0 x x x x x x x x", + "0 0 0 0 0 0 0 0 o o o o o o o o"; + ; + + memory "signature" + size = 3; + read = "0 0 1 1 0 0 0 0 x x x x x x x x", + "x x x x x x a1 a0 o o o o o o o o"; + ; + ; + +#------------------------------------------------------------ +# ATmega1280 +#------------------------------------------------------------ + +part + id = "m1280"; + desc = "ATmega1280"; + signature = 0x1e 0x97 0x03; + has_jtag = yes; +# stk500_devcode = 0xB2; +# avr910_devcode = 0x43; + chip_erase_delay = 9000; + pagel = 0xD7; + bs2 = 0xA0; + reset = dedicated; + pgm_enable = "1 0 1 0 1 1 0 0 0 1 0 1 0 0 1 1", + "x x x x x x x x x x x x x x x x"; + + chip_erase = "1 0 1 0 1 1 0 0 1 0 0 0 0 0 0 0", + "x x x x x x x x x x x x x x x x"; + + timeout = 200; + stabdelay = 100; + cmdexedelay = 25; + synchloops = 32; + bytedelay = 0; + pollindex = 3; + pollvalue = 0x53; + predelay = 1; + postdelay = 1; + pollmethod = 1; + + pp_controlstack = + 0x0E, 0x1E, 0x0F, 0x1F, 0x2E, 0x3E, 0x2F, 0x3F, + 0x4E, 0x5E, 0x4F, 0x5F, 0x6E, 0x7E, 0x6F, 0x7F, + 0x66, 0x76, 0x67, 0x77, 0x6A, 0x7A, 0x6B, 0x7B, + 0xBE, 0xFD, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00; + hventerstabdelay = 100; + progmodedelay = 0; + latchcycles = 5; + togglevtg = 1; + poweroffdelay = 15; + resetdelayms = 1; + resetdelayus = 0; + hvleavestabdelay = 15; + chiperasepulsewidth = 0; + chiperasepolltimeout = 10; + programfusepulsewidth = 0; + programfusepolltimeout = 5; + programlockpulsewidth = 0; + programlockpolltimeout = 5; + + idr = 0x31; + spmcr = 0x57; + rampz = 0x3b; + allowfullpagebitstream = no; + + ocdrev = 3; + + memory "eeprom" + paged = no; /* leave this "no" */ + page_size = 8; /* for parallel programming */ + size = 4096; + min_write_delay = 9000; + max_write_delay = 9000; + readback_p1 = 0x00; + readback_p2 = 0x00; + read = " 1 0 1 0 0 0 0 0", + " x x x x a11 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + write = " 1 1 0 0 0 0 0 0", + " x x x x a11 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " i i i i i i i i"; + + loadpage_lo = " 1 1 0 0 0 0 0 1", + " 0 0 0 0 0 0 0 0", + " 0 0 0 0 0 a2 a1 a0", + " i i i i i i i i"; + + writepage = " 1 1 0 0 0 0 1 0", + " 0 0 x x a11 a10 a9 a8", + " a7 a6 a5 a4 a3 0 0 0", + " x x x x x x x x"; + + mode = 0x41; + delay = 10; + blocksize = 8; + readsize = 256; + ; + + memory "flash" + paged = yes; + size = 131072; + page_size = 256; + num_pages = 512; + min_write_delay = 4500; + max_write_delay = 4500; + readback_p1 = 0x00; + readback_p2 = 0x00; + read_lo = " 0 0 1 0 0 0 0 0", + "a15 a14 a13 a12 a11 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + read_hi = " 0 0 1 0 1 0 0 0", + "a15 a14 a13 a12 a11 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + loadpage_lo = " 0 1 0 0 0 0 0 0", + " x x x x x x x x", + " x a6 a5 a4 a3 a2 a1 a0", + " i i i i i i i i"; + + loadpage_hi = " 0 1 0 0 1 0 0 0", + " x x x x x x x x", + " x a6 a5 a4 a3 a2 a1 a0", + " i i i i i i i i"; + + writepage = " 0 1 0 0 1 1 0 0", + "a15 a14 a13 a12 a11 a10 a9 a8", + " a7 x x x x x x x", + " x x x x x x x x"; + + mode = 0x41; + delay = 10; + blocksize = 256; + readsize = 256; + ; + + memory "lfuse" + size = 1; + write = "1 0 1 0 1 1 0 0 1 0 1 0 0 0 0 0", + "x x x x x x x x i i i i i i i i"; + + read = "0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0", + "x x x x x x x x o o o o o o o o"; + min_write_delay = 9000; + max_write_delay = 9000; + ; + + memory "hfuse" + size = 1; + write = "1 0 1 0 1 1 0 0 1 0 1 0 1 0 0 0", + "x x x x x x x x i i i i i i i i"; + + read = "0 1 0 1 1 0 0 0 0 0 0 0 1 0 0 0", + "x x x x x x x x o o o o o o o o"; + min_write_delay = 9000; + max_write_delay = 9000; + ; + + memory "efuse" + size = 1; + write = "1 0 1 0 1 1 0 0 1 0 1 0 0 1 0 0", + "x x x x x x x x x x x x x i i i"; + + read = "0 1 0 1 0 0 0 0 0 0 0 0 1 0 0 0", + "x x x x x x x x o o o o o o o o"; + min_write_delay = 9000; + max_write_delay = 9000; + ; + + memory "lock" + size = 1; + read = "0 1 0 1 1 0 0 0 0 0 0 0 0 0 0 0", + "x x x x x x x x x x o o o o o o"; + + write = "1 0 1 0 1 1 0 0 1 1 1 x x x x x", + "x x x x x x x x 1 1 i i i i i i"; + min_write_delay = 9000; + max_write_delay = 9000; + ; + + memory "calibration" + size = 1; + read = "0 0 1 1 1 0 0 0 x x x x x x x x", + "0 0 0 0 0 0 0 0 o o o o o o o o"; + ; + + memory "signature" + size = 3; + read = "0 0 1 1 0 0 0 0 x x x x x x x x", + "x x x x x x a1 a0 o o o o o o o o"; + ; + ; + +#------------------------------------------------------------ +# ATmega1281 +#------------------------------------------------------------ +# Identical to ATmega1280 + +part parent "m1280" + id = "m1281"; + desc = "ATmega1281"; + signature = 0x1e 0x97 0x04; + + ocdrev = 3; + ; + +#------------------------------------------------------------ +# ATmega2560 +#------------------------------------------------------------ + +part + id = "m2560"; + desc = "ATmega2560"; + signature = 0x1e 0x98 0x01; + has_jtag = yes; + stk500_devcode = 0xB2; +# avr910_devcode = 0x43; + chip_erase_delay = 9000; + pagel = 0xD7; + bs2 = 0xA0; + reset = dedicated; + pgm_enable = "1 0 1 0 1 1 0 0 0 1 0 1 0 0 1 1", + "x x x x x x x x x x x x x x x x"; + + chip_erase = "1 0 1 0 1 1 0 0 1 0 0 0 0 0 0 0", + "x x x x x x x x x x x x x x x x"; + + timeout = 200; + stabdelay = 100; + cmdexedelay = 25; + synchloops = 32; + bytedelay = 0; + pollindex = 3; + pollvalue = 0x53; + predelay = 1; + postdelay = 1; + pollmethod = 1; + + pp_controlstack = + 0x0E, 0x1E, 0x0F, 0x1F, 0x2E, 0x3E, 0x2F, 0x3F, + 0x4E, 0x5E, 0x4F, 0x5F, 0x6E, 0x7E, 0x6F, 0x7F, + 0x66, 0x76, 0x67, 0x77, 0x6A, 0x7A, 0x6B, 0x7B, + 0xBE, 0xFD, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02; + hventerstabdelay = 100; + progmodedelay = 0; + latchcycles = 5; + togglevtg = 1; + poweroffdelay = 15; + resetdelayms = 1; + resetdelayus = 0; + hvleavestabdelay = 15; + chiperasepulsewidth = 0; + chiperasepolltimeout = 10; + programfusepulsewidth = 0; + programfusepolltimeout = 5; + programlockpulsewidth = 0; + programlockpolltimeout = 5; + + idr = 0x31; + spmcr = 0x57; + rampz = 0x3b; + allowfullpagebitstream = no; + + ocdrev = 4; + + memory "eeprom" + paged = no; /* leave this "no" */ + page_size = 8; /* for parallel programming */ + size = 4096; + min_write_delay = 9000; + max_write_delay = 9000; + readback_p1 = 0x00; + readback_p2 = 0x00; + read = " 1 0 1 0 0 0 0 0", + " x x x x a11 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + write = " 1 1 0 0 0 0 0 0", + " x x x x a11 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " i i i i i i i i"; + + loadpage_lo = " 1 1 0 0 0 0 0 1", + " 0 0 0 0 0 0 0 0", + " 0 0 0 0 0 a2 a1 a0", + " i i i i i i i i"; + + writepage = " 1 1 0 0 0 0 1 0", + " 0 0 x x a11 a10 a9 a8", + " a7 a6 a5 a4 a3 0 0 0", + " x x x x x x x x"; + + mode = 0x41; + delay = 10; + blocksize = 8; + readsize = 256; + ; + + memory "flash" + paged = yes; + size = 262144; + page_size = 256; + num_pages = 1024; + min_write_delay = 4500; + max_write_delay = 4500; + readback_p1 = 0x00; + readback_p2 = 0x00; + read_lo = " 0 0 1 0 0 0 0 0", + "a15 a14 a13 a12 a11 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + read_hi = " 0 0 1 0 1 0 0 0", + "a15 a14 a13 a12 a11 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + loadpage_lo = " 0 1 0 0 0 0 0 0", + " x x x x x x x x", + " x a6 a5 a4 a3 a2 a1 a0", + " i i i i i i i i"; + + loadpage_hi = " 0 1 0 0 1 0 0 0", + " x x x x x x x x", + " x a6 a5 a4 a3 a2 a1 a0", + " i i i i i i i i"; + + writepage = " 0 1 0 0 1 1 0 0", + "a15 a14 a13 a12 a11 a10 a9 a8", + " a7 x x x x x x x", + " x x x x x x x x"; + + load_ext_addr = " 0 1 0 0 1 1 0 1", + " 0 0 0 0 0 0 0 0", + " 0 0 0 0 0 0 0 a16", + " 0 0 0 0 0 0 0 0"; + + mode = 0x41; + delay = 10; + blocksize = 256; + readsize = 256; + ; + + memory "lfuse" + size = 1; + write = "1 0 1 0 1 1 0 0 1 0 1 0 0 0 0 0", + "x x x x x x x x i i i i i i i i"; + + read = "0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0", + "x x x x x x x x o o o o o o o o"; + min_write_delay = 9000; + max_write_delay = 9000; + ; + + memory "hfuse" + size = 1; + write = "1 0 1 0 1 1 0 0 1 0 1 0 1 0 0 0", + "x x x x x x x x i i i i i i i i"; + + read = "0 1 0 1 1 0 0 0 0 0 0 0 1 0 0 0", + "x x x x x x x x o o o o o o o o"; + min_write_delay = 9000; + max_write_delay = 9000; + ; + + memory "efuse" + size = 1; + write = "1 0 1 0 1 1 0 0 1 0 1 0 0 1 0 0", + "x x x x x x x x x x x x x i i i"; + + read = "0 1 0 1 0 0 0 0 0 0 0 0 1 0 0 0", + "x x x x x x x x o o o o o o o o"; + min_write_delay = 9000; + max_write_delay = 9000; + ; + + memory "lock" + size = 1; + read = "0 1 0 1 1 0 0 0 0 0 0 0 0 0 0 0", + "x x x x x x x x x x o o o o o o"; + + write = "1 0 1 0 1 1 0 0 1 1 1 x x x x x", + "x x x x x x x x 1 1 i i i i i i"; + min_write_delay = 9000; + max_write_delay = 9000; + ; + + memory "calibration" + size = 1; + read = "0 0 1 1 1 0 0 0 x x x x x x x x", + "0 0 0 0 0 0 0 0 o o o o o o o o"; + ; + + memory "signature" + size = 3; + read = "0 0 1 1 0 0 0 0 x x x x x x x x", + "x x x x x x a1 a0 o o o o o o o o"; + ; + ; + +#------------------------------------------------------------ +# ATmega2561 +#------------------------------------------------------------ + +part parent "m2560" + id = "m2561"; + desc = "ATmega2561"; + signature = 0x1e 0x98 0x02; + + ocdrev = 4; + ; + +#------------------------------------------------------------ +# ATmega128RFA1 +#------------------------------------------------------------ +# Identical to ATmega2561 but half the ROM + +part parent "m2561" + id = "m128rfa1"; + desc = "ATmega128RFA1"; + signature = 0x1e 0xa7 0x01; + chip_erase_delay = 55000; + bs2 = 0xE2; + + ocdrev = 3; + + memory "flash" + paged = yes; + size = 131072; + page_size = 256; + num_pages = 512; + min_write_delay = 50000; + max_write_delay = 50000; + readback_p1 = 0x00; + readback_p2 = 0x00; + read_lo = " 0 0 1 0 0 0 0 0", + "a15 a14 a13 a12 a11 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + read_hi = " 0 0 1 0 1 0 0 0", + "a15 a14 a13 a12 a11 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + loadpage_lo = " 0 1 0 0 0 0 0 0", + " x x x x x x x x", + " x a6 a5 a4 a3 a2 a1 a0", + " i i i i i i i i"; + + loadpage_hi = " 0 1 0 0 1 0 0 0", + " x x x x x x x x", + " x a6 a5 a4 a3 a2 a1 a0", + " i i i i i i i i"; + + writepage = " 0 1 0 0 1 1 0 0", + "a15 a14 a13 a12 a11 a10 a9 a8", + " a7 x x x x x x x", + " x x x x x x x x"; + + mode = 0x41; + delay = 20; + blocksize = 256; + readsize = 256; + ; + ; + +#------------------------------------------------------------ +# ATmega256RFR2 +#------------------------------------------------------------ + +part parent "m2561" + id = "m256rfr2"; + desc = "ATmega256RFR2"; + signature = 0x1e 0xa8 0x02; + chip_erase_delay = 18500; + bs2 = 0xE2; + + memory "eeprom" + paged = no; /* leave this "no" */ + page_size = 8; /* for parallel programming */ + size = 8192; + min_write_delay = 13000; + max_write_delay = 13000; + readback_p1 = 0x00; + readback_p2 = 0x00; + read = " 1 0 1 0 0 0 0 0", + " x x x a12 a11 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + write = " 1 1 0 0 0 0 0 0", + " x x x a12 a11 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " i i i i i i i i"; + + loadpage_lo = " 1 1 0 0 0 0 0 1", + " 0 0 0 0 0 0 0 0", + " 0 0 0 0 0 a2 a1 a0", + " i i i i i i i i"; + + writepage = " 1 1 0 0 0 0 1 0", + " 0 0 x a12 a11 a10 a9 a8", + " a7 a6 a5 a4 a3 0 0 0", + " x x x x x x x x"; + + mode = 0x41; + delay = 10; + blocksize = 8; + readsize = 256; + ; + + + ocdrev = 4; + ; + +#------------------------------------------------------------ +# ATmega128RFR2 +#------------------------------------------------------------ + +part parent "m128rfa1" + id = "m128rfr2"; + desc = "ATmega128RFR2"; + signature = 0x1e 0xa7 0x02; + + + ocdrev = 3; + ; + +#------------------------------------------------------------ +# ATmega64RFR2 +#------------------------------------------------------------ + +part parent "m128rfa1" + id = "m64rfr2"; + desc = "ATmega64RFR2"; + signature = 0x1e 0xa6 0x02; + + + ocdrev = 3; + + memory "flash" + paged = yes; + size = 65536; + page_size = 256; + num_pages = 256; + min_write_delay = 50000; + max_write_delay = 50000; + readback_p1 = 0x00; + readback_p2 = 0x00; + read_lo = " 0 0 1 0 0 0 0 0", + " 0 a14 a13 a12 a11 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + read_hi = " 0 0 1 0 1 0 0 0", + " 0 a14 a13 a12 a11 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + loadpage_lo = " 0 1 0 0 0 0 0 0", + " x x x x x x x x", + " x a6 a5 a4 a3 a2 a1 a0", + " i i i i i i i i"; + + loadpage_hi = " 0 1 0 0 1 0 0 0", + " x x x x x x x x", + " x a6 a5 a4 a3 a2 a1 a0", + " i i i i i i i i"; + + writepage = " 0 1 0 0 1 1 0 0", + " 0 a14 a13 a12 a11 a10 a9 a8", + " a7 x x x x x x x", + " x x x x x x x x"; + + mode = 0x41; + delay = 20; + blocksize = 256; + readsize = 256; + ; + + memory "eeprom" + paged = no; /* leave this "no" */ + page_size = 8; /* for parallel programming */ + size = 2048; + min_write_delay = 13000; + max_write_delay = 13000; + readback_p1 = 0x00; + readback_p2 = 0x00; + read = " 1 0 1 0 0 0 0 0", + " x x x x x a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + write = " 1 1 0 0 0 0 0 0", + " x x x x x a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " i i i i i i i i"; + + loadpage_lo = " 1 1 0 0 0 0 0 1", + " 0 0 0 0 0 0 0 0", + " 0 0 0 0 0 a2 a1 a0", + " i i i i i i i i"; + + writepage = " 1 1 0 0 0 0 1 0", + " 0 0 x x x a10 a9 a8", + " a7 a6 a5 a4 a3 0 0 0", + " x x x x x x x x"; + + mode = 0x41; + delay = 10; + blocksize = 8; + readsize = 256; + ; + + + ; + +#------------------------------------------------------------ +# ATmega2564RFR2 +#------------------------------------------------------------ + +part parent "m256rfr2" + id = "m2564rfr2"; + desc = "ATmega2564RFR2"; + signature = 0x1e 0xa8 0x03; + ; + +#------------------------------------------------------------ +# ATmega1284RFR2 +#------------------------------------------------------------ + +part parent "m128rfr2" + id = "m1284rfr2"; + desc = "ATmega1284RFR2"; + signature = 0x1e 0xa7 0x03; + ; + +#------------------------------------------------------------ +# ATmega644RFR2 +#------------------------------------------------------------ + +part parent "m64rfr2" + id = "m644rfr2"; + desc = "ATmega644RFR2"; + signature = 0x1e 0xa6 0x03; + ; + +#------------------------------------------------------------ +# ATtiny24 +#------------------------------------------------------------ + +part + id = "t24"; + desc = "ATtiny24"; + has_debugwire = yes; + flash_instr = 0xB4, 0x07, 0x17; + eeprom_instr = 0xBB, 0xFF, 0xBB, 0xEE, 0xBB, 0xCC, 0xB2, 0x0D, + 0xBC, 0x07, 0xB4, 0x07, 0xBA, 0x0D, 0xBB, 0xBC, + 0x99, 0xE1, 0xBB, 0xAC; +## no STK500 devcode in XML file, use the ATtiny45 one + stk500_devcode = 0x14; +## avr910_devcode = ?; +## Try the AT90S2313 devcode: + avr910_devcode = 0x20; + signature = 0x1e 0x91 0x0b; + reset = io; + chip_erase_delay = 4500; + + pgm_enable = "1 0 1 0 1 1 0 0 0 1 0 1 0 0 1 1", + "x x x x x x x x x x x x x x x x"; + + chip_erase = "1 0 1 0 1 1 0 0 1 0 0 x x x x x", + "x x x x x x x x x x x x x x x x"; + + timeout = 200; + stabdelay = 100; + cmdexedelay = 25; + synchloops = 32; + bytedelay = 0; + pollindex = 3; + pollvalue = 0x53; + predelay = 1; + postdelay = 1; + pollmethod = 1; + + hvsp_controlstack = + 0x4C, 0x0C, 0x1C, 0x2C, 0x3C, 0x64, 0x74, 0x66, + 0x68, 0x78, 0x68, 0x68, 0x7A, 0x6A, 0x68, 0x78, + 0x78, 0x7D, 0x6D, 0x0C, 0x80, 0x40, 0x20, 0x10, + 0x11, 0x08, 0x04, 0x02, 0x03, 0x08, 0x04, 0x0F; + hventerstabdelay = 100; + hvspcmdexedelay = 0; + synchcycles = 6; + latchcycles = 1; + togglevtg = 1; + poweroffdelay = 25; + resetdelayms = 0; + resetdelayus = 70; + hvleavestabdelay = 100; + resetdelay = 25; + chiperasepolltimeout = 40; + chiperasetime = 0; + programfusepolltimeout = 25; + programlockpolltimeout = 25; + + ocdrev = 1; + + memory "eeprom" + size = 128; + paged = no; + page_size = 4; + min_write_delay = 4000; + max_write_delay = 4500; + readback_p1 = 0xff; + readback_p2 = 0xff; + read = "1 0 1 0 0 0 0 0 0 0 0 x x x x x", + "x a6 a5 a4 a3 a2 a1 a0 o o o o o o o o"; + + write = "1 1 0 0 0 0 0 0 0 0 0 x x x x x", + "x a6 a5 a4 a3 a2 a1 a0 i i i i i i i i"; + + loadpage_lo = " 1 1 0 0 0 0 0 1", + " 0 0 0 0 0 0 0 0", + " 0 0 0 0 0 0 a1 a0", + " i i i i i i i i"; + + writepage = " 1 1 0 0 0 0 1 0", + " 0 0 x x x x x x", + " x a6 a5 a4 a3 a2 0 0", + " x x x x x x x x"; + + mode = 0x41; + delay = 6; + blocksize = 4; + readsize = 256; + ; + memory "flash" + paged = yes; + size = 2048; + page_size = 32; + num_pages = 64; + min_write_delay = 4500; + max_write_delay = 4500; + readback_p1 = 0xff; + readback_p2 = 0xff; + read_lo = " 0 0 1 0 0 0 0 0", + " 0 0 0 0 0 0 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + read_hi = " 0 0 1 0 1 0 0 0", + " 0 0 0 0 0 0 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + loadpage_lo = " 0 1 0 0 0 0 0 0", + " 0 0 0 x x x x x", + " x x x x a3 a2 a1 a0", + " i i i i i i i i"; + + loadpage_hi = " 0 1 0 0 1 0 0 0", + " 0 0 0 x x x x x", + " x x x x a3 a2 a1 a0", + " i i i i i i i i"; + + writepage = " 0 1 0 0 1 1 0 0", + " 0 0 0 0 0 0 a9 a8", + " a7 a6 a5 a4 x x x x", + " x x x x x x x x"; + + mode = 0x41; + delay = 6; + blocksize = 32; + readsize = 256; + ; +# ATtiny24 has Signature Bytes: 0x1E 0x91 0x0B. + memory "signature" + size = 3; + read = "0 0 1 1 0 0 0 0 0 0 0 x x x x x", + "x x x x x x a1 a0 o o o o o o o o"; + ; + memory "lock" + size = 1; + write = "1 0 1 0 1 1 0 0 1 1 1 x x x x x", + "x x x x x x x x x x x x x x i i"; + read = "0 1 0 1 1 0 0 0 0 0 0 0 0 0 0 0", + "0 0 0 0 0 0 0 0 o o o o o o o o"; + min_write_delay = 9000; + max_write_delay = 9000; + ; + + memory "lfuse" + size = 1; + write = "1 0 1 0 1 1 0 0 1 0 1 0 0 0 0 0", + "x x x x x x x x i i i i i i i i"; + + read = "0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0", + "x x x x x x x x o o o o o o o o"; + min_write_delay = 9000; + max_write_delay = 9000; + ; + + memory "hfuse" + size = 1; + write = "1 0 1 0 1 1 0 0 1 0 1 0 1 0 0 0", + "x x x x x x x x i i i i i i i i"; + + read = "0 1 0 1 1 0 0 0 0 0 0 0 1 0 0 0", + "x x x x x x x x o o o o o o o o"; + min_write_delay = 9000; + max_write_delay = 9000; + ; + + memory "efuse" + size = 1; + write = "1 0 1 0 1 1 0 0 1 0 1 0 0 1 0 0", + "x x x x x x x x x x x x x x x i"; + + read = "0 1 0 1 0 0 0 0 0 0 0 0 1 0 0 0", + "x x x x x x x x o o o o o o o o"; + min_write_delay = 9000; + max_write_delay = 9000; + ; + + memory "calibration" + size = 1; + read = "0 0 1 1 1 0 0 0 0 0 0 x x x x x", + "0 0 0 0 0 0 0 a0 o o o o o o o o"; + ; + ; + +#------------------------------------------------------------ +# ATtiny44 +#------------------------------------------------------------ + +part + id = "t44"; + desc = "ATtiny44"; + has_debugwire = yes; + flash_instr = 0xB4, 0x07, 0x17; + eeprom_instr = 0xBB, 0xFF, 0xBB, 0xEE, 0xBB, 0xCC, 0xB2, 0x0D, + 0xBC, 0x07, 0xB4, 0x07, 0xBA, 0x0D, 0xBB, 0xBC, + 0x99, 0xE1, 0xBB, 0xAC; +## no STK500 devcode in XML file, use the ATtiny45 one + stk500_devcode = 0x14; +## avr910_devcode = ?; +## Try the AT90S2313 devcode: + avr910_devcode = 0x20; + signature = 0x1e 0x92 0x07; + reset = io; + chip_erase_delay = 4500; + + pgm_enable = "1 0 1 0 1 1 0 0 0 1 0 1 0 0 1 1", + "x x x x x x x x x x x x x x x x"; + + chip_erase = "1 0 1 0 1 1 0 0 1 0 0 x x x x x", + "x x x x x x x x x x x x x x x x"; + + timeout = 200; + stabdelay = 100; + cmdexedelay = 25; + synchloops = 32; + bytedelay = 0; + pollindex = 3; + pollvalue = 0x53; + predelay = 1; + postdelay = 1; + pollmethod = 1; + + hvsp_controlstack = + 0x4C, 0x0C, 0x1C, 0x2C, 0x3C, 0x64, 0x74, 0x66, + 0x68, 0x78, 0x68, 0x68, 0x7A, 0x6A, 0x68, 0x78, + 0x78, 0x7D, 0x6D, 0x0C, 0x80, 0x40, 0x20, 0x10, + 0x11, 0x08, 0x04, 0x02, 0x03, 0x08, 0x04, 0x0F; + hventerstabdelay = 100; + hvspcmdexedelay = 0; + synchcycles = 6; + latchcycles = 1; + togglevtg = 1; + poweroffdelay = 25; + resetdelayms = 0; + resetdelayus = 70; + hvleavestabdelay = 100; + resetdelay = 25; + chiperasepolltimeout = 40; + chiperasetime = 0; + programfusepolltimeout = 25; + programlockpolltimeout = 25; + + ocdrev = 1; + + memory "eeprom" + size = 256; + paged = no; + page_size = 4; + min_write_delay = 4000; + max_write_delay = 4500; + readback_p1 = 0xff; + readback_p2 = 0xff; + read = "1 0 1 0 0 0 0 0 0 0 0 x x x x x", + "a7 a6 a5 a4 a3 a2 a1 a0 o o o o o o o o"; + + write = "1 1 0 0 0 0 0 0 0 0 0 x x x x x", + "a7 a6 a5 a4 a3 a2 a1 a0 i i i i i i i i"; + + loadpage_lo = " 1 1 0 0 0 0 0 1", + " 0 0 0 0 0 0 0 0", + " 0 0 0 0 0 0 a1 a0", + " i i i i i i i i"; + + writepage = " 1 1 0 0 0 0 1 0", + " 0 0 x x x x x x", + " x a6 a5 a4 a3 a2 0 0", + " x x x x x x x x"; + + mode = 0x41; + delay = 6; + blocksize = 4; + readsize = 256; + ; + memory "flash" + paged = yes; + size = 4096; + page_size = 64; + num_pages = 64; + min_write_delay = 4500; + max_write_delay = 4500; + readback_p1 = 0xff; + readback_p2 = 0xff; + read_lo = " 0 0 1 0 0 0 0 0", + " 0 0 0 0 0 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + read_hi = " 0 0 1 0 1 0 0 0", + " 0 0 0 0 0 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + loadpage_lo = " 0 1 0 0 0 0 0 0", + " 0 0 0 x x x x x", + " x x x a4 a3 a2 a1 a0", + " i i i i i i i i"; + + loadpage_hi = " 0 1 0 0 1 0 0 0", + " 0 0 0 x x x x x", + " x x x a4 a3 a2 a1 a0", + " i i i i i i i i"; + + writepage = " 0 1 0 0 1 1 0 0", + " 0 0 0 0 0 a10 a9 a8", + " a7 a6 a5 x x x x x", + " x x x x x x x x"; + + mode = 0x41; + delay = 6; + blocksize = 32; + readsize = 256; + ; +# ATtiny44 has Signature Bytes: 0x1E 0x92 0x07. + memory "signature" + size = 3; + read = "0 0 1 1 0 0 0 0 0 0 0 x x x x x", + "x x x x x x a1 a0 o o o o o o o o"; + ; + memory "lock" + size = 1; + write = "1 0 1 0 1 1 0 0 1 1 1 x x x x x", + "x x x x x x x x x x x x x x i i"; + read = "0 1 0 1 1 0 0 0 0 0 0 0 0 0 0 0", + "0 0 0 0 0 0 0 0 o o o o o o o o"; + min_write_delay = 9000; + max_write_delay = 9000; + ; + + memory "lfuse" + size = 1; + write = "1 0 1 0 1 1 0 0 1 0 1 0 0 0 0 0", + "x x x x x x x x i i i i i i i i"; + + read = "0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0", + "x x x x x x x x o o o o o o o o"; + min_write_delay = 9000; + max_write_delay = 9000; + ; + + memory "hfuse" + size = 1; + write = "1 0 1 0 1 1 0 0 1 0 1 0 1 0 0 0", + "x x x x x x x x i i i i i i i i"; + + read = "0 1 0 1 1 0 0 0 0 0 0 0 1 0 0 0", + "x x x x x x x x o o o o o o o o"; + min_write_delay = 9000; + max_write_delay = 9000; + ; + + memory "efuse" + size = 1; + write = "1 0 1 0 1 1 0 0 1 0 1 0 0 1 0 0", + "x x x x x x x x x x x x x x x i"; + + read = "0 1 0 1 0 0 0 0 0 0 0 0 1 0 0 0", + "x x x x x x x x o o o o o o o o"; + min_write_delay = 9000; + max_write_delay = 9000; + ; + + memory "calibration" + size = 1; + read = "0 0 1 1 1 0 0 0 0 0 0 x x x x x", + "0 0 0 0 0 0 0 a0 o o o o o o o o"; + ; + ; + +#------------------------------------------------------------ +# ATtiny84 +#------------------------------------------------------------ + +part + id = "t84"; + desc = "ATtiny84"; + has_debugwire = yes; + flash_instr = 0xB4, 0x07, 0x17; + eeprom_instr = 0xBB, 0xFF, 0xBB, 0xEE, 0xBB, 0xCC, 0xB2, 0x0D, + 0xBC, 0x07, 0xB4, 0x07, 0xBA, 0x0D, 0xBB, 0xBC, + 0x99, 0xE1, 0xBB, 0xAC; +## no STK500 devcode in XML file, use the ATtiny45 one + stk500_devcode = 0x14; +## avr910_devcode = ?; +## Try the AT90S2313 devcode: + avr910_devcode = 0x20; + signature = 0x1e 0x93 0x0c; + reset = io; + chip_erase_delay = 4500; + + pgm_enable = "1 0 1 0 1 1 0 0 0 1 0 1 0 0 1 1", + "x x x x x x x x x x x x x x x x"; + + chip_erase = "1 0 1 0 1 1 0 0 1 0 0 x x x x x", + "x x x x x x x x x x x x x x x x"; + + timeout = 200; + stabdelay = 100; + cmdexedelay = 25; + synchloops = 32; + bytedelay = 0; + pollindex = 3; + pollvalue = 0x53; + predelay = 1; + postdelay = 1; + pollmethod = 1; + + hvsp_controlstack = + 0x4C, 0x0C, 0x1C, 0x2C, 0x3C, 0x64, 0x74, 0x66, + 0x68, 0x78, 0x68, 0x68, 0x7A, 0x6A, 0x68, 0x78, + 0x78, 0x7D, 0x6D, 0x0C, 0x80, 0x40, 0x20, 0x10, + 0x11, 0x08, 0x04, 0x02, 0x03, 0x08, 0x04, 0x0F; + hventerstabdelay = 100; + hvspcmdexedelay = 0; + synchcycles = 6; + latchcycles = 1; + togglevtg = 1; + poweroffdelay = 25; + resetdelayms = 0; + resetdelayus = 70; + hvleavestabdelay = 100; + resetdelay = 25; + chiperasepolltimeout = 40; + chiperasetime = 0; + programfusepolltimeout = 25; + programlockpolltimeout = 25; + + ocdrev = 1; + + memory "eeprom" + size = 512; + paged = no; + page_size = 4; + min_write_delay = 4000; + max_write_delay = 4500; + readback_p1 = 0xff; + readback_p2 = 0xff; + read = "1 0 1 0 0 0 0 0 0 0 0 x x x x a8", + "a7 a6 a5 a4 a3 a2 a1 a0 o o o o o o o o"; + + write = "1 1 0 0 0 0 0 0 0 0 0 x x x x a8", + "a7 a6 a5 a4 a3 a2 a1 a0 i i i i i i i i"; + + loadpage_lo = " 1 1 0 0 0 0 0 1", + " 0 0 0 0 0 0 0 0", + " 0 0 0 0 0 0 a1 a0", + " i i i i i i i i"; + + writepage = " 1 1 0 0 0 0 1 0", + " 0 0 x x x x x x", + " x a6 a5 a4 a3 a2 0 0", + " x x x x x x x x"; + + mode = 0x41; + delay = 6; + blocksize = 4; + readsize = 256; + ; + memory "flash" + paged = yes; + size = 8192; + page_size = 64; + num_pages = 128; + min_write_delay = 4500; + max_write_delay = 4500; + readback_p1 = 0xff; + readback_p2 = 0xff; + read_lo = " 0 0 1 0 0 0 0 0", + " 0 0 0 0 a11 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + read_hi = " 0 0 1 0 1 0 0 0", + " 0 0 0 0 a11 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + loadpage_lo = " 0 1 0 0 0 0 0 0", + " 0 0 0 x x x x x", + " x x x a4 a3 a2 a1 a0", + " i i i i i i i i"; + + loadpage_hi = " 0 1 0 0 1 0 0 0", + " 0 0 0 x x x x x", + " x x x a4 a3 a2 a1 a0", + " i i i i i i i i"; + + writepage = " 0 1 0 0 1 1 0 0", + " 0 0 0 0 a11 a10 a9 a8", + " a7 a6 a5 x x x x x", + " x x x x x x x x"; + + mode = 0x41; + delay = 6; + blocksize = 32; + readsize = 256; + ; +# ATtiny84 has Signature Bytes: 0x1E 0x93 0x0C. + memory "signature" + size = 3; + read = "0 0 1 1 0 0 0 0 0 0 0 x x x x x", + "x x x x x x a1 a0 o o o o o o o o"; + ; + + memory "lock" + size = 1; + write = "1 0 1 0 1 1 0 0 1 1 1 x x x x x", + "x x x x x x x x x x x x x x i i"; + read = "0 1 0 1 1 0 0 0 0 0 0 0 0 0 0 0", + "0 0 0 0 0 0 0 0 o o o o o o o o"; + min_write_delay = 9000; + max_write_delay = 9000; + ; + + memory "lfuse" + size = 1; + write = "1 0 1 0 1 1 0 0 1 0 1 0 0 0 0 0", + "x x x x x x x x i i i i i i i i"; + + read = "0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0", + "x x x x x x x x o o o o o o o o"; + min_write_delay = 9000; + max_write_delay = 9000; + ; + + memory "hfuse" + size = 1; + write = "1 0 1 0 1 1 0 0 1 0 1 0 1 0 0 0", + "x x x x x x x x i i i i i i i i"; + + read = "0 1 0 1 1 0 0 0 0 0 0 0 1 0 0 0", + "x x x x x x x x o o o o o o o o"; + min_write_delay = 9000; + max_write_delay = 9000; + ; + + memory "efuse" + size = 1; + write = "1 0 1 0 1 1 0 0 1 0 1 0 0 1 0 0", + "x x x x x x x x x x x x x x x i"; + + read = "0 1 0 1 0 0 0 0 0 0 0 0 1 0 0 0", + "x x x x x x x x o o o o o o o o"; + min_write_delay = 9000; + max_write_delay = 9000; + ; + + memory "calibration" + size = 1; + read = "0 0 1 1 1 0 0 0 0 0 0 x x x x x", + "0 0 0 0 0 0 0 a0 o o o o o o o o"; + ; + ; + +#------------------------------------------------------------ +# ATtiny43U +#------------------------------------------------------------ + +part + id = "t43u"; + desc = "ATtiny43u"; + has_debugwire = yes; + flash_instr = 0xB4, 0x07, 0x17; + eeprom_instr = 0xBB, 0xFF, 0xBB, 0xEE, 0xBB, 0xCC, 0xB2, 0x0D, + 0xBC, 0x07, 0xB4, 0x07, 0xBA, 0x0D, 0xBB, 0xBC, + 0x99, 0xE1, 0xBB, 0xAC; + stk500_devcode = 0x14; +## avr910_devcode = ?; +## Try the AT90S2313 devcode: + avr910_devcode = 0x20; + signature = 0x1e 0x92 0x0C; + reset = io; + chip_erase_delay = 1000; + + pgm_enable = "1 0 1 0 1 1 0 0 0 1 0 1 0 0 1 1", + "x x x x x x x x x x x x x x x x"; + + chip_erase = "1 0 1 0 1 1 0 0 1 0 0 x x x x x", + "x x x x x x x x x x x x x x x x"; + + timeout = 200; + stabdelay = 100; + cmdexedelay = 25; + synchloops = 32; + bytedelay = 0; + pollindex = 3; + pollvalue = 0x53; + predelay = 1; + postdelay = 1; + pollmethod = 1; + pp_controlstack = 0x0E, 0x1E, 0x0E, 0x1E, 0x2E, 0x3E, 0x2E, 0x3E, 0x4E, 0x5E, + 0x4E, 0x5E, 0x6E, 0x7E, 0x6E, 0x7E, 0x06, 0x16, 0x46, 0x56, + 0x0A, 0x1A, 0x4A, 0x5A, 0x1E, 0x7C, 0x00, 0x01, 0x00, 0x00, + 0x00, 0x00; + hventerstabdelay = 100; + progmodedelay = 0; + hvspcmdexedelay = 0; + latchcycles = 5; + togglevtg = 1; + poweroffdelay = 20; + resetdelayms = 1; + resetdelayus = 0; + hvleavestabdelay = 15; + resetdelay = 15; + chiperasepulsewidth = 0; + chiperasepolltimeout = 10; + programfusepulsewidth = 0; + programfusepolltimeout = 5; + programlockpulsewidth = 0; + programlockpolltimeout = 5; + memory "eeprom" + size = 64; + paged = yes; + page_size = 4; + num_pages = 16; + min_write_delay = 4000; + max_write_delay = 4500; + readback_p1 = 0xff; + readback_p2 = 0xff; + read = "1 0 1 0 0 0 0 0 0 0 0 x x x x x", + "0 0 a4 a3 a2 a1 a0 o o o o o o o o"; + + write = "1 1 0 0 0 0 0 0 0 0 0 x x x x x", + "0 0 a5 a4 a3 a2 a1 a0 i i i i i i i i"; + + loadpage_lo = " 1 1 0 0 0 0 0 1", + " 0 0 0 0 0 0 0 0", + " 0 0 0 0 0 0 a1 a0", + " i i i i i i i i"; + + writepage = " 1 1 0 0 0 0 1 0", + " 0 0 x x x x x x", + " 0 0 a5 a4 a3 a2 0 0", + " x x x x x x x x"; + + mode = 0x41; + delay = 5; + blocksize = 4; + readsize = 256; + ; + memory "flash" + paged = yes; + size = 4096; + page_size = 64; + num_pages = 64; + min_write_delay = 4500; + max_write_delay = 4500; + readback_p1 = 0xff; + readback_p2 = 0xff; + + read_lo = " 0 0 1 0 0 0 0 0", + " 0 0 0 0 0 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + read_hi = " 0 0 1 0 1 0 0 0", + " 0 0 0 0 0 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + loadpage_lo = " 0 1 0 0 0 0 0 0", + " 0 0 0 x x x x x", + " x x x a4 a3 a2 a1 a0", + " i i i i i i i i"; + + loadpage_hi = " 0 1 0 0 1 0 0 0", + " 0 0 0 x x x x x", + " x x x a4 a3 a2 a1 a0", + " i i i i i i i i"; + + writepage = " 0 1 0 0 1 1 0 0", + " 0 0 0 0 0 a10 a9 a8", + " a7 a6 a5 x x x x x", + " x x x x x x x x"; + + mode = 0x41; + delay = 10; + blocksize = 64; + readsize = 256; + ; + memory "signature" + size = 3; + read = "0 0 1 1 0 0 0 0 0 0 0 x x x x x", + "x x x x x x a1 a0 o o o o o o o o"; + ; + memory "lock" + size = 1; + write = "1 0 1 0 1 1 0 0 1 1 1 x x x x x", + "x x x x x x x x 1 1 i i i i i i"; + min_write_delay = 4500; + max_write_delay = 4500; + ; + + memory "lfuse" + size = 1; + write = "1 0 1 0 1 1 0 0 1 0 1 0 0 0 0 0", + "x x x x x x x x i i i i i i i i"; + + read = "0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0", + "x x x x x x x x o o o o o o o o"; + min_write_delay = 4500; + max_write_delay = 4500; + ; + + memory "hfuse" + size = 1; + write = "1 0 1 0 1 1 0 0 1 0 1 0 1 0 0 0", + "x x x x x x x x i i i i i i i i"; + + read = "0 1 0 1 1 0 0 0 0 0 0 0 1 0 0 0", + "x x x x x x x x o o o o o o o o"; + min_write_delay = 4500; + max_write_delay = 4500; + ; + + memory "efuse" + size = 1; + write = "1 0 1 0 1 1 0 0 1 0 1 0 0 1 0 0", + "x x x x x x x x x x x x x x x i"; + + read = "0 1 0 1 0 0 0 0 0 0 0 0 1 0 0 0", + "x x x x x x x x o o o o o o o o"; + min_write_delay = 4500; + max_write_delay = 4500; + ; + + memory "calibration" + size = 2; + read = "0 0 1 1 1 0 0 0 0 0 0 x x x x x", + "0 0 0 0 0 0 0 a0 o o o o o o o o"; + ; +; + +#------------------------------------------------------------ +# ATmega32u4 +#------------------------------------------------------------ + +part + id = "m32u4"; + desc = "ATmega32U4"; + signature = 0x1e 0x95 0x87; + usbpid = 0x2ff4; + has_jtag = yes; +# stk500_devcode = 0xB2; +# avr910_devcode = 0x43; + chip_erase_delay = 9000; + pagel = 0xD7; + bs2 = 0xA0; + reset = dedicated; + pgm_enable = "1 0 1 0 1 1 0 0 0 1 0 1 0 0 1 1", + "x x x x x x x x x x x x x x x x"; + + chip_erase = "1 0 1 0 1 1 0 0 1 0 0 0 0 0 0 0", + "x x x x x x x x x x x x x x x x"; + + timeout = 200; + stabdelay = 100; + cmdexedelay = 25; + synchloops = 32; + bytedelay = 0; + pollindex = 3; + pollvalue = 0x53; + predelay = 1; + postdelay = 1; + pollmethod = 1; + + pp_controlstack = + 0x0E, 0x1E, 0x0F, 0x1F, 0x2E, 0x3E, 0x2F, 0x3F, + 0x4E, 0x5E, 0x4F, 0x5F, 0x6E, 0x7E, 0x6F, 0x7F, + 0x66, 0x76, 0x67, 0x77, 0x6A, 0x7A, 0x6B, 0x7B, + 0xBE, 0xFD, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00; + hventerstabdelay = 100; + progmodedelay = 0; + latchcycles = 5; + togglevtg = 1; + poweroffdelay = 15; + resetdelayms = 1; + resetdelayus = 0; + hvleavestabdelay = 15; + chiperasepulsewidth = 0; + chiperasepolltimeout = 10; + programfusepulsewidth = 0; + programfusepolltimeout = 5; + programlockpulsewidth = 0; + programlockpolltimeout = 5; + + idr = 0x31; + spmcr = 0x57; + rampz = 0x3b; + allowfullpagebitstream = no; + + ocdrev = 3; + + memory "eeprom" + paged = no; /* leave this "no" */ + page_size = 4; /* for parallel programming */ + size = 1024; + min_write_delay = 9000; + max_write_delay = 9000; + readback_p1 = 0x00; + readback_p2 = 0x00; + read = " 1 0 1 0 0 0 0 0", + " x x x x x a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + write = " 1 1 0 0 0 0 0 0", + " x x x x x a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " i i i i i i i i"; + + loadpage_lo = " 1 1 0 0 0 0 0 1", + " 0 0 0 0 0 0 0 0", + " 0 0 0 0 0 a2 a1 a0", + " i i i i i i i i"; + + writepage = " 1 1 0 0 0 0 1 0", + " 0 0 x x x a10 a9 a8", + " a7 a6 a5 a4 a3 0 0 0", + " x x x x x x x x"; + + mode = 0x41; + delay = 20; + blocksize = 4; + readsize = 256; + ; + + memory "flash" + paged = yes; + size = 32768; + page_size = 128; + num_pages = 256; + min_write_delay = 4500; + max_write_delay = 4500; + readback_p1 = 0x00; + readback_p2 = 0x00; + read_lo = " 0 0 1 0 0 0 0 0", + " 0 a14 a13 a12 a11 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + read_hi = " 0 0 1 0 1 0 0 0", + " 0 a14 a13 a12 a11 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + loadpage_lo = " 0 1 0 0 0 0 0 0", + " x x x x x x x x", + " x x a5 a4 a3 a2 a1 a0", + " i i i i i i i i"; + + loadpage_hi = " 0 1 0 0 1 0 0 0", + " x x x x x x x x", + " x x a5 a4 a3 a2 a1 a0", + " i i i i i i i i"; + + writepage = " 0 1 0 0 1 1 0 0", + " a15 a14 a13 a12 a11 a10 a9 a8", + " a7 a6 x x x x x x", + " x x x x x x x x"; + + mode = 0x41; + delay = 6; + blocksize = 128; + readsize = 256; + ; + + memory "lfuse" + size = 1; + write = "1 0 1 0 1 1 0 0 1 0 1 0 0 0 0 0", + "x x x x x x x x i i i i i i i i"; + + read = "0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0", + "x x x x x x x x o o o o o o o o"; + min_write_delay = 9000; + max_write_delay = 9000; + ; + + memory "hfuse" + size = 1; + write = "1 0 1 0 1 1 0 0 1 0 1 0 1 0 0 0", + "x x x x x x x x i i i i i i i i"; + + read = "0 1 0 1 1 0 0 0 0 0 0 0 1 0 0 0", + "x x x x x x x x o o o o o o o o"; + min_write_delay = 9000; + max_write_delay = 9000; + ; + + memory "efuse" + size = 1; + write = "1 0 1 0 1 1 0 0 1 0 1 0 0 1 0 0", + "x x x x x x x x x x x x i i i i"; + + read = "0 1 0 1 0 0 0 0 0 0 0 0 1 0 0 0", + "x x x x x x x x o o o o o o o o"; + min_write_delay = 9000; + max_write_delay = 9000; + ; + + memory "lock" + size = 1; + read = "0 1 0 1 1 0 0 0 0 0 0 0 0 0 0 0", + "x x x x x x x x x x o o o o o o"; + + write = "1 0 1 0 1 1 0 0 1 1 1 x x x x x", + "x x x x x x x x 1 1 i i i i i i"; + min_write_delay = 9000; + max_write_delay = 9000; + ; + + memory "calibration" + size = 1; + read = "0 0 1 1 1 0 0 0 x x x x x x x x", + "0 0 0 0 0 0 0 0 o o o o o o o o"; + ; + + memory "signature" + size = 3; + read = "0 0 1 1 0 0 0 0 x x x x x x x x", + "x x x x x x a1 a0 o o o o o o o o"; + ; + ; + +#------------------------------------------------------------ +# AT90USB646 +#------------------------------------------------------------ + +part + id = "usb646"; + desc = "AT90USB646"; + signature = 0x1e 0x96 0x82; + usbpid = 0x2ff9; + has_jtag = yes; +# stk500_devcode = 0xB2; +# avr910_devcode = 0x43; + chip_erase_delay = 9000; + pagel = 0xD7; + bs2 = 0xA0; + reset = dedicated; + pgm_enable = "1 0 1 0 1 1 0 0 0 1 0 1 0 0 1 1", + "x x x x x x x x x x x x x x x x"; + + chip_erase = "1 0 1 0 1 1 0 0 1 0 0 0 0 0 0 0", + "x x x x x x x x x x x x x x x x"; + + timeout = 200; + stabdelay = 100; + cmdexedelay = 25; + synchloops = 32; + bytedelay = 0; + pollindex = 3; + pollvalue = 0x53; + predelay = 1; + postdelay = 1; + pollmethod = 1; + + pp_controlstack = + 0x0E, 0x1E, 0x0F, 0x1F, 0x2E, 0x3E, 0x2F, 0x3F, + 0x4E, 0x5E, 0x4F, 0x5F, 0x6E, 0x7E, 0x6F, 0x7F, + 0x66, 0x76, 0x67, 0x77, 0x6A, 0x7A, 0x6B, 0x7B, + 0xBE, 0xFD, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00; + hventerstabdelay = 100; + progmodedelay = 0; + latchcycles = 5; + togglevtg = 1; + poweroffdelay = 15; + resetdelayms = 1; + resetdelayus = 0; + hvleavestabdelay = 15; + chiperasepulsewidth = 0; + chiperasepolltimeout = 10; + programfusepulsewidth = 0; + programfusepolltimeout = 5; + programlockpulsewidth = 0; + programlockpolltimeout = 5; + + idr = 0x31; + spmcr = 0x57; + rampz = 0x3b; + allowfullpagebitstream = no; + + ocdrev = 3; + + memory "eeprom" + paged = no; /* leave this "no" */ + page_size = 8; /* for parallel programming */ + size = 2048; + min_write_delay = 9000; + max_write_delay = 9000; + readback_p1 = 0x00; + readback_p2 = 0x00; + read = " 1 0 1 0 0 0 0 0", + " x x x x x a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + write = " 1 1 0 0 0 0 0 0", + " x x x x x a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " i i i i i i i i"; + + loadpage_lo = " 1 1 0 0 0 0 0 1", + " 0 0 0 0 0 0 0 0", + " 0 0 0 0 0 a2 a1 a0", + " i i i i i i i i"; + + writepage = " 1 1 0 0 0 0 1 0", + " 0 0 x x x a10 a9 a8", + " a7 a6 a5 a4 a3 0 0 0", + " x x x x x x x x"; + + mode = 0x41; + delay = 10; + blocksize = 8; + readsize = 256; + ; + + memory "flash" + paged = yes; + size = 65536; + page_size = 256; + num_pages = 256; + min_write_delay = 4500; + max_write_delay = 4500; + readback_p1 = 0x00; + readback_p2 = 0x00; + read_lo = " 0 0 1 0 0 0 0 0", + " 0 a14 a13 a12 a11 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + read_hi = " 0 0 1 0 1 0 0 0", + " 0 a14 a13 a12 a11 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + loadpage_lo = " 0 1 0 0 0 0 0 0", + " x x x x x x x x", + " x a6 a5 a4 a3 a2 a1 a0", + " i i i i i i i i"; + + loadpage_hi = " 0 1 0 0 1 0 0 0", + " x x x x x x x x", + " x a6 a5 a4 a3 a2 a1 a0", + " i i i i i i i i"; + + writepage = " 0 1 0 0 1 1 0 0", + " 0 a14 a13 a12 a11 a10 a9 a8", + " a7 x x x x x x x", + " x x x x x x x x"; + + mode = 0x41; + delay = 6; + blocksize = 256; + readsize = 256; + ; + + memory "lfuse" + size = 1; + write = "1 0 1 0 1 1 0 0 1 0 1 0 0 0 0 0", + "x x x x x x x x i i i i i i i i"; + + read = "0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0", + "x x x x x x x x o o o o o o o o"; + min_write_delay = 9000; + max_write_delay = 9000; + ; + + memory "hfuse" + size = 1; + write = "1 0 1 0 1 1 0 0 1 0 1 0 1 0 0 0", + "x x x x x x x x i i i i i i i i"; + + read = "0 1 0 1 1 0 0 0 0 0 0 0 1 0 0 0", + "x x x x x x x x o o o o o o o o"; + min_write_delay = 9000; + max_write_delay = 9000; + ; + + memory "efuse" + size = 1; + write = "1 0 1 0 1 1 0 0 1 0 1 0 0 1 0 0", + "x x x x x x x x x x x x i i i i"; + + read = "0 1 0 1 0 0 0 0 0 0 0 0 1 0 0 0", + "x x x x x x x x o o o o o o o o"; + min_write_delay = 9000; + max_write_delay = 9000; + ; + + memory "lock" + size = 1; + read = "0 1 0 1 1 0 0 0 0 0 0 0 0 0 0 0", + "x x x x x x x x x x o o o o o o"; + + write = "1 0 1 0 1 1 0 0 1 1 1 x x x x x", + "x x x x x x x x 1 1 i i i i i i"; + min_write_delay = 9000; + max_write_delay = 9000; + ; + + memory "calibration" + size = 1; + read = "0 0 1 1 1 0 0 0 x x x x x x x x", + "0 0 0 0 0 0 0 0 o o o o o o o o"; + ; + + memory "signature" + size = 3; + read = "0 0 1 1 0 0 0 0 x x x x x x x x", + "x x x x x x a1 a0 o o o o o o o o"; + ; + ; + +#------------------------------------------------------------ +# AT90USB647 +#------------------------------------------------------------ +# identical to AT90USB646 + +part parent "usb646" + id = "usb647"; + desc = "AT90USB647"; + signature = 0x1e 0x96 0x82; + + ocdrev = 3; + ; + +#------------------------------------------------------------ +# AT90USB1286 +#------------------------------------------------------------ + +part + id = "usb1286"; + desc = "AT90USB1286"; + signature = 0x1e 0x97 0x82; + usbpid = 0x2ffb; + has_jtag = yes; +# stk500_devcode = 0xB2; +# avr910_devcode = 0x43; + chip_erase_delay = 9000; + pagel = 0xD7; + bs2 = 0xA0; + reset = dedicated; + pgm_enable = "1 0 1 0 1 1 0 0 0 1 0 1 0 0 1 1", + "x x x x x x x x x x x x x x x x"; + + chip_erase = "1 0 1 0 1 1 0 0 1 0 0 0 0 0 0 0", + "x x x x x x x x x x x x x x x x"; + + timeout = 200; + stabdelay = 100; + cmdexedelay = 25; + synchloops = 32; + bytedelay = 0; + pollindex = 3; + pollvalue = 0x53; + predelay = 1; + postdelay = 1; + pollmethod = 1; + + pp_controlstack = + 0x0E, 0x1E, 0x0F, 0x1F, 0x2E, 0x3E, 0x2F, 0x3F, + 0x4E, 0x5E, 0x4F, 0x5F, 0x6E, 0x7E, 0x6F, 0x7F, + 0x66, 0x76, 0x67, 0x77, 0x6A, 0x7A, 0x6B, 0x7B, + 0xBE, 0xFD, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00; + hventerstabdelay = 100; + progmodedelay = 0; + latchcycles = 5; + togglevtg = 1; + poweroffdelay = 15; + resetdelayms = 1; + resetdelayus = 0; + hvleavestabdelay = 15; + chiperasepulsewidth = 0; + chiperasepolltimeout = 10; + programfusepulsewidth = 0; + programfusepolltimeout = 5; + programlockpulsewidth = 0; + programlockpolltimeout = 5; + + idr = 0x31; + spmcr = 0x57; + rampz = 0x3b; + allowfullpagebitstream = no; + + ocdrev = 3; + + memory "eeprom" + paged = no; /* leave this "no" */ + page_size = 8; /* for parallel programming */ + size = 4096; + min_write_delay = 9000; + max_write_delay = 9000; + readback_p1 = 0x00; + readback_p2 = 0x00; + read = " 1 0 1 0 0 0 0 0", + " x x x x a11 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + write = " 1 1 0 0 0 0 0 0", + " x x x x a11 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " i i i i i i i i"; + + loadpage_lo = " 1 1 0 0 0 0 0 1", + " 0 0 0 0 0 0 0 0", + " 0 0 0 0 0 a2 a1 a0", + " i i i i i i i i"; + + writepage = " 1 1 0 0 0 0 1 0", + " 0 0 x x x a10 a9 a8", + " a7 a6 a5 a4 a3 0 0 0", + " x x x x x x x x"; + + mode = 0x41; + delay = 10; + blocksize = 8; + readsize = 256; + ; + + memory "flash" + paged = yes; + size = 131072; + page_size = 256; + num_pages = 512; + min_write_delay = 4500; + max_write_delay = 4500; + readback_p1 = 0x00; + readback_p2 = 0x00; + read_lo = " 0 0 1 0 0 0 0 0", + "a15 a14 a13 a12 a11 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + read_hi = " 0 0 1 0 1 0 0 0", + "a15 a14 a13 a12 a11 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + loadpage_lo = " 0 1 0 0 0 0 0 0", + " x x x x x x x x", + " x a6 a5 a4 a3 a2 a1 a0", + " i i i i i i i i"; + + loadpage_hi = " 0 1 0 0 1 0 0 0", + " x x x x x x x x", + " x a6 a5 a4 a3 a2 a1 a0", + " i i i i i i i i"; + + writepage = " 0 1 0 0 1 1 0 0", + "a15 a14 a13 a12 a11 a10 a9 a8", + " a7 x x x x x x x", + " x x x x x x x x"; + + mode = 0x41; + delay = 6; + blocksize = 256; + readsize = 256; + ; + + memory "lfuse" + size = 1; + write = "1 0 1 0 1 1 0 0 1 0 1 0 0 0 0 0", + "x x x x x x x x i i i i i i i i"; + + read = "0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0", + "x x x x x x x x o o o o o o o o"; + min_write_delay = 9000; + max_write_delay = 9000; + ; + + memory "hfuse" + size = 1; + write = "1 0 1 0 1 1 0 0 1 0 1 0 1 0 0 0", + "x x x x x x x x i i i i i i i i"; + + read = "0 1 0 1 1 0 0 0 0 0 0 0 1 0 0 0", + "x x x x x x x x o o o o o o o o"; + min_write_delay = 9000; + max_write_delay = 9000; + ; + + memory "efuse" + size = 1; + write = "1 0 1 0 1 1 0 0 1 0 1 0 0 1 0 0", + "x x x x x x x x x x x x i i i i"; + + read = "0 1 0 1 0 0 0 0 0 0 0 0 1 0 0 0", + "x x x x x x x x o o o o o o o o"; + min_write_delay = 9000; + max_write_delay = 9000; + ; + + memory "lock" + size = 1; + read = "0 1 0 1 1 0 0 0 0 0 0 0 0 0 0 0", + "x x x x x x x x x x o o o o o o"; + + write = "1 0 1 0 1 1 0 0 1 1 1 x x x x x", + "x x x x x x x x 1 1 i i i i i i"; + min_write_delay = 9000; + max_write_delay = 9000; + ; + + memory "calibration" + size = 1; + read = "0 0 1 1 1 0 0 0 x x x x x x x x", + "0 0 0 0 0 0 0 0 o o o o o o o o"; + ; + + memory "signature" + size = 3; + read = "0 0 1 1 0 0 0 0 x x x x x x x x", + "x x x x x x a1 a0 o o o o o o o o"; + ; + ; + +#------------------------------------------------------------ +# AT90USB1287 +#------------------------------------------------------------ +# identical to AT90USB1286 + +part parent "usb1286" + id = "usb1287"; + desc = "AT90USB1287"; + signature = 0x1e 0x97 0x82; + + ocdrev = 3; + ; + +#------------------------------------------------------------ +# AT90USB162 +#------------------------------------------------------------ + +part + id = "usb162"; + desc = "AT90USB162"; + has_jtag = no; + has_debugwire = yes; + signature = 0x1e 0x94 0x82; + usbpid = 0x2ffa; + chip_erase_delay = 9000; + reset = io; + pgm_enable = "1 0 1 0 1 1 0 0 0 1 0 1 0 0 1 1", + "x x x x x x x x x x x x x x x x"; + chip_erase = "1 0 1 0 1 1 0 0 1 0 0 x x x x x", + "x x x x x x x x x x x x x x x x"; + pagel = 0xD7; + bs2 = 0xC6; + + timeout = 200; + stabdelay = 100; + cmdexedelay = 25; + synchloops = 32; + bytedelay = 0; + pollindex = 3; + pollvalue = 0x53; + predelay = 1; + postdelay = 1; + pollmethod = 1; + pp_controlstack = + 0x0E, 0x1E, 0x0F, 0x1F, 0x2E, 0x3E, 0x2F, 0x3F, + 0x4E, 0x5E, 0x4F, 0x5F, 0x6E, 0x7E, 0x6F, 0x7F, + 0x66, 0x76, 0x67, 0x77, 0x6A, 0x7A, 0x6B, 0x7B, + 0xBE, 0xFD, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00; + hventerstabdelay = 100; + progmodedelay = 0; + latchcycles = 5; + togglevtg = 1; + poweroffdelay = 15; + resetdelayms = 1; + resetdelayus = 0; + hvleavestabdelay = 15; + chiperasepulsewidth = 0; + chiperasepolltimeout = 10; + programfusepulsewidth = 0; + programfusepolltimeout = 5; + programlockpulsewidth = 0; + programlockpolltimeout = 5; + + ocdrev = 1; + + memory "eeprom" + paged = no; /* leave this "no" */ + page_size = 4; /* for parallel programming */ + size = 512; + num_pages = 128; + min_write_delay = 9000; + max_write_delay = 9000; + readback_p1 = 0x00; + readback_p2 = 0x00; + read = " 1 0 1 0 0 0 0 0", + " 0 0 0 0 a11 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + write = " 1 1 0 0 0 0 0 0", + " 0 0 0 0 a11 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " i i i i i i i i"; + + loadpage_lo = " 1 1 0 0 0 0 0 1", + " 0 0 0 0 0 0 0 0", + " 0 0 0 0 0 0 a1 a0", + " i i i i i i i i"; + + writepage = " 1 1 0 0 0 0 1 0", + " 0 0 0 0 a11 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 0 0", + " x x x x x x x x"; + + mode = 0x41; + delay = 20; + blocksize = 4; + readsize = 256; + ; + + memory "flash" + paged = yes; + size = 16384; + page_size = 128; + num_pages = 128; + min_write_delay = 4500; + max_write_delay = 4500; + readback_p1 = 0x00; + readback_p2 = 0x00; + read_lo = " 0 0 1 0 0 0 0 0", + "a15 a14 a13 a12 a11 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + read_hi = " 0 0 1 0 1 0 0 0", + "a15 a14 a13 a12 a11 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + loadpage_lo = " 0 1 0 0 0 0 0 0", + " x x x x x x x x", + " x x a5 a4 a3 a2 a1 a0", + " i i i i i i i i"; + + loadpage_hi = " 0 1 0 0 1 0 0 0", + " x x x x x x x x", + " x x a5 a4 a3 a2 a1 a0", + " i i i i i i i i"; + + writepage = " 0 1 0 0 1 1 0 0", + "a15 a14 a13 a12 a11 a10 a9 a8", + " a7 a6 x x x x x x", + " x x x x x x x x"; + + mode = 0x41; + delay = 6; + blocksize = 128; + readsize = 256; + ; + + memory "lfuse" + size = 1; + write = "1 0 1 0 1 1 0 0 1 0 1 0 0 0 0 0", + "x x x x x x x x i i i i i i i i"; + + read = "0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0", + "x x x x x x x x o o o o o o o o"; + min_write_delay = 9000; + max_write_delay = 9000; + ; + + memory "hfuse" + size = 1; + write = "1 0 1 0 1 1 0 0 1 0 1 0 1 0 0 0", + "x x x x x x x x i i i i i i i i"; + + read = "0 1 0 1 1 0 0 0 0 0 0 0 1 0 0 0", + "x x x x x x x x o o o o o o o o"; + min_write_delay = 9000; + max_write_delay = 9000; + ; + + memory "efuse" + size = 1; + write = "1 0 1 0 1 1 0 0 1 0 1 0 0 1 0 0", + "x x x x x x x x i i i i i i i i"; + + read = "0 1 0 1 0 0 0 0 0 0 0 0 1 0 0 0", + "x x x x x x x x o o o o o o o o"; + min_write_delay = 9000; + max_write_delay = 9000; + ; + + memory "lock" + size = 1; + read = "0 1 0 1 1 0 0 0 0 0 0 0 0 0 0 0", + "x x x x x x x x x x o o o o o o"; + + write = "1 0 1 0 1 1 0 0 1 1 1 x x x x x", + "x x x x x x x x 1 1 i i i i i i"; + min_write_delay = 9000; + max_write_delay = 9000; + ; + + memory "calibration" + size = 1; + read = "0 0 1 1 1 0 0 0 0 0 0 x x x x x", + "0 0 0 0 0 0 0 0 o o o o o o o o"; + ; + memory "signature" + size = 3; + read = "0 0 1 1 0 0 0 0 0 0 0 x x x x x", + "x x x x x x a1 a0 o o o o o o o o"; + ; + ; + +#------------------------------------------------------------ +# AT90USB82 +#------------------------------------------------------------ +# Changes against AT90USB162 (beside IDs) +# memory "flash" +# size = 8192; +# num_pages = 64; + +part + id = "usb82"; + desc = "AT90USB82"; + has_jtag = no; + has_debugwire = yes; + signature = 0x1e 0x93 0x82; + usbpid = 0x2ff7; + chip_erase_delay = 9000; + reset = io; + pgm_enable = "1 0 1 0 1 1 0 0 0 1 0 1 0 0 1 1", + "x x x x x x x x x x x x x x x x"; + chip_erase = "1 0 1 0 1 1 0 0 1 0 0 x x x x x", + "x x x x x x x x x x x x x x x x"; + pagel = 0xD7; + bs2 = 0xC6; + + timeout = 200; + stabdelay = 100; + cmdexedelay = 25; + synchloops = 32; + bytedelay = 0; + pollindex = 3; + pollvalue = 0x53; + predelay = 1; + postdelay = 1; + pollmethod = 1; + pp_controlstack = + 0x0E, 0x1E, 0x0F, 0x1F, 0x2E, 0x3E, 0x2F, 0x3F, + 0x4E, 0x5E, 0x4F, 0x5F, 0x6E, 0x7E, 0x6F, 0x7F, + 0x66, 0x76, 0x67, 0x77, 0x6A, 0x7A, 0x6B, 0x7B, + 0xBE, 0xFD, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00; + hventerstabdelay = 100; + progmodedelay = 0; + latchcycles = 5; + togglevtg = 1; + poweroffdelay = 15; + resetdelayms = 1; + resetdelayus = 0; + hvleavestabdelay = 15; + chiperasepulsewidth = 0; + chiperasepolltimeout = 10; + programfusepulsewidth = 0; + programfusepolltimeout = 5; + programlockpulsewidth = 0; + programlockpolltimeout = 5; + + ocdrev = 1; + + memory "eeprom" + paged = no; /* leave this "no" */ + page_size = 4; /* for parallel programming */ + size = 512; + num_pages = 128; + min_write_delay = 9000; + max_write_delay = 9000; + readback_p1 = 0x00; + readback_p2 = 0x00; + read = " 1 0 1 0 0 0 0 0", + " 0 0 0 0 a11 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + write = " 1 1 0 0 0 0 0 0", + " 0 0 0 0 a11 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " i i i i i i i i"; + + loadpage_lo = " 1 1 0 0 0 0 0 1", + " 0 0 0 0 0 0 0 0", + " 0 0 0 0 0 0 a1 a0", + " i i i i i i i i"; + + writepage = " 1 1 0 0 0 0 1 0", + " 0 0 0 0 a11 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 0 0", + " x x x x x x x x"; + + mode = 0x41; + delay = 20; + blocksize = 4; + readsize = 256; + ; + + memory "flash" + paged = yes; + size = 8192; + page_size = 128; + num_pages = 64; + min_write_delay = 4500; + max_write_delay = 4500; + readback_p1 = 0x00; + readback_p2 = 0x00; + read_lo = " 0 0 1 0 0 0 0 0", + "a15 a14 a13 a12 a11 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + read_hi = " 0 0 1 0 1 0 0 0", + "a15 a14 a13 a12 a11 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + loadpage_lo = " 0 1 0 0 0 0 0 0", + " x x x x x x x x", + " x x a5 a4 a3 a2 a1 a0", + " i i i i i i i i"; + + loadpage_hi = " 0 1 0 0 1 0 0 0", + " x x x x x x x x", + " x x a5 a4 a3 a2 a1 a0", + " i i i i i i i i"; + + writepage = " 0 1 0 0 1 1 0 0", + "a15 a14 a13 a12 a11 a10 a9 a8", + " a7 a6 x x x x x x", + " x x x x x x x x"; + + mode = 0x41; + delay = 6; + blocksize = 128; + readsize = 256; + ; + + memory "lfuse" + size = 1; + write = "1 0 1 0 1 1 0 0 1 0 1 0 0 0 0 0", + "x x x x x x x x i i i i i i i i"; + + read = "0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0", + "x x x x x x x x o o o o o o o o"; + min_write_delay = 9000; + max_write_delay = 9000; + ; + + memory "hfuse" + size = 1; + write = "1 0 1 0 1 1 0 0 1 0 1 0 1 0 0 0", + "x x x x x x x x i i i i i i i i"; + + read = "0 1 0 1 1 0 0 0 0 0 0 0 1 0 0 0", + "x x x x x x x x o o o o o o o o"; + min_write_delay = 9000; + max_write_delay = 9000; + ; + + memory "efuse" + size = 1; + write = "1 0 1 0 1 1 0 0 1 0 1 0 0 1 0 0", + "x x x x x x x x i i i i i i i i"; + + read = "0 1 0 1 0 0 0 0 0 0 0 0 1 0 0 0", + "x x x x x x x x o o o o o o o o"; + min_write_delay = 9000; + max_write_delay = 9000; + ; + + memory "lock" + size = 1; + read = "0 1 0 1 1 0 0 0 0 0 0 0 0 0 0 0", + "x x x x x x x x x x o o o o o o"; + + write = "1 0 1 0 1 1 0 0 1 1 1 x x x x x", + "x x x x x x x x 1 1 i i i i i i"; + min_write_delay = 9000; + max_write_delay = 9000; + ; + + memory "calibration" + size = 1; + read = "0 0 1 1 1 0 0 0 0 0 0 x x x x x", + "0 0 0 0 0 0 0 0 o o o o o o o o"; + ; + memory "signature" + size = 3; + read = "0 0 1 1 0 0 0 0 0 0 0 x x x x x", + "x x x x x x a1 a0 o o o o o o o o"; + ; + ; + +#------------------------------------------------------------ +# ATmega32U2 +#------------------------------------------------------------ +# Changes against AT90USB162 (beside IDs) +# memory "flash" +# size = 32768; +# num_pages = 256; +# memory "eeprom" +# size = 1024; +# num_pages = 256; +part + id = "m32u2"; + desc = "ATmega32U2"; + has_jtag = no; + has_debugwire = yes; + signature = 0x1e 0x95 0x8a; + usbpid = 0x2ff0; + chip_erase_delay = 9000; + reset = io; + pgm_enable = "1 0 1 0 1 1 0 0 0 1 0 1 0 0 1 1", + "x x x x x x x x x x x x x x x x"; + chip_erase = "1 0 1 0 1 1 0 0 1 0 0 x x x x x", + "x x x x x x x x x x x x x x x x"; + pagel = 0xD7; + bs2 = 0xC6; + + timeout = 200; + stabdelay = 100; + cmdexedelay = 25; + synchloops = 32; + bytedelay = 0; + pollindex = 3; + pollvalue = 0x53; + predelay = 1; + postdelay = 1; + pollmethod = 1; + pp_controlstack = + 0x0E, 0x1E, 0x0F, 0x1F, 0x2E, 0x3E, 0x2F, 0x3F, + 0x4E, 0x5E, 0x4F, 0x5F, 0x6E, 0x7E, 0x6F, 0x7F, + 0x66, 0x76, 0x67, 0x77, 0x6A, 0x7A, 0x6B, 0x7B, + 0xBE, 0xFD, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00; + hventerstabdelay = 100; + progmodedelay = 0; + latchcycles = 5; + togglevtg = 1; + poweroffdelay = 15; + resetdelayms = 1; + resetdelayus = 0; + hvleavestabdelay = 15; + chiperasepulsewidth = 0; + chiperasepolltimeout = 10; + programfusepulsewidth = 0; + programfusepolltimeout = 5; + programlockpulsewidth = 0; + programlockpolltimeout = 5; + + ocdrev = 1; + + memory "eeprom" + paged = no; /* leave this "no" */ + page_size = 4; /* for parallel programming */ + size = 1024; + num_pages = 256; + min_write_delay = 9000; + max_write_delay = 9000; + readback_p1 = 0x00; + readback_p2 = 0x00; + read = " 1 0 1 0 0 0 0 0", + " 0 0 0 0 a11 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + write = " 1 1 0 0 0 0 0 0", + " 0 0 0 0 a11 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " i i i i i i i i"; + + loadpage_lo = " 1 1 0 0 0 0 0 1", + " 0 0 0 0 0 0 0 0", + " 0 0 0 0 0 0 a1 a0", + " i i i i i i i i"; + + writepage = " 1 1 0 0 0 0 1 0", + " 0 0 0 0 a11 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 0 0", + " x x x x x x x x"; + + mode = 0x41; + delay = 20; + blocksize = 4; + readsize = 256; + ; + + memory "flash" + paged = yes; + size = 32768; + page_size = 128; + num_pages = 256; + min_write_delay = 4500; + max_write_delay = 4500; + readback_p1 = 0x00; + readback_p2 = 0x00; + read_lo = " 0 0 1 0 0 0 0 0", + "a15 a14 a13 a12 a11 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + read_hi = " 0 0 1 0 1 0 0 0", + "a15 a14 a13 a12 a11 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + loadpage_lo = " 0 1 0 0 0 0 0 0", + " x x x x x x x x", + " x x a5 a4 a3 a2 a1 a0", + " i i i i i i i i"; + + loadpage_hi = " 0 1 0 0 1 0 0 0", + " x x x x x x x x", + " x x a5 a4 a3 a2 a1 a0", + " i i i i i i i i"; + + writepage = " 0 1 0 0 1 1 0 0", + "a15 a14 a13 a12 a11 a10 a9 a8", + " a7 a6 x x x x x x", + " x x x x x x x x"; + + mode = 0x41; + delay = 6; + blocksize = 128; + readsize = 256; + ; + + memory "lfuse" + size = 1; + write = "1 0 1 0 1 1 0 0 1 0 1 0 0 0 0 0", + "x x x x x x x x i i i i i i i i"; + + read = "0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0", + "x x x x x x x x o o o o o o o o"; + min_write_delay = 9000; + max_write_delay = 9000; + ; + + memory "hfuse" + size = 1; + write = "1 0 1 0 1 1 0 0 1 0 1 0 1 0 0 0", + "x x x x x x x x i i i i i i i i"; + + read = "0 1 0 1 1 0 0 0 0 0 0 0 1 0 0 0", + "x x x x x x x x o o o o o o o o"; + min_write_delay = 9000; + max_write_delay = 9000; + ; + + memory "efuse" + size = 1; + write = "1 0 1 0 1 1 0 0 1 0 1 0 0 1 0 0", + "x x x x x x x x i i i i i i i i"; + + read = "0 1 0 1 0 0 0 0 0 0 0 0 1 0 0 0", + "x x x x x x x x o o o o o o o o"; + min_write_delay = 9000; + max_write_delay = 9000; + ; + + memory "lock" + size = 1; + read = "0 1 0 1 1 0 0 0 0 0 0 0 0 0 0 0", + "x x x x x x x x x x o o o o o o"; + + write = "1 0 1 0 1 1 0 0 1 1 1 x x x x x", + "x x x x x x x x 1 1 i i i i i i"; + min_write_delay = 9000; + max_write_delay = 9000; + ; + + memory "calibration" + size = 1; + read = "0 0 1 1 1 0 0 0 0 0 0 x x x x x", + "0 0 0 0 0 0 0 0 o o o o o o o o"; + ; + memory "signature" + size = 3; + read = "0 0 1 1 0 0 0 0 0 0 0 x x x x x", + "x x x x x x a1 a0 o o o o o o o o"; + ; + ; +#------------------------------------------------------------ +# ATmega16U2 +#------------------------------------------------------------ +# Changes against ATmega32U2 (beside IDs) +# memory "flash" +# size = 16384; +# num_pages = 128; +# memory "eeprom" +# size = 512; +# num_pages = 128; +part + id = "m16u2"; + desc = "ATmega16U2"; + has_jtag = no; + has_debugwire = yes; + signature = 0x1e 0x94 0x89; + usbpid = 0x2fef; + chip_erase_delay = 9000; + reset = io; + pgm_enable = "1 0 1 0 1 1 0 0 0 1 0 1 0 0 1 1", + "x x x x x x x x x x x x x x x x"; + chip_erase = "1 0 1 0 1 1 0 0 1 0 0 x x x x x", + "x x x x x x x x x x x x x x x x"; + pagel = 0xD7; + bs2 = 0xC6; + + timeout = 200; + stabdelay = 100; + cmdexedelay = 25; + synchloops = 32; + bytedelay = 0; + pollindex = 3; + pollvalue = 0x53; + predelay = 1; + postdelay = 1; + pollmethod = 1; + pp_controlstack = + 0x0E, 0x1E, 0x0F, 0x1F, 0x2E, 0x3E, 0x2F, 0x3F, + 0x4E, 0x5E, 0x4F, 0x5F, 0x6E, 0x7E, 0x6F, 0x7F, + 0x66, 0x76, 0x67, 0x77, 0x6A, 0x7A, 0x6B, 0x7B, + 0xBE, 0xFD, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00; + hventerstabdelay = 100; + progmodedelay = 0; + latchcycles = 5; + togglevtg = 1; + poweroffdelay = 15; + resetdelayms = 1; + resetdelayus = 0; + hvleavestabdelay = 15; + chiperasepulsewidth = 0; + chiperasepolltimeout = 10; + programfusepulsewidth = 0; + programfusepolltimeout = 5; + programlockpulsewidth = 0; + programlockpolltimeout = 5; + + ocdrev = 1; + + memory "eeprom" + paged = no; /* leave this "no" */ + page_size = 4; /* for parallel programming */ + size = 512; + num_pages = 128; + min_write_delay = 9000; + max_write_delay = 9000; + readback_p1 = 0x00; + readback_p2 = 0x00; + read = " 1 0 1 0 0 0 0 0", + " 0 0 0 0 a11 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + write = " 1 1 0 0 0 0 0 0", + " 0 0 0 0 a11 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " i i i i i i i i"; + + loadpage_lo = " 1 1 0 0 0 0 0 1", + " 0 0 0 0 0 0 0 0", + " 0 0 0 0 0 0 a1 a0", + " i i i i i i i i"; + + writepage = " 1 1 0 0 0 0 1 0", + " 0 0 0 0 a11 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 0 0", + " x x x x x x x x"; + + mode = 0x41; + delay = 20; + blocksize = 4; + readsize = 256; + ; + + memory "flash" + paged = yes; + size = 16384; + page_size = 128; + num_pages = 128; + min_write_delay = 4500; + max_write_delay = 4500; + readback_p1 = 0x00; + readback_p2 = 0x00; + read_lo = " 0 0 1 0 0 0 0 0", + "a15 a14 a13 a12 a11 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + read_hi = " 0 0 1 0 1 0 0 0", + "a15 a14 a13 a12 a11 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + loadpage_lo = " 0 1 0 0 0 0 0 0", + " x x x x x x x x", + " x x a5 a4 a3 a2 a1 a0", + " i i i i i i i i"; + + loadpage_hi = " 0 1 0 0 1 0 0 0", + " x x x x x x x x", + " x x a5 a4 a3 a2 a1 a0", + " i i i i i i i i"; + + writepage = " 0 1 0 0 1 1 0 0", + "a15 a14 a13 a12 a11 a10 a9 a8", + " a7 a6 x x x x x x", + " x x x x x x x x"; + + mode = 0x41; + delay = 6; + blocksize = 128; + readsize = 256; + ; + + memory "lfuse" + size = 1; + write = "1 0 1 0 1 1 0 0 1 0 1 0 0 0 0 0", + "x x x x x x x x i i i i i i i i"; + + read = "0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0", + "x x x x x x x x o o o o o o o o"; + min_write_delay = 9000; + max_write_delay = 9000; + ; + + memory "hfuse" + size = 1; + write = "1 0 1 0 1 1 0 0 1 0 1 0 1 0 0 0", + "x x x x x x x x i i i i i i i i"; + + read = "0 1 0 1 1 0 0 0 0 0 0 0 1 0 0 0", + "x x x x x x x x o o o o o o o o"; + min_write_delay = 9000; + max_write_delay = 9000; + ; + + memory "efuse" + size = 1; + write = "1 0 1 0 1 1 0 0 1 0 1 0 0 1 0 0", + "x x x x x x x x i i i i i i i i"; + + read = "0 1 0 1 0 0 0 0 0 0 0 0 1 0 0 0", + "x x x x x x x x o o o o o o o o"; + min_write_delay = 9000; + max_write_delay = 9000; + ; + + memory "lock" + size = 1; + read = "0 1 0 1 1 0 0 0 0 0 0 0 0 0 0 0", + "x x x x x x x x x x o o o o o o"; + + write = "1 0 1 0 1 1 0 0 1 1 1 x x x x x", + "x x x x x x x x 1 1 i i i i i i"; + min_write_delay = 9000; + max_write_delay = 9000; + ; + + memory "calibration" + size = 1; + read = "0 0 1 1 1 0 0 0 0 0 0 x x x x x", + "0 0 0 0 0 0 0 0 o o o o o o o o"; + ; + memory "signature" + size = 3; + read = "0 0 1 1 0 0 0 0 0 0 0 x x x x x", + "x x x x x x a1 a0 o o o o o o o o"; + ; + ; + +#------------------------------------------------------------ +# ATmega8U2 +#------------------------------------------------------------ +# Changes against ATmega16U2 (beside IDs) +# memory "flash" +# size = 8192; +# page_size = 64; +# blocksize = 64; + +part + id = "m8u2"; + desc = "ATmega8U2"; + has_jtag = no; + has_debugwire = yes; + signature = 0x1e 0x93 0x89; + usbpid = 0x2fee; + chip_erase_delay = 9000; + reset = io; + pgm_enable = "1 0 1 0 1 1 0 0 0 1 0 1 0 0 1 1", + "x x x x x x x x x x x x x x x x"; + chip_erase = "1 0 1 0 1 1 0 0 1 0 0 x x x x x", + "x x x x x x x x x x x x x x x x"; + pagel = 0xD7; + bs2 = 0xC6; + + timeout = 200; + stabdelay = 100; + cmdexedelay = 25; + synchloops = 32; + bytedelay = 0; + pollindex = 3; + pollvalue = 0x53; + predelay = 1; + postdelay = 1; + pollmethod = 1; + pp_controlstack = + 0x0E, 0x1E, 0x0F, 0x1F, 0x2E, 0x3E, 0x2F, 0x3F, + 0x4E, 0x5E, 0x4F, 0x5F, 0x6E, 0x7E, 0x6F, 0x7F, + 0x66, 0x76, 0x67, 0x77, 0x6A, 0x7A, 0x6B, 0x7B, + 0xBE, 0xFD, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00; + hventerstabdelay = 100; + progmodedelay = 0; + latchcycles = 5; + togglevtg = 1; + poweroffdelay = 15; + resetdelayms = 1; + resetdelayus = 0; + hvleavestabdelay = 15; + chiperasepulsewidth = 0; + chiperasepolltimeout = 10; + programfusepulsewidth = 0; + programfusepolltimeout = 5; + programlockpulsewidth = 0; + programlockpolltimeout = 5; + + ocdrev = 1; + + memory "eeprom" + paged = no; /* leave this "no" */ + page_size = 4; /* for parallel programming */ + size = 512; + num_pages = 128; + min_write_delay = 9000; + max_write_delay = 9000; + readback_p1 = 0x00; + readback_p2 = 0x00; + read = " 1 0 1 0 0 0 0 0", + " 0 0 0 0 a11 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + write = " 1 1 0 0 0 0 0 0", + " 0 0 0 0 a11 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " i i i i i i i i"; + + loadpage_lo = " 1 1 0 0 0 0 0 1", + " 0 0 0 0 0 0 0 0", + " 0 0 0 0 0 0 a1 a0", + " i i i i i i i i"; + + writepage = " 1 1 0 0 0 0 1 0", + " 0 0 0 0 a11 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 0 0", + " x x x x x x x x"; + + mode = 0x41; + delay = 20; + blocksize = 4; + readsize = 256; + ; + + memory "flash" + paged = yes; + size = 8192; + page_size = 128; + num_pages = 64; + min_write_delay = 4500; + max_write_delay = 4500; + readback_p1 = 0x00; + readback_p2 = 0x00; + read_lo = " 0 0 1 0 0 0 0 0", + "a15 a14 a13 a12 a11 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + read_hi = " 0 0 1 0 1 0 0 0", + "a15 a14 a13 a12 a11 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + loadpage_lo = " 0 1 0 0 0 0 0 0", + " x x x x x x x x", + " x x a5 a4 a3 a2 a1 a0", + " i i i i i i i i"; + + loadpage_hi = " 0 1 0 0 1 0 0 0", + " x x x x x x x x", + " x x a5 a4 a3 a2 a1 a0", + " i i i i i i i i"; + + writepage = " 0 1 0 0 1 1 0 0", + "a15 a14 a13 a12 a11 a10 a9 a8", + " a7 a6 x x x x x x", + " x x x x x x x x"; + + mode = 0x41; + delay = 6; + blocksize = 128; + readsize = 256; + ; + + memory "lfuse" + size = 1; + write = "1 0 1 0 1 1 0 0 1 0 1 0 0 0 0 0", + "x x x x x x x x i i i i i i i i"; + + read = "0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0", + "x x x x x x x x o o o o o o o o"; + min_write_delay = 9000; + max_write_delay = 9000; + ; + + memory "hfuse" + size = 1; + write = "1 0 1 0 1 1 0 0 1 0 1 0 1 0 0 0", + "x x x x x x x x i i i i i i i i"; + + read = "0 1 0 1 1 0 0 0 0 0 0 0 1 0 0 0", + "x x x x x x x x o o o o o o o o"; + min_write_delay = 9000; + max_write_delay = 9000; + ; + + memory "efuse" + size = 1; + write = "1 0 1 0 1 1 0 0 1 0 1 0 0 1 0 0", + "x x x x x x x x i i i i i i i i"; + + read = "0 1 0 1 0 0 0 0 0 0 0 0 1 0 0 0", + "x x x x x x x x o o o o o o o o"; + min_write_delay = 9000; + max_write_delay = 9000; + ; + + memory "lock" + size = 1; + read = "0 1 0 1 1 0 0 0 0 0 0 0 0 0 0 0", + "x x x x x x x x x x o o o o o o"; + + write = "1 0 1 0 1 1 0 0 1 1 1 x x x x x", + "x x x x x x x x 1 1 i i i i i i"; + min_write_delay = 9000; + max_write_delay = 9000; + ; + + memory "calibration" + size = 1; + read = "0 0 1 1 1 0 0 0 0 0 0 x x x x x", + "0 0 0 0 0 0 0 0 o o o o o o o o"; + ; + memory "signature" + size = 3; + read = "0 0 1 1 0 0 0 0 0 0 0 x x x x x", + "x x x x x x a1 a0 o o o o o o o o"; + ; + ; +#------------------------------------------------------------ +# ATmega325 +#------------------------------------------------------------ + +part + id = "m325"; + desc = "ATmega325"; + signature = 0x1e 0x95 0x05; + has_jtag = yes; +# stk500_devcode = 0x??; # No STK500v1 support? +# avr910_devcode = 0x??; # Try the ATmega16 one + avr910_devcode = 0x74; + pagel = 0xd7; + bs2 = 0xa0; + chip_erase_delay = 9000; + pgm_enable = "1 0 1 0 1 1 0 0 0 1 0 1 0 0 1 1", + "0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0"; + + chip_erase = "1 0 1 0 1 1 0 0 1 0 0 0 0 0 0 0", + "0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0"; + + timeout = 200; + stabdelay = 100; + cmdexedelay = 25; + synchloops = 32; + bytedelay = 0; + pollindex = 3; + pollvalue = 0x53; + predelay = 1; + postdelay = 1; + pollmethod = 1; + + pp_controlstack = + 0x0E, 0x1E, 0x0F, 0x1F, 0x2E, 0x3E, 0x2F, 0x3F, + 0x4E, 0x5E, 0x4F, 0x5F, 0x6E, 0x7E, 0x6F, 0x7F, + 0x66, 0x76, 0x67, 0x77, 0x6A, 0x7A, 0x6B, 0x7B, + 0xBE, 0xFD, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00; + hventerstabdelay = 100; + progmodedelay = 0; + latchcycles = 5; + togglevtg = 1; + poweroffdelay = 15; + resetdelayms = 1; + resetdelayus = 0; + hvleavestabdelay = 15; + chiperasepulsewidth = 0; + chiperasepolltimeout = 10; + programfusepulsewidth = 0; + programfusepolltimeout = 5; + programlockpulsewidth = 0; + programlockpolltimeout = 5; + + idr = 0x31; + spmcr = 0x57; + allowfullpagebitstream = no; + + ocdrev = 3; + + memory "eeprom" + paged = no; /* leave this "no" */ + page_size = 4; /* for parallel programming */ + size = 1024; + min_write_delay = 9000; + max_write_delay = 9000; + readback_p1 = 0xff; + readback_p2 = 0xff; + read = " 1 0 1 0 0 0 0 0", + " 0 0 0 0 0 0 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + write = " 1 1 0 0 0 0 0 0", + " 0 0 0 0 0 0 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " i i i i i i i i"; + + loadpage_lo = " 1 1 0 0 0 0 0 1", + " 0 0 0 0 0 0 0 0", + " 0 0 0 0 0 0 a1 a0", + " i i i i i i i i"; + + writepage = " 1 1 0 0 0 0 1 0", + " 0 0 0 0 0 0 a9 a8", + " a7 a6 a5 a4 a3 a2 0 0", + " x x x x x x x x"; + + mode = 0x41; + delay = 10; + blocksize = 4; + readsize = 256; + ; + + memory "flash" + paged = yes; + size = 32768; + page_size = 128; + num_pages = 256; + min_write_delay = 4500; + max_write_delay = 4500; + readback_p1 = 0xff; + readback_p2 = 0xff; + read_lo = " 0 0 1 0 0 0 0 0", + " 0 a14 a13 a12 a11 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + read_hi = " 0 0 1 0 1 0 0 0", + " 0 a14 a13 a12 a11 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + loadpage_lo = " 0 1 0 0 0 0 0 0", + " 0 0 0 0 0 0 0 0", + " a7 a6 a5 a4 a3 a2 a1 a0", + " i i i i i i i i"; + + loadpage_hi = " 0 1 0 0 1 0 0 0", + " 0 0 0 0 0 0 0 0", + " a7 a6 a5 a4 a3 a2 a1 a0", + " i i i i i i i i"; + + writepage = " 0 1 0 0 1 1 0 0", + " 0 a14 a13 a12 a11 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " x x x x x x x x"; + + mode = 0x41; + delay = 10; + blocksize = 128; + readsize = 256; + ; + + memory "lock" + size = 1; + read = "0 1 0 1 1 0 0 0 0 0 0 0 0 0 0 0", + "x x x x x x x x x x o o o o o o"; + + write = "1 0 1 0 1 1 0 0 1 1 1 0 0 0 0 0", + "0 0 0 0 0 0 0 0 1 1 i i i i i i"; + min_write_delay = 9000; + max_write_delay = 9000; + ; + + memory "lfuse" + size = 1; + read = "0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0", + "0 0 0 0 0 0 0 0 o o o o o o o o"; + + write = "1 0 1 0 1 1 0 0 1 0 1 0 0 0 0 0", + "0 0 0 0 0 0 0 0 i i i i i i i i"; + min_write_delay = 9000; + max_write_delay = 9000; + ; + + memory "hfuse" + size = 1; + read = "0 1 0 1 1 0 0 0 0 0 0 0 1 0 0 0", + "0 0 0 0 0 0 0 0 o o o o o o o o"; + + write = "1 0 1 0 1 1 0 0 1 0 1 0 1 0 0 0", + "0 0 0 0 0 0 0 0 i i i i i i i i"; + min_write_delay = 9000; + max_write_delay = 9000; + ; + + memory "efuse" + size = 1; + + read = "0 1 0 1 0 0 0 0 0 0 0 0 1 0 0 0", + "0 0 0 0 0 0 0 0 o o o o o o o o"; + + write = "1 0 1 0 1 1 0 0 1 0 1 0 0 1 0 0", + "0 0 0 0 0 0 0 0 1 1 1 1 1 i i i"; + min_write_delay = 9000; + max_write_delay = 9000; + ; + + memory "signature" + size = 3; + read = "0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0", + "0 0 0 0 0 0 a1 a0 o o o o o o o o"; + ; + + memory "calibration" + size = 1; + + read = "0 0 1 1 1 0 0 0 0 0 0 0 0 0 0 0", + "0 0 0 0 0 0 0 0 o o o o o o o o"; + ; + ; + +#------------------------------------------------------------ +# ATmega645 +#------------------------------------------------------------ + +part + id = "m645"; + desc = "ATmega645"; + signature = 0x1E 0x96 0x05; + has_jtag = yes; +# stk500_devcode = 0x??; # No STK500v1 support? +# avr910_devcode = 0x??; # Try the ATmega16 one + avr910_devcode = 0x74; + pagel = 0xd7; + bs2 = 0xa0; + chip_erase_delay = 9000; + pgm_enable = "1 0 1 0 1 1 0 0 0 1 0 1 0 0 1 1", + "0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0"; + + chip_erase = "1 0 1 0 1 1 0 0 1 0 0 0 0 0 0 0", + "0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0"; + + timeout = 200; + stabdelay = 100; + cmdexedelay = 25; + synchloops = 32; + bytedelay = 0; + pollindex = 3; + pollvalue = 0x53; + predelay = 1; + postdelay = 1; + pollmethod = 1; + + pp_controlstack = + 0x0E, 0x1E, 0x0F, 0x1F, 0x2E, 0x3E, 0x2F, 0x3F, + 0x4E, 0x5E, 0x4F, 0x5F, 0x6E, 0x7E, 0x6F, 0x7F, + 0x66, 0x76, 0x67, 0x77, 0x6A, 0x7A, 0x6B, 0x7B, + 0xBE, 0xFD, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00; + hventerstabdelay = 100; + progmodedelay = 0; + latchcycles = 5; + togglevtg = 1; + poweroffdelay = 15; + resetdelayms = 1; + resetdelayus = 0; + hvleavestabdelay = 15; + chiperasepulsewidth = 0; + chiperasepolltimeout = 10; + programfusepulsewidth = 0; + programfusepolltimeout = 5; + programlockpulsewidth = 0; + programlockpolltimeout = 5; + + idr = 0x31; + spmcr = 0x57; + allowfullpagebitstream = no; + + ocdrev = 3; + + memory "eeprom" + paged = no; /* leave this "no" */ + page_size = 8; /* for parallel programming */ + size = 2048; + min_write_delay = 9000; + max_write_delay = 9000; + readback_p1 = 0xff; + readback_p2 = 0xff; + read = " 1 0 1 0 0 0 0 0", + " 0 0 0 0 0 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + write = " 1 1 0 0 0 0 0 0", + " 0 0 0 0 0 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " i i i i i i i i"; + + loadpage_lo = " 1 1 0 0 0 0 0 1", + " 0 0 0 0 0 0 0 0", + " 0 0 0 0 0 a2 a1 a0", + " i i i i i i i i"; + + writepage = " 1 1 0 0 0 0 1 0", + " 0 0 0 0 0 a10 a9 a8", + " a7 a6 a5 a4 a3 0 0 0", + " x x x x x x x x"; + + mode = 0x41; + delay = 10; + blocksize = 8; + readsize = 256; + ; + + memory "flash" + paged = yes; + size = 65536; + page_size = 256; + num_pages = 256; + min_write_delay = 4500; + max_write_delay = 4500; + readback_p1 = 0xff; + readback_p2 = 0xff; + read_lo = " 0 0 1 0 0 0 0 0", + " a15 a14 a13 a12 a11 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + read_hi = " 0 0 1 0 1 0 0 0", + " a15 a14 a13 a12 a11 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + loadpage_lo = " 0 1 0 0 0 0 0 0", + " 0 0 0 0 0 0 0 0", + " a7 a6 a5 a4 a3 a2 a1 a0", + " i i i i i i i i"; + + loadpage_hi = " 0 1 0 0 1 0 0 0", + " 0 0 0 0 0 0 0 0", + " a7 a6 a5 a4 a3 a2 a1 a0", + " i i i i i i i i"; + + writepage = " 0 1 0 0 1 1 0 0", + " a15 a14 a13 a12 a11 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " 0 0 0 0 0 0 0 0"; + + mode = 0x41; + delay = 10; + blocksize = 128; + readsize = 256; + ; + + memory "lock" + size = 1; + read = "0 1 0 1 1 0 0 0 0 0 0 0 0 0 0 0", + "x x x x x x x x x x o o o o o o"; + + write = "1 0 1 0 1 1 0 0 1 1 1 0 0 0 0 0", + "0 0 0 0 0 0 0 0 1 1 i i i i i i"; + min_write_delay = 9000; + max_write_delay = 9000; + ; + + memory "lfuse" + size = 1; + read = "0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0", + "0 0 0 0 0 0 0 0 o o o o o o o o"; + + write = "1 0 1 0 1 1 0 0 1 0 1 0 0 0 0 0", + "0 0 0 0 0 0 0 0 i i i i i i i i"; + min_write_delay = 9000; + max_write_delay = 9000; + ; + + memory "hfuse" + size = 1; + read = "0 1 0 1 1 0 0 0 0 0 0 0 1 0 0 0", + "0 0 0 0 0 0 0 0 o o o o o o o o"; + + write = "1 0 1 0 1 1 0 0 1 0 1 0 1 0 0 0", + "0 0 0 0 0 0 0 0 i i i i i i i i"; + min_write_delay = 9000; + max_write_delay = 9000; + ; + + memory "efuse" + size = 1; + + read = "0 1 0 1 0 0 0 0 0 0 0 0 1 0 0 0", + "0 0 0 0 0 0 0 0 o o o o o o o o"; + + write = "1 0 1 0 1 1 0 0 1 0 1 0 0 1 0 0", + "0 0 0 0 0 0 0 0 1 1 1 1 1 i i i"; + min_write_delay = 9000; + max_write_delay = 9000; + ; + + memory "signature" + size = 3; + read = "0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0", + "0 0 0 0 0 0 a1 a0 o o o o o o o o"; + ; + + memory "calibration" + size = 1; + + read = "0 0 1 1 1 0 0 0 0 0 0 0 0 0 0 0", + "0 0 0 0 0 0 0 0 o o o o o o o o"; + ; + ; + +#------------------------------------------------------------ +# ATmega3250 +#------------------------------------------------------------ + +part parent "m325" + id = "m3250"; + desc = "ATmega3250"; + signature = 0x1E 0x95 0x06; + + ocdrev = 3; + ; + +#------------------------------------------------------------ +# ATmega6450 +#------------------------------------------------------------ + +part parent "m645" + id = "m6450"; + desc = "ATmega6450"; + signature = 0x1E 0x96 0x06; + + ocdrev = 3; + ; + +#------------------------------------------------------------ +# AVR XMEGA family common values +#------------------------------------------------------------ + +part + id = ".xmega"; + desc = "AVR XMEGA family common values"; + has_pdi = yes; + nvm_base = 0x01c0; + mcu_base = 0x0090; + + memory "signature" + size = 3; + offset = 0x1000090; + ; + + memory "prodsig" + size = 0x32; + offset = 0x8e0200; + page_size = 0x32; + readsize = 0x32; + ; + + memory "fuse1" + size = 1; + offset = 0x8f0021; + ; + + memory "fuse2" + size = 1; + offset = 0x8f0022; + ; + + memory "fuse4" + size = 1; + offset = 0x8f0024; + ; + + memory "fuse5" + size = 1; + offset = 0x8f0025; + ; + + memory "lock" + size = 1; + offset = 0x8f0027; + ; + + memory "data" + # SRAM, only used to supply the offset + offset = 0x1000000; + ; +; + +#------------------------------------------------------------ +# ATxmega16A4U +#------------------------------------------------------------ + +part parent ".xmega" + id = "x16a4u"; + desc = "ATxmega16A4U"; + signature = 0x1e 0x94 0x41; + usbpid = 0x2fe3; + + memory "eeprom" + size = 0x400; + offset = 0x8c0000; + page_size = 0x20; + readsize = 0x100; + ; + + memory "application" + size = 0x4000; + offset = 0x800000; + page_size = 0x100; + readsize = 0x100; + ; + + memory "apptable" + size = 0x1000; + offset = 0x803000; + page_size = 0x100; + readsize = 0x100; + ; + + memory "boot" + size = 0x1000; + offset = 0x804000; + page_size = 0x100; + readsize = 0x100; + ; + + memory "flash" + size = 0x5000; + offset = 0x800000; + page_size = 0x100; + readsize = 0x100; + ; + + memory "usersig" + size = 0x100; + offset = 0x8e0400; + page_size = 0x100; + readsize = 0x100; + ; +; + +#------------------------------------------------------------ +# ATxmega16C4 +#------------------------------------------------------------ + +part parent "x16a4u" + id = "x16c4"; + desc = "ATxmega16C4"; + signature = 0x1e 0x95 0x44; +; + +#------------------------------------------------------------ +# ATxmega16D4 +#------------------------------------------------------------ + +part parent "x16a4u" + id = "x16d4"; + desc = "ATxmega16D4"; + signature = 0x1e 0x94 0x42; +; + +#------------------------------------------------------------ +# ATxmega16A4 +#------------------------------------------------------------ + +part parent "x16a4u" + id = "x16a4"; + desc = "ATxmega16A4"; + signature = 0x1e 0x94 0x41; + has_jtag = yes; + + memory "fuse0" + size = 1; + offset = 0x8f0020; + ; +; + +#------------------------------------------------------------ +# ATxmega32A4U +#------------------------------------------------------------ + +part parent ".xmega" + id = "x32a4u"; + desc = "ATxmega32A4U"; + signature = 0x1e 0x95 0x41; + usbpid = 0x2fe4; + + memory "eeprom" + size = 0x400; + offset = 0x8c0000; + page_size = 0x20; + readsize = 0x100; + ; + + memory "application" + size = 0x8000; + offset = 0x800000; + page_size = 0x100; + readsize = 0x100; + ; + + memory "apptable" + size = 0x1000; + offset = 0x807000; + page_size = 0x100; + readsize = 0x100; + ; + + memory "boot" + size = 0x1000; + offset = 0x808000; + page_size = 0x100; + readsize = 0x100; + ; + + memory "flash" + size = 0x9000; + offset = 0x800000; + page_size = 0x100; + readsize = 0x100; + ; + + memory "usersig" + size = 0x100; + offset = 0x8e0400; + page_size = 0x100; + readsize = 0x100; + ; +; + +#------------------------------------------------------------ +# ATxmega32C4 +#------------------------------------------------------------ + +part parent "x32a4u" + id = "x32c4"; + desc = "ATxmega32C4"; + signature = 0x1e 0x94 0x43; +; + +#------------------------------------------------------------ +# ATxmega32D4 +#------------------------------------------------------------ + +part parent "x32a4u" + id = "x32d4"; + desc = "ATxmega32D4"; + signature = 0x1e 0x95 0x42; +; + +#------------------------------------------------------------ +# ATxmega32A4 +#------------------------------------------------------------ + +part parent "x32a4u" + id = "x32a4"; + desc = "ATxmega32A4"; + signature = 0x1e 0x95 0x41; + has_jtag = yes; + + memory "fuse0" + size = 1; + offset = 0x8f0020; + ; +; + +#------------------------------------------------------------ +# ATxmega64A4U +#------------------------------------------------------------ + +part parent ".xmega" + id = "x64a4u"; + desc = "ATxmega64A4U"; + signature = 0x1e 0x96 0x46; + usbpid = 0x2fe5; + + memory "eeprom" + size = 0x800; + offset = 0x8c0000; + page_size = 0x20; + readsize = 0x100; + ; + + memory "application" + size = 0x10000; + offset = 0x800000; + page_size = 0x100; + readsize = 0x100; + ; + + memory "apptable" + size = 0x1000; + offset = 0x80f000; + page_size = 0x100; + readsize = 0x100; + ; + + memory "boot" + size = 0x1000; + offset = 0x810000; + page_size = 0x100; + readsize = 0x100; + ; + + memory "flash" + size = 0x11000; + offset = 0x800000; + page_size = 0x100; + readsize = 0x100; + ; + + memory "usersig" + size = 0x100; + offset = 0x8e0400; + page_size = 0x100; + readsize = 0x100; + ; +; + +#------------------------------------------------------------ +# ATxmega64C3 +#------------------------------------------------------------ + +part parent "x64a4u" + id = "x64c3"; + desc = "ATxmega64C3"; + signature = 0x1e 0x96 0x49; + usbpid = 0x2fd6; +; + +#------------------------------------------------------------ +# ATxmega64D3 +#------------------------------------------------------------ + +part parent "x64a4u" + id = "x64d3"; + desc = "ATxmega64D3"; + signature = 0x1e 0x96 0x4a; +; + +#------------------------------------------------------------ +# ATxmega64D4 +#------------------------------------------------------------ + +part parent "x64a4u" + id = "x64d4"; + desc = "ATxmega64D4"; + signature = 0x1e 0x96 0x47; +; + +#------------------------------------------------------------ +# ATxmega64A1 +#------------------------------------------------------------ + +part parent "x64a4u" + id = "x64a1"; + desc = "ATxmega64A1"; + signature = 0x1e 0x96 0x4e; + has_jtag = yes; + + memory "fuse0" + size = 1; + offset = 0x8f0020; + ; +; + +#------------------------------------------------------------ +# ATxmega64A1U +#------------------------------------------------------------ + +part parent "x64a1" + id = "x64a1u"; + desc = "ATxmega64A1U"; + signature = 0x1e 0x96 0x4e; + usbpid = 0x2fe8; +; + +#------------------------------------------------------------ +# ATxmega64A3 +#------------------------------------------------------------ + +part parent "x64a1" + id = "x64a3"; + desc = "ATxmega64A3"; + signature = 0x1e 0x96 0x42; +; + +#------------------------------------------------------------ +# ATxmega64A3U +#------------------------------------------------------------ + +part parent "x64a1" + id = "x64a3u"; + desc = "ATxmega64A3U"; + signature = 0x1e 0x96 0x42; + usbpid = 0x2fe5; +; + +#------------------------------------------------------------ +# ATxmega64A4 +#------------------------------------------------------------ + +part parent "x64a1" + id = "x64a4"; + desc = "ATxmega64A4"; + signature = 0x1e 0x96 0x46; +; + +#------------------------------------------------------------ +# ATxmega64B1 +#------------------------------------------------------------ + +part parent "x64a1" + id = "x64b1"; + desc = "ATxmega64B1"; + signature = 0x1e 0x96 0x52; + usbpid = 0x2fe1; +; + +#------------------------------------------------------------ +# ATxmega64B3 +#------------------------------------------------------------ + +part parent "x64a1" + id = "x64b3"; + desc = "ATxmega64B3"; + signature = 0x1e 0x96 0x51; + usbpid = 0x2fdf; +; + +#------------------------------------------------------------ +# ATxmega128C3 +#------------------------------------------------------------ + +part parent ".xmega" + id = "x128c3"; + desc = "ATxmega128C3"; + signature = 0x1e 0x97 0x52; + usbpid = 0x2fd7; + + memory "eeprom" + size = 0x800; + offset = 0x8c0000; + page_size = 0x20; + readsize = 0x100; + ; + + memory "application" + size = 0x20000; + offset = 0x800000; + page_size = 0x200; + readsize = 0x100; + ; + + memory "apptable" + size = 0x2000; + offset = 0x81e000; + page_size = 0x200; + readsize = 0x100; + ; + + memory "boot" + size = 0x2000; + offset = 0x820000; + page_size = 0x200; + readsize = 0x100; + ; + + memory "flash" + size = 0x22000; + offset = 0x800000; + page_size = 0x200; + readsize = 0x100; + ; + + memory "usersig" + size = 0x200; + offset = 0x8e0400; + page_size = 0x200; + readsize = 0x100; + ; +; + +#------------------------------------------------------------ +# ATxmega128D3 +#------------------------------------------------------------ + +part parent "x128c3" + id = "x128d3"; + desc = "ATxmega128D3"; + signature = 0x1e 0x97 0x48; +; + +#------------------------------------------------------------ +# ATxmega128D4 +#------------------------------------------------------------ + +part parent "x128c3" + id = "x128d4"; + desc = "ATxmega128D4"; + signature = 0x1e 0x97 0x47; +; + +#------------------------------------------------------------ +# ATxmega128A1 +#------------------------------------------------------------ + +part parent "x128c3" + id = "x128a1"; + desc = "ATxmega128A1"; + signature = 0x1e 0x97 0x4c; + has_jtag = yes; + + memory "fuse0" + size = 1; + offset = 0x8f0020; + ; +; + +#------------------------------------------------------------ +# ATxmega128A1 revision D +#------------------------------------------------------------ + +part parent "x128a1" + id = "x128a1d"; + desc = "ATxmega128A1revD"; + signature = 0x1e 0x97 0x41; +; + +#------------------------------------------------------------ +# ATxmega128A1U +#------------------------------------------------------------ + +part parent "x128a1" + id = "x128a1u"; + desc = "ATxmega128A1U"; + signature = 0x1e 0x97 0x4c; + usbpid = 0x2fed; +; + +#------------------------------------------------------------ +# ATxmega128A3 +#------------------------------------------------------------ + +part parent "x128a1" + id = "x128a3"; + desc = "ATxmega128A3"; + signature = 0x1e 0x97 0x42; +; + +#------------------------------------------------------------ +# ATxmega128A3U +#------------------------------------------------------------ + +part parent "x128a1" + id = "x128a3u"; + desc = "ATxmega128A3U"; + signature = 0x1e 0x97 0x42; + usbpid = 0x2fe6; +; + +#------------------------------------------------------------ +# ATxmega128A4 +#------------------------------------------------------------ + +part parent ".xmega" + id = "x128a4"; + desc = "ATxmega128A4"; + signature = 0x1e 0x97 0x46; + has_jtag = yes; + + memory "eeprom" + size = 0x800; + offset = 0x8c0000; + page_size = 0x20; + readsize = 0x100; + ; + + memory "application" + size = 0x20000; + offset = 0x800000; + page_size = 0x200; + readsize = 0x100; + ; + + memory "apptable" + size = 0x1000; + offset = 0x81f000; + page_size = 0x200; + readsize = 0x100; + ; + + memory "boot" + size = 0x2000; + offset = 0x820000; + page_size = 0x200; + readsize = 0x100; + ; + + memory "flash" + size = 0x22000; + offset = 0x800000; + page_size = 0x200; + readsize = 0x100; + ; + + memory "usersig" + size = 0x200; + offset = 0x8e0400; + page_size = 0x200; + readsize = 0x100; + ; + + memory "fuse0" + size = 1; + offset = 0x8f0020; + ; +; + +#------------------------------------------------------------ +# ATxmega128A4U +#------------------------------------------------------------ + +part parent ".xmega" + id = "x128a4u"; + desc = "ATxmega128A4U"; + signature = 0x1e 0x97 0x46; + usbpid = 0x2fde; + + memory "eeprom" + size = 0x800; + offset = 0x8c0000; + page_size = 0x20; + readsize = 0x100; + ; + + memory "application" + size = 0x20000; + offset = 0x800000; + page_size = 0x100; + readsize = 0x100; + ; + + memory "apptable" + size = 0x1000; + offset = 0x81f000; + page_size = 0x100; + readsize = 0x100; + ; + + memory "boot" + size = 0x2000; + offset = 0x820000; + page_size = 0x100; + readsize = 0x100; + ; + + memory "flash" + size = 0x22000; + offset = 0x800000; + page_size = 0x100; + readsize = 0x100; + ; + + memory "usersig" + size = 0x100; + offset = 0x8e0400; + page_size = 0x100; + readsize = 0x100; + ; +; + +#------------------------------------------------------------ +# ATxmega128B1 +#------------------------------------------------------------ + +part parent ".xmega" + id = "x128b1"; + desc = "ATxmega128B1"; + signature = 0x1e 0x97 0x4d; + usbpid = 0x2fea; + has_jtag = yes; + + memory "eeprom" + size = 0x800; + offset = 0x8c0000; + page_size = 0x20; + readsize = 0x100; + ; + + memory "application" + size = 0x20000; + offset = 0x800000; + page_size = 0x100; + readsize = 0x100; + ; + + memory "apptable" + size = 0x2000; + offset = 0x81e000; + page_size = 0x100; + readsize = 0x100; + ; + + memory "boot" + size = 0x2000; + offset = 0x820000; + page_size = 0x100; + readsize = 0x100; + ; + + memory "flash" + size = 0x22000; + offset = 0x800000; + page_size = 0x100; + readsize = 0x100; + ; + + memory "usersig" + size = 0x100; + offset = 0x8e0400; + page_size = 0x100; + readsize = 0x100; + ; + + memory "fuse0" + size = 1; + offset = 0x8f0020; + ; +; + +#------------------------------------------------------------ +# ATxmega128B3 +#------------------------------------------------------------ + +part parent "x128b1" + id = "x128b3"; + desc = "ATxmega128B3"; + signature = 0x1e 0x97 0x4b; + usbpid = 0x2fe0; +; + +#------------------------------------------------------------ +# ATxmega192C3 +#------------------------------------------------------------ + +part parent ".xmega" + id = "x192c3"; + desc = "ATxmega192C3"; + signature = 0x1e 0x97 0x51; + # usbpid = 0x2f??; + + memory "eeprom" + size = 0x800; + offset = 0x8c0000; + page_size = 0x20; + readsize = 0x100; + ; + + memory "application" + size = 0x30000; + offset = 0x800000; + page_size = 0x200; + readsize = 0x100; + ; + + memory "apptable" + size = 0x2000; + offset = 0x82e000; + page_size = 0x200; + readsize = 0x100; + ; + + memory "boot" + size = 0x2000; + offset = 0x830000; + page_size = 0x200; + readsize = 0x100; + ; + + memory "flash" + size = 0x32000; + offset = 0x800000; + page_size = 0x200; + readsize = 0x100; + ; + + memory "usersig" + size = 0x200; + offset = 0x8e0400; + page_size = 0x200; + readsize = 0x100; + ; +; + +#------------------------------------------------------------ +# ATxmega192D3 +#------------------------------------------------------------ + +part parent "x192c3" + id = "x192d3"; + desc = "ATxmega192D3"; + signature = 0x1e 0x97 0x49; +; + +#------------------------------------------------------------ +# ATxmega192A1 +#------------------------------------------------------------ + +part parent "x192c3" + id = "x192a1"; + desc = "ATxmega192A1"; + signature = 0x1e 0x97 0x4e; + has_jtag = yes; + + memory "fuse0" + size = 1; + offset = 0x8f0020; + ; +; + +#------------------------------------------------------------ +# ATxmega192A3 +#------------------------------------------------------------ + +part parent "x192a1" + id = "x192a3"; + desc = "ATxmega192A3"; + signature = 0x1e 0x97 0x44; +; + +#------------------------------------------------------------ +# ATxmega192A3U +#------------------------------------------------------------ + +part parent "x192a1" + id = "x192a3u"; + desc = "ATxmega192A3U"; + signature = 0x1e 0x97 0x44; + usbpid = 0x2fe7; +; + +#------------------------------------------------------------ +# ATxmega256C3 +#------------------------------------------------------------ + +part parent ".xmega" + id = "x256c3"; + desc = "ATxmega256C3"; + signature = 0x1e 0x98 0x46; + usbpid = 0x2fda; + + memory "eeprom" + size = 0x1000; + offset = 0x8c0000; + page_size = 0x20; + readsize = 0x100; + ; + + memory "application" + size = 0x40000; + offset = 0x800000; + page_size = 0x200; + readsize = 0x100; + ; + + memory "apptable" + size = 0x2000; + offset = 0x83e000; + page_size = 0x200; + readsize = 0x100; + ; + + memory "boot" + size = 0x2000; + offset = 0x840000; + page_size = 0x200; + readsize = 0x100; + ; + + memory "flash" + size = 0x42000; + offset = 0x800000; + page_size = 0x200; + readsize = 0x100; + ; + + memory "usersig" + size = 0x200; + offset = 0x8e0400; + page_size = 0x200; + readsize = 0x100; + ; +; + +#------------------------------------------------------------ +# ATxmega256D3 +#------------------------------------------------------------ + +part parent "x256c3" + id = "x256d3"; + desc = "ATxmega256D3"; + signature = 0x1e 0x98 0x44; +; + +#------------------------------------------------------------ +# ATxmega256A1 +#------------------------------------------------------------ + +part parent "x256c3" + id = "x256a1"; + desc = "ATxmega256A1"; + signature = 0x1e 0x98 0x46; + has_jtag = yes; + + memory "fuse0" + size = 1; + offset = 0x8f0020; + ; +; + +#------------------------------------------------------------ +# ATxmega256A3 +#------------------------------------------------------------ + +part parent "x256a1" + id = "x256a3"; + desc = "ATxmega256A3"; + signature = 0x1e 0x98 0x42; +; + +#------------------------------------------------------------ +# ATxmega256A3U +#------------------------------------------------------------ + +part parent "x256a1" + id = "x256a3u"; + desc = "ATxmega256A3U"; + signature = 0x1e 0x98 0x42; + usbpid = 0x2fec; +; + +#------------------------------------------------------------ +# ATxmega256A3B +#------------------------------------------------------------ + +part parent "x256a1" + id = "x256a3b"; + desc = "ATxmega256A3B"; + signature = 0x1e 0x98 0x43; +; + +#------------------------------------------------------------ +# ATxmega256A3BU +#------------------------------------------------------------ + +part parent "x256a1" + id = "x256a3bu"; + desc = "ATxmega256A3BU"; + signature = 0x1e 0x98 0x43; + usbpid = 0x2fe2; +; + +#------------------------------------------------------------ +# ATxmega384C3 +#------------------------------------------------------------ + +part parent ".xmega" + id = "x384c3"; + desc = "ATxmega384C3"; + signature = 0x1e 0x98 0x45; + usbpid = 0x2fdb; + + memory "eeprom" + size = 0x1000; + offset = 0x8c0000; + page_size = 0x20; + readsize = 0x100; + ; + + memory "application" + size = 0x60000; + offset = 0x800000; + page_size = 0x200; + readsize = 0x100; + ; + + memory "apptable" + size = 0x2000; + offset = 0x85e000; + page_size = 0x200; + readsize = 0x100; + ; + + memory "boot" + size = 0x2000; + offset = 0x860000; + page_size = 0x200; + readsize = 0x100; + ; + + memory "flash" + size = 0x62000; + offset = 0x800000; + page_size = 0x200; + readsize = 0x100; + ; + + memory "usersig" + size = 0x200; + offset = 0x8e0400; + page_size = 0x200; + readsize = 0x100; + ; +; + +#------------------------------------------------------------ +# ATxmega384D3 +#------------------------------------------------------------ + +part parent "x384c3" + id = "x384d3"; + desc = "ATxmega384D3"; + signature = 0x1e 0x98 0x47; +; + +#------------------------------------------------------------ +# ATxmega8E5 +#------------------------------------------------------------ + +part parent ".xmega" + id = "x8e5"; + desc = "ATxmega8E5"; + signature = 0x1e 0x93 0x41; + + memory "eeprom" + size = 0x0200; + offset = 0x08c0000; + page_size = 0x20; + readsize = 0x100; + ; + + memory "application" + size = 0x2000; + offset = 0x0800000; + page_size = 0x80; + readsize = 0x100; + ; + + memory "apptable" + size = 0x800; + offset = 0x00801800; + page_size = 0x80; + readsize = 0x100; + ; + + memory "boot" + size = 0x800; + offset = 0x00802000; + page_size = 0x80; + readsize = 0x100; + ; + + memory "flash" + size = 0x2800; + offset = 0x0800000; + page_size = 0x80; + readsize = 0x100; + ; + + memory "usersig" + size = 0x80; + offset = 0x8e0400; + page_size = 0x80; + readsize = 0x100; + ; +; + +#------------------------------------------------------------ +# ATxmega16E5 +#------------------------------------------------------------ + +part parent ".xmega" + id = "x16e5"; + desc = "ATxmega16E5"; + signature = 0x1e 0x94 0x45; + + memory "eeprom" + size = 0x0200; + offset = 0x08c0000; + page_size = 0x20; + readsize = 0x100; + ; + + memory "application" + size = 0x4000; + offset = 0x0800000; + page_size = 0x80; + readsize = 0x100; + ; + + memory "apptable" + size = 0x1000; + offset = 0x00803000; + page_size = 0x80; + readsize = 0x100; + ; + + memory "boot" + size = 0x1000; + offset = 0x00804000; + page_size = 0x80; + readsize = 0x100; + ; + + memory "flash" + size = 0x5000; + offset = 0x0800000; + page_size = 0x80; + readsize = 0x100; + ; + + memory "usersig" + size = 0x80; + offset = 0x8e0400; + page_size = 0x80; + readsize = 0x100; + ; +; + +#------------------------------------------------------------ +# ATxmega32E5 +#------------------------------------------------------------ + +part parent ".xmega" + id = "x32e5"; + desc = "ATxmega32E5"; + signature = 0x1e 0x95 0x4c; + + memory "eeprom" + size = 0x0400; + offset = 0x08c0000; + page_size = 0x20; + readsize = 0x100; + ; + + memory "application" + size = 0x8000; + offset = 0x0800000; + page_size = 0x80; + readsize = 0x100; + ; + + memory "apptable" + size = 0x1000; + offset = 0x00807000; + page_size = 0x80; + readsize = 0x100; + ; + + memory "boot" + size = 0x1000; + offset = 0x00808000; + page_size = 0x80; + readsize = 0x100; + ; + + memory "flash" + size = 0x9000; + offset = 0x0800000; + page_size = 0x80; + readsize = 0x100; + ; + + memory "usersig" + size = 0x80; + offset = 0x8e0400; + page_size = 0x80; + readsize = 0x100; + ; +; + +#------------------------------------------------------------ +# AVR32UC3A0512 +#------------------------------------------------------------ + +part + id = "uc3a0512"; + desc = "AT32UC3A0512"; + signature = 0xED 0xC0 0x3F; + has_jtag = yes; + is_avr32 = yes; + + memory "flash" + paged = yes; + page_size = 512; # bytes + readsize = 512; # bytes + num_pages = 1024; # could be set dynamicly + size = 0x00080000; # could be set dynamicly + offset = 0x80000000; + ; +; + +part parent "uc3a0512" + id = "ucr2"; + desc = "deprecated, use 'uc3a0512'"; +; + +#------------------------------------------------------------ +# ATtiny1634. +#------------------------------------------------------------ + +part + id = "t1634"; + desc = "ATtiny1634"; + has_debugwire = yes; + flash_instr = 0xB6, 0x01, 0x11; + eeprom_instr = 0xBD, 0xF2, 0xBD, 0xE1, 0xBB, 0xCF, 0xB4, 0x00, + 0xBE, 0x01, 0xB6, 0x01, 0xBC, 0x00, 0xBB, 0xBF, + 0x99, 0xF9, 0xBB, 0xAF; + stk500_devcode = 0x86; + # avr910_devcode = 0x; + signature = 0x1e 0x94 0x12; + pagel = 0xB3; + bs2 = 0xB1; + reset = io; + chip_erase_delay = 9000; + pgm_enable = "1 0 1 0 1 1 0 0 0 1 0 1 0 0 1 1", + "x x x x x x x x x x x x x x x x"; + + chip_erase = "1 0 1 0 1 1 0 0 1 0 0 x x x x x", + "x x x x x x x x x x x x x x x x"; + + timeout = 200; + stabdelay = 100; + cmdexedelay = 25; + synchloops = 32; + bytedelay = 0; + pollindex = 3; + pollvalue = 0x53; + predelay = 1; + postdelay = 1; + pollmethod = 1; + + pp_controlstack = + 0x0E, 0x1E, 0x0E, 0x1E, 0x2E, 0x3E, 0x2E, 0x3E, + 0x4E, 0x5E, 0x4E, 0x5E, 0x6E, 0x7E, 0x6E, 0x7E, + 0x26, 0x36, 0x66, 0x76, 0x2A, 0x3A, 0x6A, 0x7A, + 0x2E, 0xFD, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00; + hventerstabdelay = 100; + progmodedelay = 0; + latchcycles = 0; + togglevtg = 1; + poweroffdelay = 15; + resetdelayms = 1; + resetdelayus = 0; + hvleavestabdelay = 15; + resetdelay = 15; + chiperasepulsewidth = 0; + chiperasepolltimeout = 10; + programfusepulsewidth = 0; + programfusepolltimeout = 5; + programlockpulsewidth = 0; + programlockpolltimeout = 5; + + memory "eeprom" + paged = no; + page_size = 4; + size = 256; + min_write_delay = 3600; + max_write_delay = 3600; + readback_p1 = 0xff; + readback_p2 = 0xff; + read = " 1 0 1 0 0 0 0 0", + " 0 0 0 x x x x a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + write = " 1 1 0 0 0 0 0 0", + " 0 0 0 x x x x a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " i i i i i i i i"; + + loadpage_lo = " 1 1 0 0 0 0 0 1", + " 0 0 0 0 0 0 0 0", + " 0 0 0 0 0 0 a1 a0", + " i i i i i i i i"; + + writepage = " 1 1 0 0 0 0 1 0", + " 0 0 x x x x x a8", + " a7 a6 a5 a4 a3 a2 0 0", + " x x x x x x x x"; + + mode = 0x41; + delay = 5; + blocksize = 4; + readsize = 256; + ; + + memory "flash" + paged = yes; + size = 16384; + page_size = 32; + num_pages = 512; + min_write_delay = 4500; + max_write_delay = 4500; + readback_p1 = 0xff; + readback_p2 = 0xff; + read_lo = " 0 0 1 0 0 0 0 0", + " 0 0 0 a12 a11 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + read_hi = " 0 0 1 0 1 0 0 0", + " 0 0 0 a12 a11 a10 a9 a8", + " a7 a6 a5 a4 a3 a2 a1 a0", + " o o o o o o o o"; + + loadpage_lo = " 0 1 0 0 0 0 0 0", + " 0 0 0 x x x x x", + " x x a5 a4 a3 a2 a1 a0", + " i i i i i i i i"; + + loadpage_hi = " 0 1 0 0 1 0 0 0", + " 0 0 0 x x x x x", + " x x a5 a4 a3 a2 a1 a0", + " i i i i i i i i"; + + writepage = " 0 1 0 0 1 1 0 0", + " 0 0 0 a12 a11 a10 a9 a8", + " a7 a6 x x x x x x", + " x x x x x x x x"; + + mode = 0x41; + delay = 6; + blocksize = 128; + readsize = 256; + + ; + + memory "lfuse" + size = 1; + min_write_delay = 4500; + max_write_delay = 4500; + read = "0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0", + "x x x x x x x x o o o o o o o o"; + + write = "1 0 1 0 1 1 0 0 1 0 1 0 0 0 0 0", + "x x x x x x x x i i i i i i i i"; + ; + + memory "hfuse" + size = 1; + min_write_delay = 4500; + max_write_delay = 4500; + read = "0 1 0 1 1 0 0 0 0 0 0 0 1 0 0 0", + "x x x x x x x x o o o o o o o o"; + + write = "1 0 1 0 1 1 0 0 1 0 1 0 1 0 0 0", + "x x x x x x x x i i i i i i i i"; + ; + + memory "efuse" + size = 1; + min_write_delay = 4500; + max_write_delay = 4500; + read = "0 1 0 1 0 0 0 0 0 0 0 0 1 0 0 0", + "x x x x x x x x o o o o o o o o"; + + write = "1 0 1 0 1 1 0 0 1 0 1 0 0 1 0 0", + "x x x x x x x x x x x i i i i i"; + ; + + memory "lock" + size = 1; + min_write_delay = 4500; + max_write_delay = 4500; + read = "0 1 0 1 1 0 0 0 0 0 0 0 0 0 0 0", + "x x x x x x x x x x x x x x o o"; + + write = "1 0 1 0 1 1 0 0 1 1 1 x x x x x", + "x x x x x x x x 1 1 1 1 1 1 i i"; + ; + + memory "calibration" + size = 1; + read = "0 0 1 1 1 0 0 0 0 0 0 x x x x x", + "0 0 0 0 0 0 0 0 o o o o o o o o"; + ; + + memory "signature" + size = 3; + read = "0 0 1 1 0 0 0 0 0 0 0 x x x x x", + "x x x x x x a1 a0 o o o o o o o o"; + ; +; + +#------------------------------------------------------------ +# Common values for reduced core tinys (4/5/9/10/20/40) +#------------------------------------------------------------ + +part + id = ".reduced_core_tiny"; + desc = "Common values for reduced core tinys"; + has_tpi = yes; + + memory "signature" + size = 3; + offset = 0x3fc0; + page_size = 16; + ; + + memory "fuse" + size = 1; + offset = 0x3f40; + page_size = 16; + blocksize = 4; + ; + + memory "calibration" + size = 1; + offset = 0x3f80; + page_size = 16; + ; + + memory "lockbits" + size = 1; + offset = 0x3f00; + page_size = 16; + ; +; + +#------------------------------------------------------------ +# ATtiny4 +#------------------------------------------------------------ + +part parent ".reduced_core_tiny" + id = "t4"; + desc = "ATtiny4"; + signature = 0x1e 0x8f 0x0a; + + memory "flash" + size = 512; + offset = 0x4000; + page_size = 16; + blocksize = 128; + ; +; + +#------------------------------------------------------------ +# ATtiny5 +#------------------------------------------------------------ + +part parent "t4" + id = "t5"; + desc = "ATtiny5"; + signature = 0x1e 0x8f 0x09; +; + +#------------------------------------------------------------ +# ATtiny9 +#------------------------------------------------------------ + +part parent ".reduced_core_tiny" + id = "t9"; + desc = "ATtiny9"; + signature = 0x1e 0x90 0x08; + + memory "flash" + size = 1024; + offset = 0x4000; + page_size = 16; + blocksize = 128; + ; +; + +#------------------------------------------------------------ +# ATtiny10 +#------------------------------------------------------------ + +part parent "t9" + id = "t10"; + desc = "ATtiny10"; + signature = 0x1e 0x90 0x03; +; + +#------------------------------------------------------------ +# ATtiny20 +#------------------------------------------------------------ + +part parent ".reduced_core_tiny" + id = "t20"; + desc = "ATtiny20"; + signature = 0x1e 0x91 0x0F; + + memory "flash" + size = 2048; + offset = 0x4000; + page_size = 16; + blocksize = 128; + ; +; + +#------------------------------------------------------------ +# ATtiny40 +#------------------------------------------------------------ + +part parent ".reduced_core_tiny" + id = "t40"; + desc = "ATtiny40"; + signature = 0x1e 0x92 0x0E; + + memory "flash" + size = 4096; + offset = 0x4000; + page_size = 64; + blocksize = 128; + ; +; + +#------------------------------------------------------------ +# ATmega406 +#------------------------------------------------------------ + +part + id = "m406"; + desc = "ATMEGA406"; + has_jtag = yes; + signature = 0x1e 0x95 0x07; + + # STK500 parameters (parallel programming IO lines) + pagel = 0xa7; + bs2 = 0xa0; + serial = no; + parallel = yes; + + # STK500v2 HV programming parameters, from XML + pp_controlstack = 0x0e, 0x1e, 0x0f, 0x1f, 0x2e, 0x3e, 0x2f, 0x3f, + 0x4e, 0x5e, 0x4f, 0x5f, 0x6e, 0x7e, 0x6f, 0x7f, + 0x66, 0x76, 0x67, 0x77, 0x6a, 0x7a, 0x6b, 0x7b, + 0xbe, 0xfd, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00; + + # JTAG ICE mkII parameters, also from XML files + allowfullpagebitstream = no; + enablepageprogramming = yes; + idr = 0x51; + rampz = 0x00; + spmcr = 0x57; + eecr = 0x3f; + + memory "eeprom" + paged = no; + size = 512; + page_size = 4; + blocksize = 4; + readsize = 4; + num_pages = 128; + ; + + memory "flash" + paged = yes; + size = 40960; + page_size = 128; + blocksize = 128; + readsize = 128; + num_pages = 320; + ; + + memory "hfuse" + size = 1; + ; + + memory "lfuse" + size = 1; + ; + + memory "lockbits" + size = 1; + ; + + memory "signature" + size = 3; + ; +; + + diff --git a/ravedude/src/avrdude/mod.rs b/ravedude/src/avrdude/mod.rs new file mode 100644 index 0000000000..a4b3083c65 --- /dev/null +++ b/ravedude/src/avrdude/mod.rs @@ -0,0 +1,82 @@ +use anyhow::Context as _; +use std::path; +use std::process; + +#[derive(Debug)] +pub struct AvrdudeOptions<'a> { + pub programmer: &'a str, + pub partno: &'a str, + pub baudrate: Option, + pub do_chip_erase: bool, +} + +#[derive(Debug)] +pub struct Avrdude { + config: tempfile::NamedTempFile, + process: process::Child, +} + +impl Avrdude { + pub fn run( + options: &AvrdudeOptions, + port: Option>, + bin: &path::Path, + ) -> anyhow::Result { + let config = tempfile::Builder::new() + .prefix(".avrdude-") + .suffix(".conf") + .tempfile() + .unwrap(); + + { + use std::io::Write; + + let mut f = std::fs::File::create(&config).context("could not create avrdude.conf")?; + f.write_all(include_bytes!("avrdude.conf")) + .context("coult not write avrdude.conf")?; + f.flush().unwrap(); + } + + let mut command = process::Command::new("avrdude"); + let mut command = command + .arg("-C") + .arg(&config.as_ref()) + .arg("-c") + .arg(options.programmer) + .arg("-p") + .arg(options.partno); + + if let Some(port) = port { + command = command + .arg("-P") + .arg(port.as_ref()); + } + + if let Some(baudrate) = options.baudrate { + command = command.arg("-b").arg(baudrate.to_string()); + } + + // TODO: Check that `bin` does not contain : + let mut flash_instruction: std::ffi::OsString = "flash:w:".into(); + flash_instruction.push(bin); + flash_instruction.push(":e"); + + if options.do_chip_erase { + command = command.arg("-e"); + } + + command = command.arg("-D").arg("-U").arg(flash_instruction); + + let process = command.spawn().context("failed starting avrdude")?; + + Ok(Self { config, process }) + } + + pub fn wait(&mut self) -> anyhow::Result<()> { + let ret = self.process.wait()?; + if !ret.success() { + anyhow::bail!("avrdude failed"); + } + Ok(()) + } +} diff --git a/ravedude/src/board.rs b/ravedude/src/board.rs new file mode 100644 index 0000000000..3efe4cf4b0 --- /dev/null +++ b/ravedude/src/board.rs @@ -0,0 +1,272 @@ +use crate::avrdude; + +pub trait Board { + fn display_name(&self) -> &str; + fn needs_reset(&self) -> Option<&str>; + fn avrdude_options(&self) -> avrdude::AvrdudeOptions; + fn guess_port(&self) -> Option>; +} + +pub fn get_board(board: &str) -> Option> { + Some(match board { + "uno" => Box::new(ArduinoUno), + "nano" => Box::new(ArduinoNano), + "leonardo" => Box::new(ArduinoLeonardo), + "micro" => Box::new(ArduinoMicro), + "mega2560" => Box::new(ArduinoMega2560), + "diecimila" => Box::new(ArduinoDiecimila), + "promicro" => Box::new(SparkFunProMicro), + "trinket-pro" => Box::new(TrinketPro), + _ => return None, + }) +} + +// ---------------------------------------------------------------------------- + +fn find_port_from_vid_pid_list(list: &[(u16, u16)]) -> anyhow::Result { + for serialport::SerialPortInfo { + port_name, + port_type, + } in serialport::available_ports().unwrap() + { + if let serialport::SerialPortType::UsbPort(usb_info) = port_type { + for (vid, pid) in list.iter() { + if usb_info.vid == *vid && usb_info.pid == *pid { + return Ok(port_name.into()); + } + } + } + } + Err(anyhow::anyhow!("Serial port not found.")) +} + +// ---------------------------------------------------------------------------- + +struct ArduinoUno; + +impl Board for ArduinoUno { + fn display_name(&self) -> &str { + "Arduino Uno" + } + + fn needs_reset(&self) -> Option<&str> { + None + } + + fn avrdude_options(&self) -> avrdude::AvrdudeOptions { + avrdude::AvrdudeOptions { + programmer: "arduino", + partno: "atmega328p", + baudrate: None, + do_chip_erase: true, + } + } + + fn guess_port(&self) -> Option> { + Some(find_port_from_vid_pid_list(&[ + (0x2341, 0x0043), + (0x2341, 0x0001), + (0x2A03, 0x0043), + (0x2341, 0x0243), + ])) + } +} + +struct ArduinoMicro; + +impl Board for ArduinoMicro { + fn display_name(&self) -> &str { + "Arduino Micro" + } + + fn needs_reset(&self) -> Option<&str> { + Some("Reset the board by pressing the reset button once.") + } + + fn avrdude_options(&self) -> avrdude::AvrdudeOptions { + avrdude::AvrdudeOptions { + programmer: "avr109", + partno: "atmega32u4", + baudrate: Some(115200), + do_chip_erase: true, + } + } + + fn guess_port(&self) -> Option> { + Some(find_port_from_vid_pid_list(&[ + (0x2341, 0x0037), + (0x2341, 0x8037), + (0x2A03, 0x0037), + (0x2A03, 0x8037), + (0x2341, 0x0237), + (0x2341, 0x8237), + ])) + } +} + +struct ArduinoNano; + +impl Board for ArduinoNano { + fn display_name(&self) -> &str { + "Arduino Nano" + } + + fn needs_reset(&self) -> Option<&str> { + None + } + + fn avrdude_options(&self) -> avrdude::AvrdudeOptions { + avrdude::AvrdudeOptions { + programmer: "arduino", + partno: "atmega328p", + baudrate: Some(57600), + do_chip_erase: true, + } + } + + fn guess_port(&self) -> Option> { + Some(Err(anyhow::anyhow!("Not able to guess port"))) + } +} + +struct ArduinoLeonardo; + +impl Board for ArduinoLeonardo { + fn display_name(&self) -> &str { + "Arduino Leonardo" + } + + fn needs_reset(&self) -> Option<&str> { + Some("Reset the board by pressing the reset button once.") + } + + fn avrdude_options(&self) -> avrdude::AvrdudeOptions { + avrdude::AvrdudeOptions { + programmer: "avr109", + partno: "atmega32u4", + baudrate: None, + do_chip_erase: true, + } + } + + fn guess_port(&self) -> Option> { + Some(find_port_from_vid_pid_list(&[ + (0x2341, 0x0036), + (0x2341, 0x8036), + (0x2A03, 0x0036), + (0x2A03, 0x8036), + ])) + } +} + +struct ArduinoMega2560; + +impl Board for ArduinoMega2560 { + fn display_name(&self) -> &str { + "Arduino Mega 2560" + } + + fn needs_reset(&self) -> Option<&str> { + None + } + + fn avrdude_options(&self) -> avrdude::AvrdudeOptions { + avrdude::AvrdudeOptions { + programmer: "wiring", + partno: "atmega2560", + baudrate: Some(115200), + do_chip_erase: false, + } + } + + fn guess_port(&self) -> Option> { + Some(find_port_from_vid_pid_list(&[ + (0x2341, 0x0010), + (0x2341, 0x0042), + (0x2A03, 0x0010), + (0x2A03, 0x0042), + (0x2341, 0x0210), + (0x2341, 0x0242), + ])) + } +} + +struct ArduinoDiecimila; + +impl Board for ArduinoDiecimila { + fn display_name(&self) -> &str { + "Arduino Diecimila" + } + + fn needs_reset(&self) -> Option<&str> { + None + } + + fn avrdude_options(&self) -> avrdude::AvrdudeOptions { + avrdude::AvrdudeOptions { + programmer: "arduino", + partno: "atmega168", + baudrate: Some(19200), + do_chip_erase: false, + } + } + + fn guess_port(&self) -> Option> { + Some(Err(anyhow::anyhow!("Not able to guess port"))) + } +} + +struct SparkFunProMicro; + +impl Board for SparkFunProMicro { + fn display_name(&self) -> &str { + "SparkFun Pro Micro" + } + + fn needs_reset(&self) -> Option<&str> { + Some("Reset the board by quickly pressing the reset button **twice**.") + } + + fn avrdude_options(&self) -> avrdude::AvrdudeOptions { + avrdude::AvrdudeOptions { + programmer: "avr109", + partno: "atmega32u4", + baudrate: None, + do_chip_erase: true, + } + } + + fn guess_port(&self) -> Option> { + Some(find_port_from_vid_pid_list(&[ + (0x1B4F, 0x9205), //5V + (0x1B4F, 0x9206), //5V + (0x1B4F, 0x9203), //3.3V + (0x1B4F, 0x9204), //3.3V + ])) + } +} + +struct TrinketPro; + +impl Board for TrinketPro { + fn display_name(&self) -> &str { + "Trinket Pro" + } + + fn needs_reset(&self) -> Option<&str> { + Some("Reset the board by pressing the reset button once.") + } + + fn avrdude_options(&self) -> avrdude::AvrdudeOptions { + avrdude::AvrdudeOptions { + programmer: "usbtiny", + partno: "atmega328p", + baudrate: None, + do_chip_erase: false, + } + } + + fn guess_port(&self) -> Option> { + None // The TrinketPro does not have USB-to-Serial. + } +} diff --git a/ravedude/src/console.rs b/ravedude/src/console.rs new file mode 100644 index 0000000000..e513e4a057 --- /dev/null +++ b/ravedude/src/console.rs @@ -0,0 +1,35 @@ +use anyhow::Context as _; +use std::io::Read as _; +use std::io::Write as _; + +pub fn open(port: &std::path::Path, baudrate: u32) -> anyhow::Result<()> { + let mut rx = serialport::new(port.to_string_lossy(), baudrate) + .timeout(std::time::Duration::from_secs(2)) + .open_native() + .with_context(|| format!("failed to open serial port `{}`", port.display()))?; + let mut tx = rx.try_clone_native()?; + + let mut stdin = std::io::stdin(); + let mut stdout = std::io::stdout(); + + // Spawn a thread for the receiving end because stdio is not portably non-blocking... + std::thread::spawn(move || loop { + let mut buf = [0u8; 4098]; + match rx.read(&mut buf) { + Ok(count) => { + stdout.write(&buf[..count]).unwrap(); + stdout.flush().unwrap(); + } + Err(e) => { + assert!(e.kind() == std::io::ErrorKind::TimedOut); + } + } + }); + + loop { + let mut buf = [0u8; 4098]; + let count = stdin.read(&mut buf)?; + tx.write(&buf[..count])?; + tx.flush()?; + } +} diff --git a/ravedude/src/main.rs b/ravedude/src/main.rs new file mode 100644 index 0000000000..e1845be776 --- /dev/null +++ b/ravedude/src/main.rs @@ -0,0 +1,137 @@ +use anyhow::Context as _; +use colored::Colorize as _; +use structopt::clap::AppSettings; + +mod avrdude; +mod board; +mod console; +mod ui; + +/// ravedude is a rust wrapper around avrdude for providing the smoothest possible development +/// experience with rust on AVR microcontrollers. +/// +/// ravedude is primarily intended to be used as a "runner" in the cargo configuration. +#[derive(structopt::StructOpt, Debug)] +#[structopt(name = "ravedude", + setting = AppSettings::ColoredHelp, + setting = AppSettings::DeriveDisplayOrder, + version = git_version::git_version!( + args = ["--always", "--dirty", "--abbrev=12"], + cargo_prefix = "v", + cargo_suffix = " (no git)", + fallback = "unknown" + ))] +struct Args { + /// After sucessfully flashing the program, open a serial console to see output sent by the + /// board and possibly interact with it. + #[structopt(short = "c", long = "open-console")] + open_console: bool, + + /// Baudrate which should be used for the serial console. + #[structopt(short = "b", long = "baudrate")] + baudrate: Option, + + /// Overwrite which port to use. By default ravedude will try to find a connected board by + /// itself. + #[structopt(short = "P", long = "port", parse(from_os_str), env = "RAVEDUDE_PORT")] + port: Option, + + /// Which board to interact with. + /// + /// Must be one of the known board identifiers: + /// + /// * uno + /// * micro + /// * nano + /// * leonardo + /// * mega2560 + #[structopt(name = "BOARD", verbatim_doc_comment)] + board: String, + + /// The binary to be flashed. + /// + /// If no binary is given, flashing will be skipped. + #[structopt(name = "BINARY", parse(from_os_str))] + bin: Option, +} + +fn main() { + match ravedude() { + Ok(()) => (), + Err(e) => { + ui::print_error(e); + std::process::exit(1); + } + } +} + +fn ravedude() -> anyhow::Result<()> { + let args: Args = structopt::StructOpt::from_args(); + + let board = board::get_board(&args.board).expect("board not found"); + + task_message!("Board", "{}", board.display_name()); + + if let Some(msg) = board.needs_reset() { + warning!("this board cannot reset itself."); + eprintln!(""); + eprintln!(" {}", msg); + eprintln!(""); + eprint!("Once reset, press ENTER here: "); + std::io::stdin().read_line(&mut String::new())?; + } + + let port = match args.port { + Some(port) => Ok(Some(port)), + None => match board.guess_port() { + Some(Ok(port)) => Ok(Some(port)), + p @ Some(Err(_)) => p.transpose().context("no matching serial port found, use -P or set RAVEDUDE_PORT in your environment"), + None => Ok(None), + } + }?; + + + if let Some(bin) = args.bin.as_ref() { + if let Some(port) = port.as_ref() { + task_message!( + "Programming", + "{} {} {}", + bin.display(), + "=>".blue().bold(), + port.display() + ); + } else { + task_message!( + "Programming", + "{}", + bin.display(), + ); + } + + let mut avrdude = avrdude::Avrdude::run(&board.avrdude_options(), port.as_ref(), bin)?; + avrdude.wait()?; + + task_message!("Programmed", "{}", bin.display()); + } else { + task_message!( + "", + "{}", + "(Skip flashing because no binary was given)".dimmed() + ); + } + + if args.open_console { + let baudrate = args + .baudrate + .context("-b/--baudrate is needed for the serial console")?; + + let port = port.context("console can only be opened for devices with USB-to-Serial")?; + + task_message!("Console", "{} at {} baud", port.display(), baudrate); + console::open(&port, baudrate)?; + } else if args.bin.is_none() && port.is_some() { + warning!("you probably meant to add -c/--open-console?"); + } + + Ok(()) +} diff --git a/ravedude/src/ui.rs b/ravedude/src/ui.rs new file mode 100644 index 0000000000..bde33fb14e --- /dev/null +++ b/ravedude/src/ui.rs @@ -0,0 +1,39 @@ +/// Emit a message in the cargo style with a green "verb" up front and some text afterwards. +#[macro_export] +macro_rules! task_message { + ($verb:expr, $($fmt:tt)+) => { + eprint!("{:>12} ", colored::Colorize::bold(colored::Colorize::green($verb))); + eprintln!($($fmt)+); + }; +} + +#[macro_export] +macro_rules! warning { + ($($fmt:tt)+) => { + eprint!("{}", colored::Colorize::bold(colored::Colorize::yellow("Warning"))); + eprint!("{}", colored::Colorize::bold(": ")); + eprintln!("{}", colored::Colorize::bold(&*format!($($fmt)+))); + }; +} + +pub fn print_error(e: anyhow::Error) { + use colored::Colorize as _; + + eprintln!( + "{}{}{}", + "Error".red().bold(), + ": ".bold(), + e.to_string().bold() + ); + + eprintln!(""); + + for cause in e.chain().skip(1) { + eprintln!( + "{}{}{}", + "Caused by".yellow().bold(), + ": ".bold(), + cause.to_string().bold() + ); + } +} diff --git a/rust-toolchain.toml b/rust-toolchain.toml new file mode 100644 index 0000000000..66d37572aa --- /dev/null +++ b/rust-toolchain.toml @@ -0,0 +1,4 @@ +[toolchain] +channel = "nightly-2021-01-07" +components = [ "rust-src" ] +profile = "minimal" \ No newline at end of file