├── .dockerignore ├── .github └── workflows │ └── docker-image.yml ├── .gitignore ├── Cargo.toml ├── Dockerfile.ci ├── LICENSE-APACHE ├── LICENSE-MIT ├── README.md ├── avr-atmega328p.json ├── build.rs ├── core_generator ├── Cargo.toml └── src │ ├── gen.rs │ └── main.rs ├── examples ├── spi.rs └── uart.rs ├── regenerate-cores.sh └── src ├── .gitignore ├── cores ├── .gitkeep ├── atmega168.rs ├── atmega168a.rs ├── atmega168p.rs ├── atmega168pa.rs ├── atmega328.rs ├── atmega328p.rs ├── atmega48.rs ├── atmega48a.rs ├── atmega48p.rs ├── atmega48pa.rs ├── atmega88.rs ├── atmega88a.rs ├── atmega88p.rs ├── atmega88pa.rs └── mod.rs ├── interrupt.rs ├── legacy ├── mod.rs └── serial.rs ├── lib.rs ├── modules ├── mod.rs ├── spi │ ├── clock.rs │ ├── mod.rs │ └── settings.rs ├── timer │ ├── mod.rs │ ├── timer16.rs │ └── timer8.rs └── usart.rs ├── pin.rs ├── prelude.rs └── register.rs /.dockerignore: -------------------------------------------------------------------------------- 1 | target/ 2 | Dockerfile 3 | 4 | -------------------------------------------------------------------------------- /.github/workflows/docker-image.yml: -------------------------------------------------------------------------------- 1 | name: Test suite 2 | 3 | 4 | on: 5 | push: 6 | branches: [ master ] 7 | pull_request: 8 | branches: [ master ] 9 | schedule: 10 | - cron: "0 2 * * 1-5" 11 | 12 | jobs: 13 | build: 14 | runs-on: ubuntu-latest 15 | 16 | steps: 17 | - uses: actions/checkout@v2 18 | - name: Prepare the AVR Rust build environment 19 | run: 20 | docker build . --file Dockerfile.ci --tag avr-rust/ruduino.ci:$GITHUB_RUN_NUMBER 21 | 22 | - name: Compile the crate 23 | run: 24 | docker run avr-rust/ruduino.ci:$GITHUB_RUN_NUMBER 25 | 26 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | Cargo.lock 2 | target/ 3 | -------------------------------------------------------------------------------- /Cargo.toml: -------------------------------------------------------------------------------- 1 | [workspace] 2 | members = [ 3 | ".", 4 | "./core_generator", 5 | ] 6 | 7 | [package] 8 | name = "ruduino" 9 | version = "0.4.0" 10 | edition = "2018" 11 | authors = [ 12 | "The AVR-Rust Project Developers", 13 | "Jake Goulding ", 14 | "Dylan McKay ", 15 | ] 16 | 17 | license = "MIT/Apache-2.0" 18 | readme = "README.md" 19 | repository = "https://github.com/avr-rust/ruduino" 20 | description = """ 21 | Reusable components for AVR microcontrollers 22 | """ 23 | 24 | keywords = ["avr", "arduino", "uno"] 25 | 26 | [features] 27 | default = ["avr-std-stub"] 28 | all-mcus = [] 29 | 30 | [dependencies] 31 | avr-config = { version = "2.0", features = ["cpu-frequency"] } 32 | avr_delay = { git = "https://github.com/avr-rust/delay", rev = "849918a8dfb2" } 33 | avr-std-stub = { version = "1.0", optional = true } 34 | const_env--value = "0.1" 35 | target-cpu-macro = "0.1" 36 | 37 | [build-dependencies] 38 | avr-mcu = "0.3" 39 | 40 | [package.metadata.docs.rs] 41 | all-features = true # we specifically want to enable 'all-mcus' for documentation 42 | -------------------------------------------------------------------------------- /Dockerfile.ci: -------------------------------------------------------------------------------- 1 | FROM ubuntu:18.04 2 | 3 | RUN useradd -m avr-rust 4 | 5 | # Install dependencies 6 | RUN apt-get update -y && apt-get install -y wget gcc binutils gcc-avr avr-libc 7 | 8 | RUN mkdir -p /code && chown avr-rust:avr-rust /code 9 | 10 | USER avr-rust 11 | 12 | # Install Rustup along with nightly 13 | RUN wget -q https://sh.rustup.rs -O /tmp/rustup.sh && sh /tmp/rustup.sh -y --profile minimal --default-toolchain nightly -c rust-src --quiet 14 | ENV PATH=/home/avr-rust/.cargo/bin:$PATH 15 | 16 | COPY --chown=avr-rust:avr-rust . /code/ruduino 17 | 18 | WORKDIR /code/ruduino 19 | ENV AVR_CPU_FREQUENCY_HZ=16000000 20 | 21 | CMD ["cargo", "build", "-Z", "build-std=core", "--target", "avr-atmega328p.json", "--release"] 22 | -------------------------------------------------------------------------------- /LICENSE-APACHE: -------------------------------------------------------------------------------- 1 | Apache License 2 | Version 2.0, January 2004 3 | http://www.apache.org/licenses/ 4 | 5 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 6 | 7 | 1. Definitions. 8 | 9 | "License" shall mean the terms and conditions for use, reproduction, 10 | and distribution as defined by Sections 1 through 9 of this document. 11 | 12 | "Licensor" shall mean the copyright owner or entity authorized by 13 | the copyright owner that is granting the License. 14 | 15 | "Legal Entity" shall mean the union of the acting entity and all 16 | other entities that control, are controlled by, or are under common 17 | control with that entity. For the purposes of this definition, 18 | "control" means (i) the power, direct or indirect, to cause the 19 | direction or management of such entity, whether by contract or 20 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 21 | outstanding shares, or (iii) beneficial ownership of such entity. 22 | 23 | "You" (or "Your") shall mean an individual or Legal Entity 24 | exercising permissions granted by this License. 25 | 26 | "Source" form shall mean the preferred form for making modifications, 27 | including but not limited to software source code, documentation 28 | source, and configuration files. 29 | 30 | "Object" form shall mean any form resulting from mechanical 31 | transformation or translation of a Source form, including but 32 | not limited to compiled object code, generated documentation, 33 | and conversions to other media types. 34 | 35 | "Work" shall mean the work of authorship, whether in Source or 36 | Object form, made available under the License, as indicated by a 37 | copyright notice that is included in or attached to the work 38 | (an example is provided in the Appendix below). 39 | 40 | "Derivative Works" shall mean any work, whether in Source or Object 41 | form, that is based on (or derived from) the Work and for which the 42 | editorial revisions, annotations, elaborations, or other modifications 43 | represent, as a whole, an original work of authorship. For the purposes 44 | of this License, Derivative Works shall not include works that remain 45 | separable from, or merely link (or bind by name) to the interfaces of, 46 | the Work and Derivative Works thereof. 47 | 48 | "Contribution" shall mean any work of authorship, including 49 | the original version of the Work and any modifications or additions 50 | to that Work or Derivative Works thereof, that is intentionally 51 | submitted to Licensor for inclusion in the Work by the copyright owner 52 | or by an individual or Legal Entity authorized to submit on behalf of 53 | the copyright owner. For the purposes of this definition, "submitted" 54 | means any form of electronic, verbal, or written communication sent 55 | to the Licensor or its representatives, including but not limited to 56 | communication on electronic mailing lists, source code control systems, 57 | and issue tracking systems that are managed by, or on behalf of, the 58 | Licensor for the purpose of discussing and improving the Work, but 59 | excluding communication that is conspicuously marked or otherwise 60 | designated in writing by the copyright owner as "Not a Contribution." 61 | 62 | "Contributor" shall mean Licensor and any individual or Legal Entity 63 | on behalf of whom a Contribution has been received by Licensor and 64 | subsequently incorporated within the Work. 65 | 66 | 2. Grant of Copyright License. Subject to the terms and conditions of 67 | this License, each Contributor hereby grants to You a perpetual, 68 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 69 | copyright license to reproduce, prepare Derivative Works of, 70 | publicly display, publicly perform, sublicense, and distribute the 71 | Work and such Derivative Works in Source or Object form. 72 | 73 | 3. Grant of Patent License. Subject to the terms and conditions of 74 | this License, each Contributor hereby grants to You a perpetual, 75 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 76 | (except as stated in this section) patent license to make, have made, 77 | use, offer to sell, sell, import, and otherwise transfer the Work, 78 | where such license applies only to those patent claims licensable 79 | by such Contributor that are necessarily infringed by their 80 | Contribution(s) alone or by combination of their Contribution(s) 81 | with the Work to which such Contribution(s) was submitted. If You 82 | institute patent litigation against any entity (including a 83 | cross-claim or counterclaim in a lawsuit) alleging that the Work 84 | or a Contribution incorporated within the Work constitutes direct 85 | or contributory patent infringement, then any patent licenses 86 | granted to You under this License for that Work shall terminate 87 | as of the date such litigation is filed. 88 | 89 | 4. Redistribution. You may reproduce and distribute copies of the 90 | Work or Derivative Works thereof in any medium, with or without 91 | modifications, and in Source or Object form, provided that You 92 | meet the following conditions: 93 | 94 | (a) You must give any other recipients of the Work or 95 | Derivative Works a copy of this License; and 96 | 97 | (b) You must cause any modified files to carry prominent notices 98 | stating that You changed the files; and 99 | 100 | (c) You must retain, in the Source form of any Derivative Works 101 | that You distribute, all copyright, patent, trademark, and 102 | attribution notices from the Source form of the Work, 103 | excluding those notices that do not pertain to any part of 104 | the Derivative Works; and 105 | 106 | (d) If the Work includes a "NOTICE" text file as part of its 107 | distribution, then any Derivative Works that You distribute must 108 | include a readable copy of the attribution notices contained 109 | within such NOTICE file, excluding those notices that do not 110 | pertain to any part of the Derivative Works, in at least one 111 | of the following places: within a NOTICE text file distributed 112 | as part of the Derivative Works; within the Source form or 113 | documentation, if provided along with the Derivative Works; or, 114 | within a display generated by the Derivative Works, if and 115 | wherever such third-party notices normally appear. The contents 116 | of the NOTICE file are for informational purposes only and 117 | do not modify the License. You may add Your own attribution 118 | notices within Derivative Works that You distribute, alongside 119 | or as an addendum to the NOTICE text from the Work, provided 120 | that such additional attribution notices cannot be construed 121 | as modifying the License. 122 | 123 | You may add Your own copyright statement to Your modifications and 124 | may provide additional or different license terms and conditions 125 | for use, reproduction, or distribution of Your modifications, or 126 | for any such Derivative Works as a whole, provided Your use, 127 | reproduction, and distribution of the Work otherwise complies with 128 | the conditions stated in this License. 129 | 130 | 5. Submission of Contributions. Unless You explicitly state otherwise, 131 | any Contribution intentionally submitted for inclusion in the Work 132 | by You to the Licensor shall be under the terms and conditions of 133 | this License, without any additional terms or conditions. 134 | Notwithstanding the above, nothing herein shall supersede or modify 135 | the terms of any separate license agreement you may have executed 136 | with Licensor regarding such Contributions. 137 | 138 | 6. Trademarks. This License does not grant permission to use the trade 139 | names, trademarks, service marks, or product names of the Licensor, 140 | except as required for reasonable and customary use in describing the 141 | origin of the Work and reproducing the content of the NOTICE file. 142 | 143 | 7. Disclaimer of Warranty. Unless required by applicable law or 144 | agreed to in writing, Licensor provides the Work (and each 145 | Contributor provides its Contributions) on an "AS IS" BASIS, 146 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 147 | implied, including, without limitation, any warranties or conditions 148 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 149 | PARTICULAR PURPOSE. You are solely responsible for determining the 150 | appropriateness of using or redistributing the Work and assume any 151 | risks associated with Your exercise of permissions under this License. 152 | 153 | 8. Limitation of Liability. In no event and under no legal theory, 154 | whether in tort (including negligence), contract, or otherwise, 155 | unless required by applicable law (such as deliberate and grossly 156 | negligent acts) or agreed to in writing, shall any Contributor be 157 | liable to You for damages, including any direct, indirect, special, 158 | incidental, or consequential damages of any character arising as a 159 | result of this License or out of the use or inability to use the 160 | Work (including but not limited to damages for loss of goodwill, 161 | work stoppage, computer failure or malfunction, or any and all 162 | other commercial damages or losses), even if such Contributor 163 | has been advised of the possibility of such damages. 164 | 165 | 9. Accepting Warranty or Additional Liability. While redistributing 166 | the Work or Derivative Works thereof, You may choose to offer, 167 | and charge a fee for, acceptance of support, warranty, indemnity, 168 | or other liability obligations and/or rights consistent with this 169 | License. However, in accepting such obligations, You may act only 170 | on Your own behalf and on Your sole responsibility, not on behalf 171 | of any other Contributor, and only if You agree to indemnify, 172 | defend, and hold each Contributor harmless for any liability 173 | incurred by, or claims asserted against, such Contributor by reason 174 | of your accepting any such warranty or additional liability. 175 | 176 | END OF TERMS AND CONDITIONS 177 | 178 | APPENDIX: How to apply the Apache License to your work. 179 | 180 | To apply the Apache License to your work, attach the following 181 | boilerplate notice, with the fields enclosed by brackets "[]" 182 | replaced with your own identifying information. (Don't include 183 | the brackets!) The text should be enclosed in the appropriate 184 | comment syntax for the file format. We also recommend that a 185 | file or class name and description of purpose be included on the 186 | same "printed page" as the copyright notice for easier 187 | identification within third-party archives. 188 | 189 | Copyright [yyyy] [name of copyright owner] 190 | 191 | Licensed under the Apache License, Version 2.0 (the "License"); 192 | you may not use this file except in compliance with the License. 193 | You may obtain a copy of the License at 194 | 195 | http://www.apache.org/licenses/LICENSE-2.0 196 | 197 | Unless required by applicable law or agreed to in writing, software 198 | distributed under the License is distributed on an "AS IS" BASIS, 199 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 200 | See the License for the specific language governing permissions and 201 | limitations under the License. 202 | -------------------------------------------------------------------------------- /LICENSE-MIT: -------------------------------------------------------------------------------- 1 | Copyright (c) 2016 The AVR-Rust Project Developers 2 | 3 | Permission is hereby granted, free of charge, to any 4 | person obtaining a copy of this software and associated 5 | documentation files (the "Software"), to deal in the 6 | Software without restriction, including without 7 | limitation the rights to use, copy, modify, merge, 8 | publish, distribute, sublicense, and/or sell copies of 9 | the Software, and to permit persons to whom the Software 10 | is furnished to do so, subject to the following 11 | conditions: 12 | 13 | The above copyright notice and this permission notice 14 | shall be included in all copies or substantial portions 15 | of the Software. 16 | 17 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF 18 | ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED 19 | TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A 20 | PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT 21 | SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY 22 | CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 23 | OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR 24 | IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 25 | DEALINGS IN THE SOFTWARE. 26 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Ruduino 2 | 3 | This library provides a set of reusable components for the Arduino Uno. 4 | 5 | ## Overview 6 | 7 | ### Register and bit definitions 8 | 9 | ```rust 10 | use ruduino::cores::current::PORTB; // Register 11 | use ruduino::cores::current::PORTB7; // Pin 12 | ``` 13 | 14 | ### Prelude 15 | 16 | Disable interrupts. 17 | 18 | ```rust 19 | without_interrupts(|| { 20 | unsafe { write_volatile(DDRB, 0xFF) } 21 | }) 22 | ``` 23 | 24 | ### Timers 25 | 26 | Configure a timer. 27 | 28 | ```rust 29 | const DESIRED_HZ_TIM1: f64 = 2.0; 30 | const TIM1_PRESCALER: u64 = 1024; 31 | const INTERRUPT_EVERY_1_HZ_1024_PRESCALER: u16 = 32 | ((ruduino::config::CPU_FREQUENCY_HZ as f64 / (DESIRED_HZ_TIM1 * TIM1_PRESCALER as f64)) as u64 - 1) as u16; 33 | 34 | timer1::Timer::new() 35 | .waveform_generation_mode(timer1::WaveformGenerationMode::ClearOnTimerMatchOutputCompare) 36 | .clock_source(timer1::ClockSource::Prescale1024) 37 | .output_compare_1(Some(INTERRUPT_EVERY_1_HZ_1024_PRESCALER)) 38 | .configure(); 39 | ``` 40 | 41 | Set up an interrupt handler that will be called when the timer fires. 42 | 43 | ```rust 44 | #[no_mangle] 45 | pub unsafe extern "avr-interrupt" fn _ivr_timer1_compare_a() { 46 | let prev_value = read_volatile(PORTB); 47 | write_volatile(PORTB, prev_value ^ PINB5); 48 | } 49 | ``` 50 | 51 | ### Hardware Serial Port 52 | 53 | Configure the serial port. 54 | 55 | ```rust 56 | const BAUD: u64 = 9600; 57 | const UBRR: u16 = (ruduino::config::CPU_FREQUENCY_HZ / 16 / BAUD - 1) as u16; 58 | 59 | serial::Serial::new(UBRR) 60 | .character_size(serial::CharacterSize::EightBits) 61 | .mode(serial::Mode::Asynchronous) 62 | .parity(serial::Parity::Disabled) 63 | .stop_bits(serial::StopBits::OneBit) 64 | .configure(); 65 | ``` 66 | 67 | Transmit a sequence of bytes. 68 | 69 | ```rust 70 | for &b in b"OK" { 71 | serial::transmit(b); 72 | } 73 | ``` 74 | 75 | Read a byte if there's something available. 76 | 77 | ```rust 78 | if let Some(b) = serial::try_receive() { 79 | serial::transmit(b); 80 | serial::transmit(b); 81 | } 82 | ``` 83 | 84 | -------------------------------------------------------------------------------- /avr-atmega328p.json: -------------------------------------------------------------------------------- 1 | { 2 | "arch": "avr", 3 | "cpu": "atmega328p", 4 | "data-layout": "e-P1-p:16:8-i8:8-i16:8-i32:8-i64:8-f32:8-f64:8-n8-a:8", 5 | "env": "", 6 | "executables": true, 7 | "linker": "avr-gcc", 8 | "linker-flavor": "gcc", 9 | "linker-is-gnu": true, 10 | "llvm-target": "avr-unknown-unknown", 11 | "os": "unknown", 12 | "position-independent-executables": false, 13 | "exe-suffix": ".elf", 14 | "eh-frame-header": false, 15 | "pre-link-args": { 16 | "gcc": [ 17 | "-Os", 18 | "-mmcu=atmega328p" 19 | ] 20 | }, 21 | "late-link-args": { 22 | "gcc": [ 23 | "-lc", 24 | "-lgcc" 25 | ] 26 | }, 27 | "target-c-int-width": "16", 28 | "target-endian": "little", 29 | "target-pointer-width": "16", 30 | "vendor": "unknown" 31 | } 32 | -------------------------------------------------------------------------------- /build.rs: -------------------------------------------------------------------------------- 1 | const DEFAULT_MCU_FOR_NON_AVR_DOCS: &'static str = "atmega328"; 2 | 3 | fn main() { 4 | let current_mcu = if avr_mcu::current::is_compiling_for_avr() { 5 | avr_mcu::current::mcu() 6 | .expect("no target cpu specified") 7 | } else { 8 | avr_mcu::microcontroller(DEFAULT_MCU_FOR_NON_AVR_DOCS) 9 | }; 10 | let current_mcu_name = current_mcu.device.name.clone().to_lowercase(); 11 | 12 | println!("cargo:rustc-cfg=avr_mcu_{}", ¤t_mcu_name); 13 | } 14 | -------------------------------------------------------------------------------- /core_generator/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "ruduino-core-generator" 3 | version = "0.0.0" # not versioned 4 | publish = false 5 | edition = "2018" 6 | authors = [ 7 | "The AVR-Rust Project Developers", 8 | "Jake Goulding ", 9 | "Dylan McKay ", 10 | ] 11 | 12 | license = "MIT/Apache-2.0" 13 | readme = "README.md" 14 | repository = "https://github.com/avr-rust/ruduino" 15 | 16 | [[bin]] 17 | name = "ruduino-core-generator" 18 | path = "src/main.rs" 19 | 20 | [dependencies] 21 | avr-mcu = "0.3" 22 | target-cpu-fetch = "0.1" 23 | -------------------------------------------------------------------------------- /core_generator/src/gen.rs: -------------------------------------------------------------------------------- 1 | use avr_mcu::*; 2 | use std::io; 3 | use std::io::prelude::*; 4 | 5 | pub fn write_registers(mcu: &Mcu, w: &mut dyn Write) -> Result<(), io::Error> { 6 | for register in mcu.registers() { 7 | let ty = if register.size == 1 { "u8" } else { "u16" }; 8 | 9 | // HACK: Skip, atmeg328p pack defines two of these. 10 | if register.name == "GTCCR" { continue; } 11 | 12 | writeln!(w, "#[allow(non_camel_case_types)]")?; 13 | writeln!(w, "pub struct {};", register.name)?; 14 | writeln!(w)?; 15 | 16 | writeln!(w, "impl {} {{", register.name)?; 17 | for bitfield in register.bitfields.iter() { 18 | // Create a mask for the whole bitset. 19 | writeln!(w, " pub const {}: RegisterBits = RegisterBits::new(0x{:x});", bitfield.name, bitfield.mask)?; 20 | 21 | // We create masks for the individual bits in the field if there 22 | // is more than one bit in the field. 23 | let mut current_mask = bitfield.mask; 24 | let mut current_mask_bit_num = 0; 25 | for current_register_bit_num in 0..15 { 26 | if (current_mask & 0b1) == 0b1 { 27 | writeln!(w, " pub const {}{}: RegisterBits = RegisterBits::new(1<<{});", 28 | bitfield.name, current_mask_bit_num, current_register_bit_num)?; 29 | current_mask_bit_num += 1; 30 | } 31 | 32 | current_mask >>= 1; 33 | } 34 | writeln!(w)?; 35 | } 36 | writeln!(w, "}}")?; 37 | writeln!(w)?; 38 | 39 | writeln!(w, "impl Register for {} {{", register.name)?; 40 | writeln!(w, " type T = {};", ty)?; 41 | writeln!(w, " const ADDRESS: *mut {} = 0x{:x} as *mut {};", ty, register.offset, ty)?; 42 | writeln!(w, "}}")?; 43 | } 44 | 45 | Ok(()) 46 | } 47 | 48 | pub fn write_pins(mcu: &Mcu, w: &mut dyn Write) -> Result<(), io::Error> { 49 | if let Some(port) = mcu.peripheral("PORT") { 50 | writeln!(w, "pub mod port {{")?; 51 | writeln!(w, " #![allow(unused_imports)]")?; 52 | writeln!(w)?; 53 | writeln!(w, " use super::*;")?; 54 | writeln!(w, " use crate::Pin;")?; 55 | writeln!(w)?; 56 | 57 | for instance in port.instances.iter() { 58 | let port_letter = instance.name.chars().rev().next().unwrap(); 59 | 60 | for signal in instance.signals.iter() { 61 | let idx = signal.index.expect("signal with no index"); 62 | let struct_name = format!("{}{}", port_letter, idx); 63 | 64 | let io_module = mcu.modules.iter().find(|m| m.name == "PORT") 65 | .expect("no port io module defined for this port"); 66 | let register_group = io_module.register_groups.iter() 67 | .find(|rg| rg.name == instance.name) 68 | .expect("no register group defined for this port"); 69 | 70 | writeln!(w, " pub struct {};", struct_name)?; 71 | writeln!(w)?; 72 | writeln!(w, " impl Pin for {} {{", struct_name)?; 73 | for reg in register_group.registers.iter() { 74 | let mut const_name = reg.name.clone(); 75 | const_name.pop(); // Pop port character from register name (DDRB/PORTB/etc).. 76 | 77 | writeln!(w, " /// {}.", reg.caption)?; 78 | writeln!(w, " type {} = {};", const_name, reg.name)?; 79 | } 80 | writeln!(w, " /// {}", signal.pad)?; 81 | writeln!(w, " const MASK: u8 = 1<<{};", idx)?; 82 | writeln!(w, " }}")?; 83 | writeln!(w)?; 84 | } 85 | } 86 | 87 | writeln!(w, "}}")?; 88 | writeln!(w)?; 89 | } 90 | Ok(()) 91 | } 92 | 93 | pub fn write_spi_modules(mcu: &Mcu, w: &mut dyn Write) -> Result<(), io::Error> { 94 | if let Some(module) = mcu.module("SPI") { 95 | let peripheral = mcu.peripheral("SPI").expect("found SPI module but no peripheral"); 96 | let port_peripheral = mcu.port_peripheral(); 97 | 98 | writeln!(w, "pub struct Spi;")?; 99 | writeln!(w)?; 100 | writeln!(w, "impl modules::HardwareSpi for Spi {{")?; 101 | 102 | for spi_signal in peripheral.signals() { 103 | let spi_signal_name = spi_signal.group.clone().expect("spi signal does not have group name"); 104 | let (port_instance, port_signal) = port_peripheral.instance_signal_with_pad(&spi_signal.pad) 105 | .expect("no port signal associated with the spi signal pad"); 106 | let pin_name = self::pin_name(port_instance, port_signal); 107 | 108 | let const_name = match &spi_signal_name[..] { 109 | "MISO" => "MasterInSlaveOut", 110 | "MOSI" => "MasterOutSlaveIn", 111 | "SCK" => "Clock", 112 | "SS" => "SlaveSelect", 113 | _ => panic!("unknown spi signal name: '{}'", spi_signal_name), 114 | }; 115 | 116 | writeln!(w, " type {} = {};", const_name, pin_name)?; 117 | } 118 | 119 | for reg in module.registers() { 120 | let const_name = match ®.caption[..] { 121 | "SPI Data Register" => "DataRegister", 122 | "SPI Status Register" => "StatusRegister", 123 | "SPI Control Register" => "ControlRegister", 124 | _ => panic!("unknown SPI module register: {}", reg.caption), 125 | }; 126 | 127 | writeln!(w, " type {} = {};", const_name, reg.name)?; 128 | } 129 | writeln!(w, "}}")?; 130 | writeln!(w)?; 131 | } 132 | Ok(()) 133 | } 134 | 135 | pub fn write_usarts(mcu: &Mcu, w: &mut dyn Write) -> Result<(), io::Error> { 136 | if let Some(module) = mcu.module("USART") { 137 | for usart in module.register_groups.iter() { 138 | writeln!(w, "/// The {} module.", usart.name)?; 139 | writeln!(w, "pub struct {};", usart.name)?; 140 | writeln!(w)?; 141 | writeln!(w, "impl modules::HardwareUsart for {} {{", usart.name)?; 142 | for register in usart.registers.iter() { 143 | let reg_ty = if register.name.starts_with("UDR") { // the data register. 144 | "DataRegister".to_owned() 145 | } else if register.name.starts_with("UCSR") { // one of the three control/status registers. 146 | let suffix = register.name.chars().rev().next().unwrap(); 147 | format!("ControlRegister{}", suffix) 148 | } else if register.name.starts_with("UBRR") { // the baud rate register. 149 | "BaudRateRegister".to_owned() 150 | } else { 151 | panic!("unknown usart register '{}'", register.name); 152 | }; 153 | writeln!(w, " type {} = {};", reg_ty, register.name)?; 154 | } 155 | writeln!(w, "}}")?; 156 | writeln!(w)?; 157 | } 158 | } 159 | Ok(()) 160 | } 161 | 162 | pub fn write_timers(mcu: &Mcu, w: &mut dyn Write) -> Result<(), io::Error> { 163 | if let Some(tc) = mcu.module("TC8") { // Timer/Counter, 8-bit. 164 | const TYPE_NAME: &'static str = "Timer8"; 165 | 166 | let find_reg = |name: &'static str| { 167 | tc.registers().find(|r| r.name.starts_with(name)) 168 | .expect(&format!("could not find '{}' register", name)) 169 | }; 170 | let find_reg_suffix_optional = |name: &'static str, suffix: &'static str| { 171 | tc.registers().find(|r| r.name.starts_with(name) && r.name.ends_with(suffix)) 172 | }; 173 | let find_reg_suffix = |name: &'static str, suffix: &'static str| { 174 | find_reg_suffix_optional(name, suffix) 175 | .expect(&format!("could not find '{}' register", name)) 176 | }; 177 | let timer_number = find_reg("TIMSK").name.chars().last().unwrap() 178 | .to_digit(10).unwrap(); 179 | 180 | // TODO: At the moment, we do not support 8 bit timers that don't have two compare 181 | // registers. 182 | let should_skip_timer = find_reg_suffix_optional("OCR", "B").is_none(); 183 | 184 | if !should_skip_timer { 185 | writeln!(w, "/// 8-bit timer.")?; 186 | writeln!(w, "pub struct {};", TYPE_NAME)?; 187 | writeln!(w)?; 188 | writeln!(w, "impl modules::Timer8 for {} {{", TYPE_NAME)?; 189 | writeln!(w, " type CompareA = {};", find_reg_suffix("OCR", "A").name)?; 190 | writeln!(w, " type CompareB = {};", find_reg_suffix("OCR", "B").name)?; 191 | writeln!(w, " type Counter = {};", find_reg("TCNT").name)?; 192 | writeln!(w, " type ControlA = {};", find_reg_suffix("TCCR", "A").name)?; 193 | writeln!(w, " type ControlB = {};", find_reg_suffix("TCCR", "B").name)?; 194 | writeln!(w, " type InterruptMask = {};", find_reg("TIMSK").name)?; 195 | writeln!(w, " type InterruptFlag = {};", find_reg("TIFR").name)?; 196 | writeln!(w, " const CS0: RegisterBits = Self::ControlB::CS00;")?; 197 | writeln!(w, " const CS1: RegisterBits = Self::ControlB::CS01;")?; 198 | writeln!(w, " const CS2: RegisterBits = Self::ControlB::CS02;")?; 199 | writeln!(w, " const WGM0: RegisterBits = Self::ControlA::WGM00;")?; 200 | writeln!(w, " const WGM1: RegisterBits = Self::ControlA::WGM01;")?; 201 | writeln!(w, " const WGM2: RegisterBits = Self::ControlB::WGM020;")?; 202 | writeln!(w, " const OCIEA: RegisterBits = Self::InterruptMask::OCIE{}A;", timer_number)?; 203 | writeln!(w, "}}")?; 204 | } 205 | } 206 | 207 | if let Some(tc) = mcu.module("TC16") { // Timer/Counter, 16-bit. 208 | const TYPE_NAME: &'static str = "Timer16"; 209 | 210 | let find_reg = |name: &'static str| { 211 | tc.registers().find(|r| r.name.starts_with(name)) 212 | .expect(&format!("could not find '{}' register", name)) 213 | }; 214 | let find_reg_suffix = |name: &'static str, suffix: &'static str| { 215 | tc.registers().find(|r| r.name.starts_with(name) && r.name.ends_with(suffix)) 216 | .expect(&format!("could not find '{}' register", name)) 217 | }; 218 | let timer_number = find_reg("TIMSK").name.chars().last().unwrap() 219 | .to_digit(10).unwrap(); 220 | 221 | writeln!(w, "/// 16-bit timer.")?; 222 | writeln!(w, "pub struct {};", TYPE_NAME)?; 223 | writeln!(w)?; 224 | writeln!(w, "impl modules::Timer16 for {} {{", TYPE_NAME)?; 225 | writeln!(w, " type CompareA = {};", find_reg_suffix("OCR", "A").name)?; 226 | writeln!(w, " type CompareB = {};", find_reg_suffix("OCR", "B").name)?; 227 | writeln!(w, " type Counter = {};", find_reg("TCNT").name)?; 228 | writeln!(w, " type ControlA = {};", find_reg_suffix("TCCR", "A").name)?; 229 | writeln!(w, " type ControlB = {};", find_reg_suffix("TCCR", "B").name)?; 230 | writeln!(w, " type ControlC = {};", find_reg_suffix("TCCR", "C").name)?; 231 | writeln!(w, " type InterruptMask = {};", find_reg("TIMSK").name)?; 232 | writeln!(w, " type InterruptFlag = {};", find_reg("TIFR").name)?; 233 | writeln!(w, " const CS0: RegisterBits = Self::ControlB::CS10;")?; 234 | writeln!(w, " const CS1: RegisterBits = Self::ControlB::CS11;")?; 235 | writeln!(w, " const CS2: RegisterBits = Self::ControlB::CS12;")?; 236 | writeln!(w, " const WGM0: RegisterBits = Self::ControlA::WGM10;")?; 237 | writeln!(w, " const WGM1: RegisterBits = Self::ControlA::WGM11;")?; 238 | writeln!(w, " const WGM2: RegisterBits = Self::ControlB::WGM10;")?; 239 | writeln!(w, " const WGM3: RegisterBits = Self::ControlB::WGM11;")?; 240 | writeln!(w, " const OCIEA: RegisterBits = Self::InterruptMask::OCIE{}A;", timer_number)?; 241 | writeln!(w, "}}")?; 242 | } 243 | 244 | Ok(()) 245 | } 246 | 247 | /// Gets the name of a pin. 248 | fn pin_name(instance: &Instance, signal: &Signal) -> String { 249 | let idx = signal.index.expect("signal with no index"); 250 | let letter = instance.name.chars().rev().next().unwrap(); 251 | format!("port::{}{}", letter, idx) 252 | } 253 | -------------------------------------------------------------------------------- /core_generator/src/main.rs: -------------------------------------------------------------------------------- 1 | extern crate avr_mcu; 2 | 3 | mod gen; 4 | 5 | use avr_mcu::*; 6 | use std::fs::{self, File}; 7 | use std::io; 8 | use std::io::prelude::*; 9 | use std::path::{Path, PathBuf}; 10 | 11 | /// The MCU that will be assumed when running 'cargo doc' targeting 12 | /// archicectures that are not AVR. 13 | const DEFAULT_MCU_FOR_NON_AVR_DOCS: &'static str = "atmega328"; 14 | 15 | // Disable core generation for various devices as it does not work for them yet. 16 | const DISABLE_FOR_DEVICES: &'static [&'static str] = &[ 17 | "ATmega256RFR2", 18 | "AT90PWM81", 19 | "at90can128", 20 | "at90can32", 21 | "at90can64", 22 | "at90pwm216", 23 | "at90pwm316", 24 | "at90usb1286", 25 | "at90usb1287", 26 | "at90usb162", 27 | "at90usb646", 28 | "at90usb647", 29 | "at90usb82", 30 | "atmega1280", 31 | "atmega1281", 32 | "atmega1284", 33 | "atmega1284p", 34 | "atmega164a", 35 | "atmega164p", 36 | "atmega164pa", 37 | "atmega165a", 38 | "atmega165p", 39 | "atmega165pa", 40 | "atmega168pb", 41 | "atmega169a", 42 | "atmega169p", 43 | "atmega169pa", 44 | "atmega16m1", 45 | "atmega2560", 46 | "atmega2561", 47 | "atmega324a", 48 | "atmega324p", 49 | "atmega324pa", 50 | "atmega324pb", 51 | "atmega325", 52 | "atmega3250", 53 | "atmega3250a", 54 | "atmega3250p", 55 | "atmega3250pa", 56 | "atmega325a", 57 | "atmega325p", 58 | "atmega325pa", 59 | "atmega328pb", 60 | "atmega329", 61 | "atmega3290", 62 | "atmega3290a", 63 | "atmega3290p", 64 | "atmega3290pa", 65 | "atmega329a", 66 | "atmega329p", 67 | "atmega329pa", 68 | "atmega32c1", 69 | "atmega32m1", 70 | "atmega48pb", 71 | "atmega640", 72 | "atmega644", 73 | "atmega644a", 74 | "atmega644p", 75 | "atmega644pa", 76 | "atmega645", 77 | "atmega6450", 78 | "atmega6450a", 79 | "atmega6450p", 80 | "atmega645a", 81 | "atmega645p", 82 | "atmega649", 83 | "atmega6490", 84 | "atmega6490a", 85 | "atmega6490p", 86 | "atmega649a", 87 | "atmega649p", 88 | "atmega64c1", 89 | "atmega64m1", 90 | "atmega88pb", 91 | "attiny10", 92 | "attiny102", 93 | "attiny104", 94 | "attiny13", 95 | "attiny13a", 96 | "attiny167", 97 | "attiny24", 98 | "attiny24a", 99 | "attiny4", 100 | "attiny43u", 101 | "attiny44", 102 | "attiny44a", 103 | "attiny5", 104 | "attiny80", 105 | "attiny828", 106 | "attiny84", 107 | "attiny840", 108 | "attiny84a", 109 | "attiny87", 110 | "attiny9", 111 | "at90pwm1", 112 | "at90pwm2b", 113 | "at90pwm3b", 114 | ]; 115 | 116 | fn base_output_path() -> PathBuf { 117 | match std::env::args().skip(1).next() { 118 | Some(path) => Path::new(&path).to_owned(), 119 | None => panic!("please pass a destination path for the generated cores on the command line"), 120 | } 121 | } 122 | 123 | fn cores_path() -> PathBuf { 124 | base_output_path().join("cores") 125 | } 126 | 127 | fn core_module_name(mcu: &Mcu) -> String { 128 | normalize_device_name(&mcu.device.name) 129 | } 130 | 131 | fn normalize_device_name(device_name: &str) -> String { 132 | device_name.to_lowercase().to_owned() 133 | } 134 | 135 | fn main() { 136 | if !cores_path().exists() { 137 | fs::create_dir_all(&cores_path()).expect("could not create cores directory"); 138 | } 139 | 140 | let microcontrollers = avr_mcu::microcontrollers(); 141 | let (count_total, mut cores_successful, mut cores_failed) = (microcontrollers.len(), Vec::new(), Vec::new()); 142 | 143 | for (i, mcu) in microcontrollers.iter().enumerate() { 144 | if DISABLE_FOR_DEVICES.iter().any(|d| mcu.device.name == *d || core_module_name(mcu) == *d) { 145 | println!("skipping generation of core for '{}'", mcu.device.name); 146 | continue; 147 | } 148 | 149 | let result = std::panic::catch_unwind(|| { 150 | println!("generating core for '{}' ({} of {})", mcu.device.name, i + 1, count_total); 151 | generate_cores(&[mcu.clone()]).unwrap(); 152 | }); 153 | 154 | match result { 155 | Ok(..) => { 156 | println!("successfully generated core for '{}'", mcu.device.name); 157 | cores_successful.push(mcu); 158 | }, 159 | Err(e) => { 160 | delete_core_module(mcu).unwrap(); // Don't leave around broken core files. 161 | 162 | let error_message = if let Some(e) = e.downcast_ref::<&dyn std::error::Error>() { 163 | format!("{}", e) 164 | } else { 165 | String::new() 166 | }; 167 | 168 | eprintln!("failed to generate core for '{}', skipping: {}\n", mcu.device.name, error_message); 169 | cores_failed.push(mcu); 170 | }, 171 | } 172 | } 173 | println!("generating 'src/cores/mod.rs' for the {} successfully generated cores", cores_successful.len()); 174 | generate_cores_mod_rs(&cores_successful[..]).expect("failed to generates src/cores/mod.rs"); 175 | 176 | println!("statistics:"); 177 | println!(" total successful: {}", cores_successful.len()); 178 | println!(" total failed: {}", cores_failed.len()); 179 | } 180 | 181 | fn generate_cores(mcus: &[Mcu]) -> Result<(), io::Error> { 182 | for mcu in mcus { 183 | generate_core_module(mcu).expect("failed to generate mcu core"); 184 | } 185 | 186 | Ok(()) 187 | } 188 | 189 | fn generate_core_module(mcu: &Mcu) -> Result<(), io::Error> { 190 | let path = cores_path().join(format!("{}.rs", core_module_name(mcu))); 191 | let mut file = File::create(&path)?; 192 | write_core_module(mcu, &mut file) 193 | } 194 | 195 | fn delete_core_module(mcu: &Mcu) -> Result<(), io::Error> { 196 | let path = cores_path().join(format!("{}.rs", core_module_name(mcu))); 197 | std::fs::remove_file(&path) 198 | } 199 | 200 | fn generate_cores_mod_rs(mcus: &[&Mcu]) -> Result<(), io::Error> { 201 | let path = cores_path().join("mod.rs"); 202 | let mut w = File::create(&path)?; 203 | 204 | writeln!(w, "//! The primary module containing microcontroller-specific core definitions")?; 205 | writeln!(w)?; 206 | 207 | for mcu in mcus { 208 | let module_name = core_module_name(mcu); 209 | let is_fallback_mcu = module_name == DEFAULT_MCU_FOR_NON_AVR_DOCS; 210 | 211 | let cfg_check_default_fallback = if is_fallback_mcu { 212 | format!(", not(target_arch = \"avr\")") 213 | } else { 214 | String::new() 215 | }; 216 | let current_module_check = if is_fallback_mcu { 217 | format!("any(avr_mcu_{}, not(target_arch = \"avr\"))", module_name) 218 | } else { 219 | format!("avr_mcu_{}", module_name) 220 | }; 221 | 222 | writeln!(w, "/// The {}.", mcu.device.name)?; 223 | if is_fallback_mcu { 224 | writeln!(w, "///\n/// This device is chosen as the default when the crate is targeting non-AVR devices.")?; 225 | } 226 | 227 | writeln!(w, "#[cfg(any(avr_mcu_{}, feature = \"all-mcus\"{}))] pub mod {};", module_name, cfg_check_default_fallback, module_name)?; 228 | 229 | writeln!(w, "#[cfg({})] pub use self::{} as current;", current_module_check, module_name)?; 230 | writeln!(w)?; 231 | } 232 | writeln!(w) 233 | } 234 | 235 | fn write_core_module(mcu: &Mcu, w: &mut dyn Write) -> Result<(), io::Error> { 236 | writeln!(w, "//! Core for {}.", mcu.device.name)?; 237 | writeln!(w)?; 238 | writeln!(w, "use crate::{{modules, RegisterBits, Register}};")?; 239 | writeln!(w)?; 240 | 241 | gen::write_registers(mcu, w)?; 242 | gen::write_pins(mcu, w)?; 243 | gen::write_spi_modules(mcu, w)?; 244 | gen::write_usarts(mcu, w)?; 245 | gen::write_timers(mcu, w)?; 246 | 247 | writeln!(w) 248 | } 249 | 250 | -------------------------------------------------------------------------------- /examples/spi.rs: -------------------------------------------------------------------------------- 1 | #![no_std] 2 | #![no_main] 3 | 4 | extern crate ruduino; 5 | use ruduino::cores::current; 6 | 7 | // Some devices may have multiple SPI modules. 8 | // The ATmega328p only has one. 9 | type Spi = current::Spi; 10 | 11 | #[no_mangle] 12 | pub extern fn main() { 13 | } 14 | 15 | -------------------------------------------------------------------------------- /examples/uart.rs: -------------------------------------------------------------------------------- 1 | #![no_std] 2 | #![no_main] 3 | 4 | //! Serial port example. 5 | //! 6 | //! The output is viewable with simavr 7 | //! 8 | //! ``` 9 | //! cargo build -Z build-std=core --target avr-atmega328p.json --examples --release 10 | //! simavr -m atmega328p target/avr-atmega328p/release/examples/uart.elf 11 | //! ``` 12 | 13 | use ruduino::legacy::serial; 14 | 15 | #[no_mangle] 16 | fn main() { 17 | const CPU_FREQUENCY_HZ: u64 = 16_000_000; 18 | const BAUD: u64 = 9600; 19 | const UBRR: u16 = (CPU_FREQUENCY_HZ / 16 / BAUD - 1) as u16; 20 | 21 | serial::Serial::new(UBRR) 22 | .character_size(serial::CharacterSize::EightBits) 23 | .mode(serial::Mode::Asynchronous) 24 | .parity(serial::Parity::Disabled) 25 | .stop_bits(serial::StopBits::OneBit) 26 | .configure(); 27 | 28 | for &b in b"Hello, from Rust!\n" { 29 | serial::transmit(b); 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /regenerate-cores.sh: -------------------------------------------------------------------------------- 1 | #! /bin/bash -ea 2 | 3 | set -o pipefail 4 | 5 | SCRIPT_DIR=$(dirname $0) 6 | 7 | cd "${SCRIPT_DIR}/core_generator" 8 | 9 | cargo run "../src" 10 | 11 | -------------------------------------------------------------------------------- /src/.gitignore: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/avr-rust/ruduino/c0574999752c6bfc2c190312661a0c264247e5b1/src/.gitignore -------------------------------------------------------------------------------- /src/cores/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/avr-rust/ruduino/c0574999752c6bfc2c190312661a0c264247e5b1/src/cores/.gitkeep -------------------------------------------------------------------------------- /src/cores/atmega48.rs: -------------------------------------------------------------------------------- 1 | //! Core for ATmega48. 2 | 3 | use crate::{modules, RegisterBits, Register}; 4 | 5 | #[allow(non_camel_case_types)] 6 | pub struct EXTENDED; 7 | 8 | impl EXTENDED { 9 | pub const SELFPRGEN: RegisterBits = RegisterBits::new(0x1); 10 | pub const SELFPRGEN0: RegisterBits = RegisterBits::new(1<<0); 11 | 12 | } 13 | 14 | impl Register for EXTENDED { 15 | type T = u8; 16 | const ADDRESS: *mut u8 = 0x2 as *mut u8; 17 | } 18 | #[allow(non_camel_case_types)] 19 | pub struct HIGH; 20 | 21 | impl HIGH { 22 | pub const RSTDISBL: RegisterBits = RegisterBits::new(0x80); 23 | pub const RSTDISBL0: RegisterBits = RegisterBits::new(1<<7); 24 | 25 | pub const DWEN: RegisterBits = RegisterBits::new(0x40); 26 | pub const DWEN0: RegisterBits = RegisterBits::new(1<<6); 27 | 28 | pub const SPIEN: RegisterBits = RegisterBits::new(0x20); 29 | pub const SPIEN0: RegisterBits = RegisterBits::new(1<<5); 30 | 31 | pub const WDTON: RegisterBits = RegisterBits::new(0x10); 32 | pub const WDTON0: RegisterBits = RegisterBits::new(1<<4); 33 | 34 | pub const EESAVE: RegisterBits = RegisterBits::new(0x8); 35 | pub const EESAVE0: RegisterBits = RegisterBits::new(1<<3); 36 | 37 | pub const BODLEVEL: RegisterBits = RegisterBits::new(0x7); 38 | pub const BODLEVEL0: RegisterBits = RegisterBits::new(1<<0); 39 | pub const BODLEVEL1: RegisterBits = RegisterBits::new(1<<1); 40 | pub const BODLEVEL2: RegisterBits = RegisterBits::new(1<<2); 41 | 42 | } 43 | 44 | impl Register for HIGH { 45 | type T = u8; 46 | const ADDRESS: *mut u8 = 0x1 as *mut u8; 47 | } 48 | #[allow(non_camel_case_types)] 49 | pub struct LOW; 50 | 51 | impl LOW { 52 | pub const CKDIV8: RegisterBits = RegisterBits::new(0x80); 53 | pub const CKDIV80: RegisterBits = RegisterBits::new(1<<7); 54 | 55 | pub const CKOUT: RegisterBits = RegisterBits::new(0x40); 56 | pub const CKOUT0: RegisterBits = RegisterBits::new(1<<6); 57 | 58 | pub const SUT_CKSEL: RegisterBits = RegisterBits::new(0x3f); 59 | pub const SUT_CKSEL0: RegisterBits = RegisterBits::new(1<<0); 60 | pub const SUT_CKSEL1: RegisterBits = RegisterBits::new(1<<1); 61 | pub const SUT_CKSEL2: RegisterBits = RegisterBits::new(1<<2); 62 | pub const SUT_CKSEL3: RegisterBits = RegisterBits::new(1<<3); 63 | pub const SUT_CKSEL4: RegisterBits = RegisterBits::new(1<<4); 64 | pub const SUT_CKSEL5: RegisterBits = RegisterBits::new(1<<5); 65 | 66 | } 67 | 68 | impl Register for LOW { 69 | type T = u8; 70 | const ADDRESS: *mut u8 = 0x0 as *mut u8; 71 | } 72 | #[allow(non_camel_case_types)] 73 | pub struct LOCKBIT; 74 | 75 | impl LOCKBIT { 76 | pub const LB: RegisterBits = RegisterBits::new(0x3); 77 | pub const LB0: RegisterBits = RegisterBits::new(1<<0); 78 | pub const LB1: RegisterBits = RegisterBits::new(1<<1); 79 | 80 | } 81 | 82 | impl Register for LOCKBIT { 83 | type T = u8; 84 | const ADDRESS: *mut u8 = 0x0 as *mut u8; 85 | } 86 | #[allow(non_camel_case_types)] 87 | pub struct UDR0; 88 | 89 | impl UDR0 { 90 | } 91 | 92 | impl Register for UDR0 { 93 | type T = u8; 94 | const ADDRESS: *mut u8 = 0xc6 as *mut u8; 95 | } 96 | #[allow(non_camel_case_types)] 97 | pub struct UCSR0A; 98 | 99 | impl UCSR0A { 100 | pub const RXC0: RegisterBits = RegisterBits::new(0x80); 101 | pub const RXC00: RegisterBits = RegisterBits::new(1<<7); 102 | 103 | pub const TXC0: RegisterBits = RegisterBits::new(0x40); 104 | pub const TXC00: RegisterBits = RegisterBits::new(1<<6); 105 | 106 | pub const UDRE0: RegisterBits = RegisterBits::new(0x20); 107 | pub const UDRE00: RegisterBits = RegisterBits::new(1<<5); 108 | 109 | pub const FE0: RegisterBits = RegisterBits::new(0x10); 110 | pub const FE00: RegisterBits = RegisterBits::new(1<<4); 111 | 112 | pub const DOR0: RegisterBits = RegisterBits::new(0x8); 113 | pub const DOR00: RegisterBits = RegisterBits::new(1<<3); 114 | 115 | pub const UPE0: RegisterBits = RegisterBits::new(0x4); 116 | pub const UPE00: RegisterBits = RegisterBits::new(1<<2); 117 | 118 | pub const U2X0: RegisterBits = RegisterBits::new(0x2); 119 | pub const U2X00: RegisterBits = RegisterBits::new(1<<1); 120 | 121 | pub const MPCM0: RegisterBits = RegisterBits::new(0x1); 122 | pub const MPCM00: RegisterBits = RegisterBits::new(1<<0); 123 | 124 | } 125 | 126 | impl Register for UCSR0A { 127 | type T = u8; 128 | const ADDRESS: *mut u8 = 0xc0 as *mut u8; 129 | } 130 | #[allow(non_camel_case_types)] 131 | pub struct UCSR0B; 132 | 133 | impl UCSR0B { 134 | pub const RXCIE0: RegisterBits = RegisterBits::new(0x80); 135 | pub const RXCIE00: RegisterBits = RegisterBits::new(1<<7); 136 | 137 | pub const TXCIE0: RegisterBits = RegisterBits::new(0x40); 138 | pub const TXCIE00: RegisterBits = RegisterBits::new(1<<6); 139 | 140 | pub const UDRIE0: RegisterBits = RegisterBits::new(0x20); 141 | pub const UDRIE00: RegisterBits = RegisterBits::new(1<<5); 142 | 143 | pub const RXEN0: RegisterBits = RegisterBits::new(0x10); 144 | pub const RXEN00: RegisterBits = RegisterBits::new(1<<4); 145 | 146 | pub const TXEN0: RegisterBits = RegisterBits::new(0x8); 147 | pub const TXEN00: RegisterBits = RegisterBits::new(1<<3); 148 | 149 | pub const UCSZ02: RegisterBits = RegisterBits::new(0x4); 150 | pub const UCSZ020: RegisterBits = RegisterBits::new(1<<2); 151 | 152 | pub const RXB80: RegisterBits = RegisterBits::new(0x2); 153 | pub const RXB800: RegisterBits = RegisterBits::new(1<<1); 154 | 155 | pub const TXB80: RegisterBits = RegisterBits::new(0x1); 156 | pub const TXB800: RegisterBits = RegisterBits::new(1<<0); 157 | 158 | } 159 | 160 | impl Register for UCSR0B { 161 | type T = u8; 162 | const ADDRESS: *mut u8 = 0xc1 as *mut u8; 163 | } 164 | #[allow(non_camel_case_types)] 165 | pub struct UCSR0C; 166 | 167 | impl UCSR0C { 168 | pub const UMSEL0: RegisterBits = RegisterBits::new(0xc0); 169 | pub const UMSEL00: RegisterBits = RegisterBits::new(1<<6); 170 | pub const UMSEL01: RegisterBits = RegisterBits::new(1<<7); 171 | 172 | pub const UPM0: RegisterBits = RegisterBits::new(0x30); 173 | pub const UPM00: RegisterBits = RegisterBits::new(1<<4); 174 | pub const UPM01: RegisterBits = RegisterBits::new(1<<5); 175 | 176 | pub const USBS0: RegisterBits = RegisterBits::new(0x8); 177 | pub const USBS00: RegisterBits = RegisterBits::new(1<<3); 178 | 179 | pub const UCSZ0: RegisterBits = RegisterBits::new(0x6); 180 | pub const UCSZ00: RegisterBits = RegisterBits::new(1<<1); 181 | pub const UCSZ01: RegisterBits = RegisterBits::new(1<<2); 182 | 183 | pub const UCPOL0: RegisterBits = RegisterBits::new(0x1); 184 | pub const UCPOL00: RegisterBits = RegisterBits::new(1<<0); 185 | 186 | } 187 | 188 | impl Register for UCSR0C { 189 | type T = u8; 190 | const ADDRESS: *mut u8 = 0xc2 as *mut u8; 191 | } 192 | #[allow(non_camel_case_types)] 193 | pub struct UBRR0; 194 | 195 | impl UBRR0 { 196 | } 197 | 198 | impl Register for UBRR0 { 199 | type T = u16; 200 | const ADDRESS: *mut u16 = 0xc4 as *mut u16; 201 | } 202 | #[allow(non_camel_case_types)] 203 | pub struct TWAMR; 204 | 205 | impl TWAMR { 206 | pub const TWAM: RegisterBits = RegisterBits::new(0xfe); 207 | pub const TWAM0: RegisterBits = RegisterBits::new(1<<1); 208 | pub const TWAM1: RegisterBits = RegisterBits::new(1<<2); 209 | pub const TWAM2: RegisterBits = RegisterBits::new(1<<3); 210 | pub const TWAM3: RegisterBits = RegisterBits::new(1<<4); 211 | pub const TWAM4: RegisterBits = RegisterBits::new(1<<5); 212 | pub const TWAM5: RegisterBits = RegisterBits::new(1<<6); 213 | pub const TWAM6: RegisterBits = RegisterBits::new(1<<7); 214 | 215 | } 216 | 217 | impl Register for TWAMR { 218 | type T = u8; 219 | const ADDRESS: *mut u8 = 0xbd as *mut u8; 220 | } 221 | #[allow(non_camel_case_types)] 222 | pub struct TWBR; 223 | 224 | impl TWBR { 225 | } 226 | 227 | impl Register for TWBR { 228 | type T = u8; 229 | const ADDRESS: *mut u8 = 0xb8 as *mut u8; 230 | } 231 | #[allow(non_camel_case_types)] 232 | pub struct TWCR; 233 | 234 | impl TWCR { 235 | pub const TWINT: RegisterBits = RegisterBits::new(0x80); 236 | pub const TWINT0: RegisterBits = RegisterBits::new(1<<7); 237 | 238 | pub const TWEA: RegisterBits = RegisterBits::new(0x40); 239 | pub const TWEA0: RegisterBits = RegisterBits::new(1<<6); 240 | 241 | pub const TWSTA: RegisterBits = RegisterBits::new(0x20); 242 | pub const TWSTA0: RegisterBits = RegisterBits::new(1<<5); 243 | 244 | pub const TWSTO: RegisterBits = RegisterBits::new(0x10); 245 | pub const TWSTO0: RegisterBits = RegisterBits::new(1<<4); 246 | 247 | pub const TWWC: RegisterBits = RegisterBits::new(0x8); 248 | pub const TWWC0: RegisterBits = RegisterBits::new(1<<3); 249 | 250 | pub const TWEN: RegisterBits = RegisterBits::new(0x4); 251 | pub const TWEN0: RegisterBits = RegisterBits::new(1<<2); 252 | 253 | pub const TWIE: RegisterBits = RegisterBits::new(0x1); 254 | pub const TWIE0: RegisterBits = RegisterBits::new(1<<0); 255 | 256 | } 257 | 258 | impl Register for TWCR { 259 | type T = u8; 260 | const ADDRESS: *mut u8 = 0xbc as *mut u8; 261 | } 262 | #[allow(non_camel_case_types)] 263 | pub struct TWSR; 264 | 265 | impl TWSR { 266 | pub const TWS: RegisterBits = RegisterBits::new(0xf8); 267 | pub const TWS0: RegisterBits = RegisterBits::new(1<<3); 268 | pub const TWS1: RegisterBits = RegisterBits::new(1<<4); 269 | pub const TWS2: RegisterBits = RegisterBits::new(1<<5); 270 | pub const TWS3: RegisterBits = RegisterBits::new(1<<6); 271 | pub const TWS4: RegisterBits = RegisterBits::new(1<<7); 272 | 273 | pub const TWPS: RegisterBits = RegisterBits::new(0x3); 274 | pub const TWPS0: RegisterBits = RegisterBits::new(1<<0); 275 | pub const TWPS1: RegisterBits = RegisterBits::new(1<<1); 276 | 277 | } 278 | 279 | impl Register for TWSR { 280 | type T = u8; 281 | const ADDRESS: *mut u8 = 0xb9 as *mut u8; 282 | } 283 | #[allow(non_camel_case_types)] 284 | pub struct TWDR; 285 | 286 | impl TWDR { 287 | } 288 | 289 | impl Register for TWDR { 290 | type T = u8; 291 | const ADDRESS: *mut u8 = 0xbb as *mut u8; 292 | } 293 | #[allow(non_camel_case_types)] 294 | pub struct TWAR; 295 | 296 | impl TWAR { 297 | pub const TWA: RegisterBits = RegisterBits::new(0xfe); 298 | pub const TWA0: RegisterBits = RegisterBits::new(1<<1); 299 | pub const TWA1: RegisterBits = RegisterBits::new(1<<2); 300 | pub const TWA2: RegisterBits = RegisterBits::new(1<<3); 301 | pub const TWA3: RegisterBits = RegisterBits::new(1<<4); 302 | pub const TWA4: RegisterBits = RegisterBits::new(1<<5); 303 | pub const TWA5: RegisterBits = RegisterBits::new(1<<6); 304 | pub const TWA6: RegisterBits = RegisterBits::new(1<<7); 305 | 306 | pub const TWGCE: RegisterBits = RegisterBits::new(0x1); 307 | pub const TWGCE0: RegisterBits = RegisterBits::new(1<<0); 308 | 309 | } 310 | 311 | impl Register for TWAR { 312 | type T = u8; 313 | const ADDRESS: *mut u8 = 0xba as *mut u8; 314 | } 315 | #[allow(non_camel_case_types)] 316 | pub struct TIMSK1; 317 | 318 | impl TIMSK1 { 319 | pub const ICIE1: RegisterBits = RegisterBits::new(0x20); 320 | pub const ICIE10: RegisterBits = RegisterBits::new(1<<5); 321 | 322 | pub const OCIE1B: RegisterBits = RegisterBits::new(0x4); 323 | pub const OCIE1B0: RegisterBits = RegisterBits::new(1<<2); 324 | 325 | pub const OCIE1A: RegisterBits = RegisterBits::new(0x2); 326 | pub const OCIE1A0: RegisterBits = RegisterBits::new(1<<1); 327 | 328 | pub const TOIE1: RegisterBits = RegisterBits::new(0x1); 329 | pub const TOIE10: RegisterBits = RegisterBits::new(1<<0); 330 | 331 | } 332 | 333 | impl Register for TIMSK1 { 334 | type T = u8; 335 | const ADDRESS: *mut u8 = 0x6f as *mut u8; 336 | } 337 | #[allow(non_camel_case_types)] 338 | pub struct TIFR1; 339 | 340 | impl TIFR1 { 341 | pub const ICF1: RegisterBits = RegisterBits::new(0x20); 342 | pub const ICF10: RegisterBits = RegisterBits::new(1<<5); 343 | 344 | pub const OCF1B: RegisterBits = RegisterBits::new(0x4); 345 | pub const OCF1B0: RegisterBits = RegisterBits::new(1<<2); 346 | 347 | pub const OCF1A: RegisterBits = RegisterBits::new(0x2); 348 | pub const OCF1A0: RegisterBits = RegisterBits::new(1<<1); 349 | 350 | pub const TOV1: RegisterBits = RegisterBits::new(0x1); 351 | pub const TOV10: RegisterBits = RegisterBits::new(1<<0); 352 | 353 | } 354 | 355 | impl Register for TIFR1 { 356 | type T = u8; 357 | const ADDRESS: *mut u8 = 0x36 as *mut u8; 358 | } 359 | #[allow(non_camel_case_types)] 360 | pub struct TCCR1A; 361 | 362 | impl TCCR1A { 363 | pub const COM1A: RegisterBits = RegisterBits::new(0xc0); 364 | pub const COM1A0: RegisterBits = RegisterBits::new(1<<6); 365 | pub const COM1A1: RegisterBits = RegisterBits::new(1<<7); 366 | 367 | pub const COM1B: RegisterBits = RegisterBits::new(0x30); 368 | pub const COM1B0: RegisterBits = RegisterBits::new(1<<4); 369 | pub const COM1B1: RegisterBits = RegisterBits::new(1<<5); 370 | 371 | pub const WGM1: RegisterBits = RegisterBits::new(0x3); 372 | pub const WGM10: RegisterBits = RegisterBits::new(1<<0); 373 | pub const WGM11: RegisterBits = RegisterBits::new(1<<1); 374 | 375 | } 376 | 377 | impl Register for TCCR1A { 378 | type T = u8; 379 | const ADDRESS: *mut u8 = 0x80 as *mut u8; 380 | } 381 | #[allow(non_camel_case_types)] 382 | pub struct TCCR1B; 383 | 384 | impl TCCR1B { 385 | pub const ICNC1: RegisterBits = RegisterBits::new(0x80); 386 | pub const ICNC10: RegisterBits = RegisterBits::new(1<<7); 387 | 388 | pub const ICES1: RegisterBits = RegisterBits::new(0x40); 389 | pub const ICES10: RegisterBits = RegisterBits::new(1<<6); 390 | 391 | pub const WGM1: RegisterBits = RegisterBits::new(0x18); 392 | pub const WGM10: RegisterBits = RegisterBits::new(1<<3); 393 | pub const WGM11: RegisterBits = RegisterBits::new(1<<4); 394 | 395 | pub const CS1: RegisterBits = RegisterBits::new(0x7); 396 | pub const CS10: RegisterBits = RegisterBits::new(1<<0); 397 | pub const CS11: RegisterBits = RegisterBits::new(1<<1); 398 | pub const CS12: RegisterBits = RegisterBits::new(1<<2); 399 | 400 | } 401 | 402 | impl Register for TCCR1B { 403 | type T = u8; 404 | const ADDRESS: *mut u8 = 0x81 as *mut u8; 405 | } 406 | #[allow(non_camel_case_types)] 407 | pub struct TCCR1C; 408 | 409 | impl TCCR1C { 410 | pub const FOC1A: RegisterBits = RegisterBits::new(0x80); 411 | pub const FOC1A0: RegisterBits = RegisterBits::new(1<<7); 412 | 413 | pub const FOC1B: RegisterBits = RegisterBits::new(0x40); 414 | pub const FOC1B0: RegisterBits = RegisterBits::new(1<<6); 415 | 416 | } 417 | 418 | impl Register for TCCR1C { 419 | type T = u8; 420 | const ADDRESS: *mut u8 = 0x82 as *mut u8; 421 | } 422 | #[allow(non_camel_case_types)] 423 | pub struct TCNT1; 424 | 425 | impl TCNT1 { 426 | } 427 | 428 | impl Register for TCNT1 { 429 | type T = u16; 430 | const ADDRESS: *mut u16 = 0x84 as *mut u16; 431 | } 432 | #[allow(non_camel_case_types)] 433 | pub struct OCR1A; 434 | 435 | impl OCR1A { 436 | } 437 | 438 | impl Register for OCR1A { 439 | type T = u16; 440 | const ADDRESS: *mut u16 = 0x88 as *mut u16; 441 | } 442 | #[allow(non_camel_case_types)] 443 | pub struct OCR1B; 444 | 445 | impl OCR1B { 446 | } 447 | 448 | impl Register for OCR1B { 449 | type T = u16; 450 | const ADDRESS: *mut u16 = 0x8a as *mut u16; 451 | } 452 | #[allow(non_camel_case_types)] 453 | pub struct ICR1; 454 | 455 | impl ICR1 { 456 | } 457 | 458 | impl Register for ICR1 { 459 | type T = u16; 460 | const ADDRESS: *mut u16 = 0x86 as *mut u16; 461 | } 462 | #[allow(non_camel_case_types)] 463 | pub struct TIMSK2; 464 | 465 | impl TIMSK2 { 466 | pub const OCIE2B: RegisterBits = RegisterBits::new(0x4); 467 | pub const OCIE2B0: RegisterBits = RegisterBits::new(1<<2); 468 | 469 | pub const OCIE2A: RegisterBits = RegisterBits::new(0x2); 470 | pub const OCIE2A0: RegisterBits = RegisterBits::new(1<<1); 471 | 472 | pub const TOIE2: RegisterBits = RegisterBits::new(0x1); 473 | pub const TOIE20: RegisterBits = RegisterBits::new(1<<0); 474 | 475 | } 476 | 477 | impl Register for TIMSK2 { 478 | type T = u8; 479 | const ADDRESS: *mut u8 = 0x70 as *mut u8; 480 | } 481 | #[allow(non_camel_case_types)] 482 | pub struct TIFR2; 483 | 484 | impl TIFR2 { 485 | pub const OCF2B: RegisterBits = RegisterBits::new(0x4); 486 | pub const OCF2B0: RegisterBits = RegisterBits::new(1<<2); 487 | 488 | pub const OCF2A: RegisterBits = RegisterBits::new(0x2); 489 | pub const OCF2A0: RegisterBits = RegisterBits::new(1<<1); 490 | 491 | pub const TOV2: RegisterBits = RegisterBits::new(0x1); 492 | pub const TOV20: RegisterBits = RegisterBits::new(1<<0); 493 | 494 | } 495 | 496 | impl Register for TIFR2 { 497 | type T = u8; 498 | const ADDRESS: *mut u8 = 0x37 as *mut u8; 499 | } 500 | #[allow(non_camel_case_types)] 501 | pub struct TCCR2A; 502 | 503 | impl TCCR2A { 504 | pub const COM2A: RegisterBits = RegisterBits::new(0xc0); 505 | pub const COM2A0: RegisterBits = RegisterBits::new(1<<6); 506 | pub const COM2A1: RegisterBits = RegisterBits::new(1<<7); 507 | 508 | pub const COM2B: RegisterBits = RegisterBits::new(0x30); 509 | pub const COM2B0: RegisterBits = RegisterBits::new(1<<4); 510 | pub const COM2B1: RegisterBits = RegisterBits::new(1<<5); 511 | 512 | pub const WGM2: RegisterBits = RegisterBits::new(0x3); 513 | pub const WGM20: RegisterBits = RegisterBits::new(1<<0); 514 | pub const WGM21: RegisterBits = RegisterBits::new(1<<1); 515 | 516 | } 517 | 518 | impl Register for TCCR2A { 519 | type T = u8; 520 | const ADDRESS: *mut u8 = 0xb0 as *mut u8; 521 | } 522 | #[allow(non_camel_case_types)] 523 | pub struct TCCR2B; 524 | 525 | impl TCCR2B { 526 | pub const FOC2A: RegisterBits = RegisterBits::new(0x80); 527 | pub const FOC2A0: RegisterBits = RegisterBits::new(1<<7); 528 | 529 | pub const FOC2B: RegisterBits = RegisterBits::new(0x40); 530 | pub const FOC2B0: RegisterBits = RegisterBits::new(1<<6); 531 | 532 | pub const WGM22: RegisterBits = RegisterBits::new(0x8); 533 | pub const WGM220: RegisterBits = RegisterBits::new(1<<3); 534 | 535 | pub const CS2: RegisterBits = RegisterBits::new(0x7); 536 | pub const CS20: RegisterBits = RegisterBits::new(1<<0); 537 | pub const CS21: RegisterBits = RegisterBits::new(1<<1); 538 | pub const CS22: RegisterBits = RegisterBits::new(1<<2); 539 | 540 | } 541 | 542 | impl Register for TCCR2B { 543 | type T = u8; 544 | const ADDRESS: *mut u8 = 0xb1 as *mut u8; 545 | } 546 | #[allow(non_camel_case_types)] 547 | pub struct TCNT2; 548 | 549 | impl TCNT2 { 550 | } 551 | 552 | impl Register for TCNT2 { 553 | type T = u8; 554 | const ADDRESS: *mut u8 = 0xb2 as *mut u8; 555 | } 556 | #[allow(non_camel_case_types)] 557 | pub struct OCR2B; 558 | 559 | impl OCR2B { 560 | } 561 | 562 | impl Register for OCR2B { 563 | type T = u8; 564 | const ADDRESS: *mut u8 = 0xb4 as *mut u8; 565 | } 566 | #[allow(non_camel_case_types)] 567 | pub struct OCR2A; 568 | 569 | impl OCR2A { 570 | } 571 | 572 | impl Register for OCR2A { 573 | type T = u8; 574 | const ADDRESS: *mut u8 = 0xb3 as *mut u8; 575 | } 576 | #[allow(non_camel_case_types)] 577 | pub struct ASSR; 578 | 579 | impl ASSR { 580 | pub const EXCLK: RegisterBits = RegisterBits::new(0x40); 581 | pub const EXCLK0: RegisterBits = RegisterBits::new(1<<6); 582 | 583 | pub const AS2: RegisterBits = RegisterBits::new(0x20); 584 | pub const AS20: RegisterBits = RegisterBits::new(1<<5); 585 | 586 | pub const TCN2UB: RegisterBits = RegisterBits::new(0x10); 587 | pub const TCN2UB0: RegisterBits = RegisterBits::new(1<<4); 588 | 589 | pub const OCR2AUB: RegisterBits = RegisterBits::new(0x8); 590 | pub const OCR2AUB0: RegisterBits = RegisterBits::new(1<<3); 591 | 592 | pub const OCR2BUB: RegisterBits = RegisterBits::new(0x4); 593 | pub const OCR2BUB0: RegisterBits = RegisterBits::new(1<<2); 594 | 595 | pub const TCR2AUB: RegisterBits = RegisterBits::new(0x2); 596 | pub const TCR2AUB0: RegisterBits = RegisterBits::new(1<<1); 597 | 598 | pub const TCR2BUB: RegisterBits = RegisterBits::new(0x1); 599 | pub const TCR2BUB0: RegisterBits = RegisterBits::new(1<<0); 600 | 601 | } 602 | 603 | impl Register for ASSR { 604 | type T = u8; 605 | const ADDRESS: *mut u8 = 0xb6 as *mut u8; 606 | } 607 | #[allow(non_camel_case_types)] 608 | pub struct ADMUX; 609 | 610 | impl ADMUX { 611 | pub const REFS: RegisterBits = RegisterBits::new(0xc0); 612 | pub const REFS0: RegisterBits = RegisterBits::new(1<<6); 613 | pub const REFS1: RegisterBits = RegisterBits::new(1<<7); 614 | 615 | pub const ADLAR: RegisterBits = RegisterBits::new(0x20); 616 | pub const ADLAR0: RegisterBits = RegisterBits::new(1<<5); 617 | 618 | pub const MUX: RegisterBits = RegisterBits::new(0xf); 619 | pub const MUX0: RegisterBits = RegisterBits::new(1<<0); 620 | pub const MUX1: RegisterBits = RegisterBits::new(1<<1); 621 | pub const MUX2: RegisterBits = RegisterBits::new(1<<2); 622 | pub const MUX3: RegisterBits = RegisterBits::new(1<<3); 623 | 624 | } 625 | 626 | impl Register for ADMUX { 627 | type T = u8; 628 | const ADDRESS: *mut u8 = 0x7c as *mut u8; 629 | } 630 | #[allow(non_camel_case_types)] 631 | pub struct ADC; 632 | 633 | impl ADC { 634 | } 635 | 636 | impl Register for ADC { 637 | type T = u16; 638 | const ADDRESS: *mut u16 = 0x78 as *mut u16; 639 | } 640 | #[allow(non_camel_case_types)] 641 | pub struct ADCSRA; 642 | 643 | impl ADCSRA { 644 | pub const ADEN: RegisterBits = RegisterBits::new(0x80); 645 | pub const ADEN0: RegisterBits = RegisterBits::new(1<<7); 646 | 647 | pub const ADSC: RegisterBits = RegisterBits::new(0x40); 648 | pub const ADSC0: RegisterBits = RegisterBits::new(1<<6); 649 | 650 | pub const ADATE: RegisterBits = RegisterBits::new(0x20); 651 | pub const ADATE0: RegisterBits = RegisterBits::new(1<<5); 652 | 653 | pub const ADIF: RegisterBits = RegisterBits::new(0x10); 654 | pub const ADIF0: RegisterBits = RegisterBits::new(1<<4); 655 | 656 | pub const ADIE: RegisterBits = RegisterBits::new(0x8); 657 | pub const ADIE0: RegisterBits = RegisterBits::new(1<<3); 658 | 659 | pub const ADPS: RegisterBits = RegisterBits::new(0x7); 660 | pub const ADPS0: RegisterBits = RegisterBits::new(1<<0); 661 | pub const ADPS1: RegisterBits = RegisterBits::new(1<<1); 662 | pub const ADPS2: RegisterBits = RegisterBits::new(1<<2); 663 | 664 | } 665 | 666 | impl Register for ADCSRA { 667 | type T = u8; 668 | const ADDRESS: *mut u8 = 0x7a as *mut u8; 669 | } 670 | #[allow(non_camel_case_types)] 671 | pub struct ADCSRB; 672 | 673 | impl ADCSRB { 674 | pub const ACME: RegisterBits = RegisterBits::new(0x40); 675 | pub const ACME0: RegisterBits = RegisterBits::new(1<<6); 676 | 677 | pub const ADTS: RegisterBits = RegisterBits::new(0x7); 678 | pub const ADTS0: RegisterBits = RegisterBits::new(1<<0); 679 | pub const ADTS1: RegisterBits = RegisterBits::new(1<<1); 680 | pub const ADTS2: RegisterBits = RegisterBits::new(1<<2); 681 | 682 | } 683 | 684 | impl Register for ADCSRB { 685 | type T = u8; 686 | const ADDRESS: *mut u8 = 0x7b as *mut u8; 687 | } 688 | #[allow(non_camel_case_types)] 689 | pub struct DIDR0; 690 | 691 | impl DIDR0 { 692 | pub const ADC5D: RegisterBits = RegisterBits::new(0x20); 693 | pub const ADC5D0: RegisterBits = RegisterBits::new(1<<5); 694 | 695 | pub const ADC4D: RegisterBits = RegisterBits::new(0x10); 696 | pub const ADC4D0: RegisterBits = RegisterBits::new(1<<4); 697 | 698 | pub const ADC3D: RegisterBits = RegisterBits::new(0x8); 699 | pub const ADC3D0: RegisterBits = RegisterBits::new(1<<3); 700 | 701 | pub const ADC2D: RegisterBits = RegisterBits::new(0x4); 702 | pub const ADC2D0: RegisterBits = RegisterBits::new(1<<2); 703 | 704 | pub const ADC1D: RegisterBits = RegisterBits::new(0x2); 705 | pub const ADC1D0: RegisterBits = RegisterBits::new(1<<1); 706 | 707 | pub const ADC0D: RegisterBits = RegisterBits::new(0x1); 708 | pub const ADC0D0: RegisterBits = RegisterBits::new(1<<0); 709 | 710 | } 711 | 712 | impl Register for DIDR0 { 713 | type T = u8; 714 | const ADDRESS: *mut u8 = 0x7e as *mut u8; 715 | } 716 | #[allow(non_camel_case_types)] 717 | pub struct ACSR; 718 | 719 | impl ACSR { 720 | pub const ACD: RegisterBits = RegisterBits::new(0x80); 721 | pub const ACD0: RegisterBits = RegisterBits::new(1<<7); 722 | 723 | pub const ACBG: RegisterBits = RegisterBits::new(0x40); 724 | pub const ACBG0: RegisterBits = RegisterBits::new(1<<6); 725 | 726 | pub const ACO: RegisterBits = RegisterBits::new(0x20); 727 | pub const ACO0: RegisterBits = RegisterBits::new(1<<5); 728 | 729 | pub const ACI: RegisterBits = RegisterBits::new(0x10); 730 | pub const ACI0: RegisterBits = RegisterBits::new(1<<4); 731 | 732 | pub const ACIE: RegisterBits = RegisterBits::new(0x8); 733 | pub const ACIE0: RegisterBits = RegisterBits::new(1<<3); 734 | 735 | pub const ACIC: RegisterBits = RegisterBits::new(0x4); 736 | pub const ACIC0: RegisterBits = RegisterBits::new(1<<2); 737 | 738 | pub const ACIS: RegisterBits = RegisterBits::new(0x3); 739 | pub const ACIS0: RegisterBits = RegisterBits::new(1<<0); 740 | pub const ACIS1: RegisterBits = RegisterBits::new(1<<1); 741 | 742 | } 743 | 744 | impl Register for ACSR { 745 | type T = u8; 746 | const ADDRESS: *mut u8 = 0x50 as *mut u8; 747 | } 748 | #[allow(non_camel_case_types)] 749 | pub struct DIDR1; 750 | 751 | impl DIDR1 { 752 | pub const AIN1D: RegisterBits = RegisterBits::new(0x2); 753 | pub const AIN1D0: RegisterBits = RegisterBits::new(1<<1); 754 | 755 | pub const AIN0D: RegisterBits = RegisterBits::new(0x1); 756 | pub const AIN0D0: RegisterBits = RegisterBits::new(1<<0); 757 | 758 | } 759 | 760 | impl Register for DIDR1 { 761 | type T = u8; 762 | const ADDRESS: *mut u8 = 0x7f as *mut u8; 763 | } 764 | #[allow(non_camel_case_types)] 765 | pub struct PORTB; 766 | 767 | impl PORTB { 768 | } 769 | 770 | impl Register for PORTB { 771 | type T = u8; 772 | const ADDRESS: *mut u8 = 0x25 as *mut u8; 773 | } 774 | #[allow(non_camel_case_types)] 775 | pub struct DDRB; 776 | 777 | impl DDRB { 778 | } 779 | 780 | impl Register for DDRB { 781 | type T = u8; 782 | const ADDRESS: *mut u8 = 0x24 as *mut u8; 783 | } 784 | #[allow(non_camel_case_types)] 785 | pub struct PINB; 786 | 787 | impl PINB { 788 | } 789 | 790 | impl Register for PINB { 791 | type T = u8; 792 | const ADDRESS: *mut u8 = 0x23 as *mut u8; 793 | } 794 | #[allow(non_camel_case_types)] 795 | pub struct PORTC; 796 | 797 | impl PORTC { 798 | } 799 | 800 | impl Register for PORTC { 801 | type T = u8; 802 | const ADDRESS: *mut u8 = 0x28 as *mut u8; 803 | } 804 | #[allow(non_camel_case_types)] 805 | pub struct DDRC; 806 | 807 | impl DDRC { 808 | } 809 | 810 | impl Register for DDRC { 811 | type T = u8; 812 | const ADDRESS: *mut u8 = 0x27 as *mut u8; 813 | } 814 | #[allow(non_camel_case_types)] 815 | pub struct PINC; 816 | 817 | impl PINC { 818 | } 819 | 820 | impl Register for PINC { 821 | type T = u8; 822 | const ADDRESS: *mut u8 = 0x26 as *mut u8; 823 | } 824 | #[allow(non_camel_case_types)] 825 | pub struct PORTD; 826 | 827 | impl PORTD { 828 | } 829 | 830 | impl Register for PORTD { 831 | type T = u8; 832 | const ADDRESS: *mut u8 = 0x2b as *mut u8; 833 | } 834 | #[allow(non_camel_case_types)] 835 | pub struct DDRD; 836 | 837 | impl DDRD { 838 | } 839 | 840 | impl Register for DDRD { 841 | type T = u8; 842 | const ADDRESS: *mut u8 = 0x2a as *mut u8; 843 | } 844 | #[allow(non_camel_case_types)] 845 | pub struct PIND; 846 | 847 | impl PIND { 848 | } 849 | 850 | impl Register for PIND { 851 | type T = u8; 852 | const ADDRESS: *mut u8 = 0x29 as *mut u8; 853 | } 854 | #[allow(non_camel_case_types)] 855 | pub struct OCR0B; 856 | 857 | impl OCR0B { 858 | } 859 | 860 | impl Register for OCR0B { 861 | type T = u8; 862 | const ADDRESS: *mut u8 = 0x48 as *mut u8; 863 | } 864 | #[allow(non_camel_case_types)] 865 | pub struct OCR0A; 866 | 867 | impl OCR0A { 868 | } 869 | 870 | impl Register for OCR0A { 871 | type T = u8; 872 | const ADDRESS: *mut u8 = 0x47 as *mut u8; 873 | } 874 | #[allow(non_camel_case_types)] 875 | pub struct TCNT0; 876 | 877 | impl TCNT0 { 878 | } 879 | 880 | impl Register for TCNT0 { 881 | type T = u8; 882 | const ADDRESS: *mut u8 = 0x46 as *mut u8; 883 | } 884 | #[allow(non_camel_case_types)] 885 | pub struct TCCR0B; 886 | 887 | impl TCCR0B { 888 | pub const FOC0A: RegisterBits = RegisterBits::new(0x80); 889 | pub const FOC0A0: RegisterBits = RegisterBits::new(1<<7); 890 | 891 | pub const FOC0B: RegisterBits = RegisterBits::new(0x40); 892 | pub const FOC0B0: RegisterBits = RegisterBits::new(1<<6); 893 | 894 | pub const WGM02: RegisterBits = RegisterBits::new(0x8); 895 | pub const WGM020: RegisterBits = RegisterBits::new(1<<3); 896 | 897 | pub const CS0: RegisterBits = RegisterBits::new(0x7); 898 | pub const CS00: RegisterBits = RegisterBits::new(1<<0); 899 | pub const CS01: RegisterBits = RegisterBits::new(1<<1); 900 | pub const CS02: RegisterBits = RegisterBits::new(1<<2); 901 | 902 | } 903 | 904 | impl Register for TCCR0B { 905 | type T = u8; 906 | const ADDRESS: *mut u8 = 0x45 as *mut u8; 907 | } 908 | #[allow(non_camel_case_types)] 909 | pub struct TCCR0A; 910 | 911 | impl TCCR0A { 912 | pub const COM0A: RegisterBits = RegisterBits::new(0xc0); 913 | pub const COM0A0: RegisterBits = RegisterBits::new(1<<6); 914 | pub const COM0A1: RegisterBits = RegisterBits::new(1<<7); 915 | 916 | pub const COM0B: RegisterBits = RegisterBits::new(0x30); 917 | pub const COM0B0: RegisterBits = RegisterBits::new(1<<4); 918 | pub const COM0B1: RegisterBits = RegisterBits::new(1<<5); 919 | 920 | pub const WGM0: RegisterBits = RegisterBits::new(0x3); 921 | pub const WGM00: RegisterBits = RegisterBits::new(1<<0); 922 | pub const WGM01: RegisterBits = RegisterBits::new(1<<1); 923 | 924 | } 925 | 926 | impl Register for TCCR0A { 927 | type T = u8; 928 | const ADDRESS: *mut u8 = 0x44 as *mut u8; 929 | } 930 | #[allow(non_camel_case_types)] 931 | pub struct TIMSK0; 932 | 933 | impl TIMSK0 { 934 | pub const OCIE0B: RegisterBits = RegisterBits::new(0x4); 935 | pub const OCIE0B0: RegisterBits = RegisterBits::new(1<<2); 936 | 937 | pub const OCIE0A: RegisterBits = RegisterBits::new(0x2); 938 | pub const OCIE0A0: RegisterBits = RegisterBits::new(1<<1); 939 | 940 | pub const TOIE0: RegisterBits = RegisterBits::new(0x1); 941 | pub const TOIE00: RegisterBits = RegisterBits::new(1<<0); 942 | 943 | } 944 | 945 | impl Register for TIMSK0 { 946 | type T = u8; 947 | const ADDRESS: *mut u8 = 0x6e as *mut u8; 948 | } 949 | #[allow(non_camel_case_types)] 950 | pub struct TIFR0; 951 | 952 | impl TIFR0 { 953 | pub const OCF0B: RegisterBits = RegisterBits::new(0x4); 954 | pub const OCF0B0: RegisterBits = RegisterBits::new(1<<2); 955 | 956 | pub const OCF0A: RegisterBits = RegisterBits::new(0x2); 957 | pub const OCF0A0: RegisterBits = RegisterBits::new(1<<1); 958 | 959 | pub const TOV0: RegisterBits = RegisterBits::new(0x1); 960 | pub const TOV00: RegisterBits = RegisterBits::new(1<<0); 961 | 962 | } 963 | 964 | impl Register for TIFR0 { 965 | type T = u8; 966 | const ADDRESS: *mut u8 = 0x35 as *mut u8; 967 | } 968 | #[allow(non_camel_case_types)] 969 | pub struct EICRA; 970 | 971 | impl EICRA { 972 | pub const ISC1: RegisterBits = RegisterBits::new(0xc); 973 | pub const ISC10: RegisterBits = RegisterBits::new(1<<2); 974 | pub const ISC11: RegisterBits = RegisterBits::new(1<<3); 975 | 976 | pub const ISC0: RegisterBits = RegisterBits::new(0x3); 977 | pub const ISC00: RegisterBits = RegisterBits::new(1<<0); 978 | pub const ISC01: RegisterBits = RegisterBits::new(1<<1); 979 | 980 | } 981 | 982 | impl Register for EICRA { 983 | type T = u8; 984 | const ADDRESS: *mut u8 = 0x69 as *mut u8; 985 | } 986 | #[allow(non_camel_case_types)] 987 | pub struct EIMSK; 988 | 989 | impl EIMSK { 990 | pub const INT: RegisterBits = RegisterBits::new(0x3); 991 | pub const INT0: RegisterBits = RegisterBits::new(1<<0); 992 | pub const INT1: RegisterBits = RegisterBits::new(1<<1); 993 | 994 | } 995 | 996 | impl Register for EIMSK { 997 | type T = u8; 998 | const ADDRESS: *mut u8 = 0x3d as *mut u8; 999 | } 1000 | #[allow(non_camel_case_types)] 1001 | pub struct EIFR; 1002 | 1003 | impl EIFR { 1004 | pub const INTF: RegisterBits = RegisterBits::new(0x3); 1005 | pub const INTF0: RegisterBits = RegisterBits::new(1<<0); 1006 | pub const INTF1: RegisterBits = RegisterBits::new(1<<1); 1007 | 1008 | } 1009 | 1010 | impl Register for EIFR { 1011 | type T = u8; 1012 | const ADDRESS: *mut u8 = 0x3c as *mut u8; 1013 | } 1014 | #[allow(non_camel_case_types)] 1015 | pub struct PCICR; 1016 | 1017 | impl PCICR { 1018 | pub const PCIE: RegisterBits = RegisterBits::new(0x7); 1019 | pub const PCIE0: RegisterBits = RegisterBits::new(1<<0); 1020 | pub const PCIE1: RegisterBits = RegisterBits::new(1<<1); 1021 | pub const PCIE2: RegisterBits = RegisterBits::new(1<<2); 1022 | 1023 | } 1024 | 1025 | impl Register for PCICR { 1026 | type T = u8; 1027 | const ADDRESS: *mut u8 = 0x68 as *mut u8; 1028 | } 1029 | #[allow(non_camel_case_types)] 1030 | pub struct PCMSK2; 1031 | 1032 | impl PCMSK2 { 1033 | pub const PCINT: RegisterBits = RegisterBits::new(0xff); 1034 | pub const PCINT0: RegisterBits = RegisterBits::new(1<<0); 1035 | pub const PCINT1: RegisterBits = RegisterBits::new(1<<1); 1036 | pub const PCINT2: RegisterBits = RegisterBits::new(1<<2); 1037 | pub const PCINT3: RegisterBits = RegisterBits::new(1<<3); 1038 | pub const PCINT4: RegisterBits = RegisterBits::new(1<<4); 1039 | pub const PCINT5: RegisterBits = RegisterBits::new(1<<5); 1040 | pub const PCINT6: RegisterBits = RegisterBits::new(1<<6); 1041 | pub const PCINT7: RegisterBits = RegisterBits::new(1<<7); 1042 | 1043 | } 1044 | 1045 | impl Register for PCMSK2 { 1046 | type T = u8; 1047 | const ADDRESS: *mut u8 = 0x6d as *mut u8; 1048 | } 1049 | #[allow(non_camel_case_types)] 1050 | pub struct PCMSK1; 1051 | 1052 | impl PCMSK1 { 1053 | pub const PCINT: RegisterBits = RegisterBits::new(0x7f); 1054 | pub const PCINT0: RegisterBits = RegisterBits::new(1<<0); 1055 | pub const PCINT1: RegisterBits = RegisterBits::new(1<<1); 1056 | pub const PCINT2: RegisterBits = RegisterBits::new(1<<2); 1057 | pub const PCINT3: RegisterBits = RegisterBits::new(1<<3); 1058 | pub const PCINT4: RegisterBits = RegisterBits::new(1<<4); 1059 | pub const PCINT5: RegisterBits = RegisterBits::new(1<<5); 1060 | pub const PCINT6: RegisterBits = RegisterBits::new(1<<6); 1061 | 1062 | } 1063 | 1064 | impl Register for PCMSK1 { 1065 | type T = u8; 1066 | const ADDRESS: *mut u8 = 0x6c as *mut u8; 1067 | } 1068 | #[allow(non_camel_case_types)] 1069 | pub struct PCMSK0; 1070 | 1071 | impl PCMSK0 { 1072 | pub const PCINT: RegisterBits = RegisterBits::new(0xff); 1073 | pub const PCINT0: RegisterBits = RegisterBits::new(1<<0); 1074 | pub const PCINT1: RegisterBits = RegisterBits::new(1<<1); 1075 | pub const PCINT2: RegisterBits = RegisterBits::new(1<<2); 1076 | pub const PCINT3: RegisterBits = RegisterBits::new(1<<3); 1077 | pub const PCINT4: RegisterBits = RegisterBits::new(1<<4); 1078 | pub const PCINT5: RegisterBits = RegisterBits::new(1<<5); 1079 | pub const PCINT6: RegisterBits = RegisterBits::new(1<<6); 1080 | pub const PCINT7: RegisterBits = RegisterBits::new(1<<7); 1081 | 1082 | } 1083 | 1084 | impl Register for PCMSK0 { 1085 | type T = u8; 1086 | const ADDRESS: *mut u8 = 0x6b as *mut u8; 1087 | } 1088 | #[allow(non_camel_case_types)] 1089 | pub struct PCIFR; 1090 | 1091 | impl PCIFR { 1092 | pub const PCIF: RegisterBits = RegisterBits::new(0x7); 1093 | pub const PCIF0: RegisterBits = RegisterBits::new(1<<0); 1094 | pub const PCIF1: RegisterBits = RegisterBits::new(1<<1); 1095 | pub const PCIF2: RegisterBits = RegisterBits::new(1<<2); 1096 | 1097 | } 1098 | 1099 | impl Register for PCIFR { 1100 | type T = u8; 1101 | const ADDRESS: *mut u8 = 0x3b as *mut u8; 1102 | } 1103 | #[allow(non_camel_case_types)] 1104 | pub struct SPDR; 1105 | 1106 | impl SPDR { 1107 | } 1108 | 1109 | impl Register for SPDR { 1110 | type T = u8; 1111 | const ADDRESS: *mut u8 = 0x4e as *mut u8; 1112 | } 1113 | #[allow(non_camel_case_types)] 1114 | pub struct SPSR; 1115 | 1116 | impl SPSR { 1117 | pub const SPIF: RegisterBits = RegisterBits::new(0x80); 1118 | pub const SPIF0: RegisterBits = RegisterBits::new(1<<7); 1119 | 1120 | pub const WCOL: RegisterBits = RegisterBits::new(0x40); 1121 | pub const WCOL0: RegisterBits = RegisterBits::new(1<<6); 1122 | 1123 | pub const SPI2X: RegisterBits = RegisterBits::new(0x1); 1124 | pub const SPI2X0: RegisterBits = RegisterBits::new(1<<0); 1125 | 1126 | } 1127 | 1128 | impl Register for SPSR { 1129 | type T = u8; 1130 | const ADDRESS: *mut u8 = 0x4d as *mut u8; 1131 | } 1132 | #[allow(non_camel_case_types)] 1133 | pub struct SPCR; 1134 | 1135 | impl SPCR { 1136 | pub const SPIE: RegisterBits = RegisterBits::new(0x80); 1137 | pub const SPIE0: RegisterBits = RegisterBits::new(1<<7); 1138 | 1139 | pub const SPE: RegisterBits = RegisterBits::new(0x40); 1140 | pub const SPE0: RegisterBits = RegisterBits::new(1<<6); 1141 | 1142 | pub const DORD: RegisterBits = RegisterBits::new(0x20); 1143 | pub const DORD0: RegisterBits = RegisterBits::new(1<<5); 1144 | 1145 | pub const MSTR: RegisterBits = RegisterBits::new(0x10); 1146 | pub const MSTR0: RegisterBits = RegisterBits::new(1<<4); 1147 | 1148 | pub const CPOL: RegisterBits = RegisterBits::new(0x8); 1149 | pub const CPOL0: RegisterBits = RegisterBits::new(1<<3); 1150 | 1151 | pub const CPHA: RegisterBits = RegisterBits::new(0x4); 1152 | pub const CPHA0: RegisterBits = RegisterBits::new(1<<2); 1153 | 1154 | pub const SPR: RegisterBits = RegisterBits::new(0x3); 1155 | pub const SPR0: RegisterBits = RegisterBits::new(1<<0); 1156 | pub const SPR1: RegisterBits = RegisterBits::new(1<<1); 1157 | 1158 | } 1159 | 1160 | impl Register for SPCR { 1161 | type T = u8; 1162 | const ADDRESS: *mut u8 = 0x4c as *mut u8; 1163 | } 1164 | #[allow(non_camel_case_types)] 1165 | pub struct PRR; 1166 | 1167 | impl PRR { 1168 | pub const PRTWI: RegisterBits = RegisterBits::new(0x80); 1169 | pub const PRTWI0: RegisterBits = RegisterBits::new(1<<7); 1170 | 1171 | pub const PRTIM2: RegisterBits = RegisterBits::new(0x40); 1172 | pub const PRTIM20: RegisterBits = RegisterBits::new(1<<6); 1173 | 1174 | pub const PRTIM0: RegisterBits = RegisterBits::new(0x20); 1175 | pub const PRTIM00: RegisterBits = RegisterBits::new(1<<5); 1176 | 1177 | pub const PRTIM1: RegisterBits = RegisterBits::new(0x8); 1178 | pub const PRTIM10: RegisterBits = RegisterBits::new(1<<3); 1179 | 1180 | pub const PRSPI: RegisterBits = RegisterBits::new(0x4); 1181 | pub const PRSPI0: RegisterBits = RegisterBits::new(1<<2); 1182 | 1183 | pub const PRUSART0: RegisterBits = RegisterBits::new(0x2); 1184 | pub const PRUSART00: RegisterBits = RegisterBits::new(1<<1); 1185 | 1186 | pub const PRADC: RegisterBits = RegisterBits::new(0x1); 1187 | pub const PRADC0: RegisterBits = RegisterBits::new(1<<0); 1188 | 1189 | } 1190 | 1191 | impl Register for PRR { 1192 | type T = u8; 1193 | const ADDRESS: *mut u8 = 0x64 as *mut u8; 1194 | } 1195 | #[allow(non_camel_case_types)] 1196 | pub struct OSCCAL; 1197 | 1198 | impl OSCCAL { 1199 | pub const OSCCAL: RegisterBits = RegisterBits::new(0xff); 1200 | pub const OSCCAL0: RegisterBits = RegisterBits::new(1<<0); 1201 | pub const OSCCAL1: RegisterBits = RegisterBits::new(1<<1); 1202 | pub const OSCCAL2: RegisterBits = RegisterBits::new(1<<2); 1203 | pub const OSCCAL3: RegisterBits = RegisterBits::new(1<<3); 1204 | pub const OSCCAL4: RegisterBits = RegisterBits::new(1<<4); 1205 | pub const OSCCAL5: RegisterBits = RegisterBits::new(1<<5); 1206 | pub const OSCCAL6: RegisterBits = RegisterBits::new(1<<6); 1207 | pub const OSCCAL7: RegisterBits = RegisterBits::new(1<<7); 1208 | 1209 | } 1210 | 1211 | impl Register for OSCCAL { 1212 | type T = u8; 1213 | const ADDRESS: *mut u8 = 0x66 as *mut u8; 1214 | } 1215 | #[allow(non_camel_case_types)] 1216 | pub struct CLKPR; 1217 | 1218 | impl CLKPR { 1219 | pub const CLKPCE: RegisterBits = RegisterBits::new(0x80); 1220 | pub const CLKPCE0: RegisterBits = RegisterBits::new(1<<7); 1221 | 1222 | pub const CLKPS: RegisterBits = RegisterBits::new(0xf); 1223 | pub const CLKPS0: RegisterBits = RegisterBits::new(1<<0); 1224 | pub const CLKPS1: RegisterBits = RegisterBits::new(1<<1); 1225 | pub const CLKPS2: RegisterBits = RegisterBits::new(1<<2); 1226 | pub const CLKPS3: RegisterBits = RegisterBits::new(1<<3); 1227 | 1228 | } 1229 | 1230 | impl Register for CLKPR { 1231 | type T = u8; 1232 | const ADDRESS: *mut u8 = 0x61 as *mut u8; 1233 | } 1234 | #[allow(non_camel_case_types)] 1235 | pub struct SREG; 1236 | 1237 | impl SREG { 1238 | pub const I: RegisterBits = RegisterBits::new(0x80); 1239 | pub const I0: RegisterBits = RegisterBits::new(1<<7); 1240 | 1241 | pub const T: RegisterBits = RegisterBits::new(0x40); 1242 | pub const T0: RegisterBits = RegisterBits::new(1<<6); 1243 | 1244 | pub const H: RegisterBits = RegisterBits::new(0x20); 1245 | pub const H0: RegisterBits = RegisterBits::new(1<<5); 1246 | 1247 | pub const S: RegisterBits = RegisterBits::new(0x10); 1248 | pub const S0: RegisterBits = RegisterBits::new(1<<4); 1249 | 1250 | pub const V: RegisterBits = RegisterBits::new(0x8); 1251 | pub const V0: RegisterBits = RegisterBits::new(1<<3); 1252 | 1253 | pub const N: RegisterBits = RegisterBits::new(0x4); 1254 | pub const N0: RegisterBits = RegisterBits::new(1<<2); 1255 | 1256 | pub const Z: RegisterBits = RegisterBits::new(0x2); 1257 | pub const Z0: RegisterBits = RegisterBits::new(1<<1); 1258 | 1259 | pub const C: RegisterBits = RegisterBits::new(0x1); 1260 | pub const C0: RegisterBits = RegisterBits::new(1<<0); 1261 | 1262 | } 1263 | 1264 | impl Register for SREG { 1265 | type T = u8; 1266 | const ADDRESS: *mut u8 = 0x5f as *mut u8; 1267 | } 1268 | #[allow(non_camel_case_types)] 1269 | pub struct SP; 1270 | 1271 | impl SP { 1272 | } 1273 | 1274 | impl Register for SP { 1275 | type T = u16; 1276 | const ADDRESS: *mut u16 = 0x5d as *mut u16; 1277 | } 1278 | #[allow(non_camel_case_types)] 1279 | pub struct SPMCSR; 1280 | 1281 | impl SPMCSR { 1282 | pub const SPMIE: RegisterBits = RegisterBits::new(0x80); 1283 | pub const SPMIE0: RegisterBits = RegisterBits::new(1<<7); 1284 | 1285 | pub const RWWSB: RegisterBits = RegisterBits::new(0x40); 1286 | pub const RWWSB0: RegisterBits = RegisterBits::new(1<<6); 1287 | 1288 | pub const RWWSRE: RegisterBits = RegisterBits::new(0x10); 1289 | pub const RWWSRE0: RegisterBits = RegisterBits::new(1<<4); 1290 | 1291 | pub const BLBSET: RegisterBits = RegisterBits::new(0x8); 1292 | pub const BLBSET0: RegisterBits = RegisterBits::new(1<<3); 1293 | 1294 | pub const PGWRT: RegisterBits = RegisterBits::new(0x4); 1295 | pub const PGWRT0: RegisterBits = RegisterBits::new(1<<2); 1296 | 1297 | pub const PGERS: RegisterBits = RegisterBits::new(0x2); 1298 | pub const PGERS0: RegisterBits = RegisterBits::new(1<<1); 1299 | 1300 | pub const SELFPRGEN: RegisterBits = RegisterBits::new(0x1); 1301 | pub const SELFPRGEN0: RegisterBits = RegisterBits::new(1<<0); 1302 | 1303 | } 1304 | 1305 | impl Register for SPMCSR { 1306 | type T = u8; 1307 | const ADDRESS: *mut u8 = 0x57 as *mut u8; 1308 | } 1309 | #[allow(non_camel_case_types)] 1310 | pub struct MCUCR; 1311 | 1312 | impl MCUCR { 1313 | pub const PUD: RegisterBits = RegisterBits::new(0x10); 1314 | pub const PUD0: RegisterBits = RegisterBits::new(1<<4); 1315 | 1316 | } 1317 | 1318 | impl Register for MCUCR { 1319 | type T = u8; 1320 | const ADDRESS: *mut u8 = 0x55 as *mut u8; 1321 | } 1322 | #[allow(non_camel_case_types)] 1323 | pub struct MCUSR; 1324 | 1325 | impl MCUSR { 1326 | pub const WDRF: RegisterBits = RegisterBits::new(0x8); 1327 | pub const WDRF0: RegisterBits = RegisterBits::new(1<<3); 1328 | 1329 | pub const BORF: RegisterBits = RegisterBits::new(0x4); 1330 | pub const BORF0: RegisterBits = RegisterBits::new(1<<2); 1331 | 1332 | pub const EXTRF: RegisterBits = RegisterBits::new(0x2); 1333 | pub const EXTRF0: RegisterBits = RegisterBits::new(1<<1); 1334 | 1335 | pub const PORF: RegisterBits = RegisterBits::new(0x1); 1336 | pub const PORF0: RegisterBits = RegisterBits::new(1<<0); 1337 | 1338 | } 1339 | 1340 | impl Register for MCUSR { 1341 | type T = u8; 1342 | const ADDRESS: *mut u8 = 0x54 as *mut u8; 1343 | } 1344 | #[allow(non_camel_case_types)] 1345 | pub struct SMCR; 1346 | 1347 | impl SMCR { 1348 | pub const SM: RegisterBits = RegisterBits::new(0xe); 1349 | pub const SM0: RegisterBits = RegisterBits::new(1<<1); 1350 | pub const SM1: RegisterBits = RegisterBits::new(1<<2); 1351 | pub const SM2: RegisterBits = RegisterBits::new(1<<3); 1352 | 1353 | pub const SE: RegisterBits = RegisterBits::new(0x1); 1354 | pub const SE0: RegisterBits = RegisterBits::new(1<<0); 1355 | 1356 | } 1357 | 1358 | impl Register for SMCR { 1359 | type T = u8; 1360 | const ADDRESS: *mut u8 = 0x53 as *mut u8; 1361 | } 1362 | #[allow(non_camel_case_types)] 1363 | pub struct GPIOR2; 1364 | 1365 | impl GPIOR2 { 1366 | } 1367 | 1368 | impl Register for GPIOR2 { 1369 | type T = u8; 1370 | const ADDRESS: *mut u8 = 0x4b as *mut u8; 1371 | } 1372 | #[allow(non_camel_case_types)] 1373 | pub struct GPIOR1; 1374 | 1375 | impl GPIOR1 { 1376 | } 1377 | 1378 | impl Register for GPIOR1 { 1379 | type T = u8; 1380 | const ADDRESS: *mut u8 = 0x4a as *mut u8; 1381 | } 1382 | #[allow(non_camel_case_types)] 1383 | pub struct GPIOR0; 1384 | 1385 | impl GPIOR0 { 1386 | } 1387 | 1388 | impl Register for GPIOR0 { 1389 | type T = u8; 1390 | const ADDRESS: *mut u8 = 0x3e as *mut u8; 1391 | } 1392 | #[allow(non_camel_case_types)] 1393 | pub struct WDTCSR; 1394 | 1395 | impl WDTCSR { 1396 | pub const WDIF: RegisterBits = RegisterBits::new(0x80); 1397 | pub const WDIF0: RegisterBits = RegisterBits::new(1<<7); 1398 | 1399 | pub const WDIE: RegisterBits = RegisterBits::new(0x40); 1400 | pub const WDIE0: RegisterBits = RegisterBits::new(1<<6); 1401 | 1402 | pub const WDP: RegisterBits = RegisterBits::new(0x27); 1403 | pub const WDP0: RegisterBits = RegisterBits::new(1<<0); 1404 | pub const WDP1: RegisterBits = RegisterBits::new(1<<1); 1405 | pub const WDP2: RegisterBits = RegisterBits::new(1<<2); 1406 | pub const WDP3: RegisterBits = RegisterBits::new(1<<5); 1407 | 1408 | pub const WDCE: RegisterBits = RegisterBits::new(0x10); 1409 | pub const WDCE0: RegisterBits = RegisterBits::new(1<<4); 1410 | 1411 | pub const WDE: RegisterBits = RegisterBits::new(0x8); 1412 | pub const WDE0: RegisterBits = RegisterBits::new(1<<3); 1413 | 1414 | } 1415 | 1416 | impl Register for WDTCSR { 1417 | type T = u8; 1418 | const ADDRESS: *mut u8 = 0x60 as *mut u8; 1419 | } 1420 | #[allow(non_camel_case_types)] 1421 | pub struct EEARL; 1422 | 1423 | impl EEARL { 1424 | } 1425 | 1426 | impl Register for EEARL { 1427 | type T = u8; 1428 | const ADDRESS: *mut u8 = 0x41 as *mut u8; 1429 | } 1430 | #[allow(non_camel_case_types)] 1431 | pub struct EEDR; 1432 | 1433 | impl EEDR { 1434 | } 1435 | 1436 | impl Register for EEDR { 1437 | type T = u8; 1438 | const ADDRESS: *mut u8 = 0x40 as *mut u8; 1439 | } 1440 | #[allow(non_camel_case_types)] 1441 | pub struct EECR; 1442 | 1443 | impl EECR { 1444 | pub const EEPM: RegisterBits = RegisterBits::new(0x30); 1445 | pub const EEPM0: RegisterBits = RegisterBits::new(1<<4); 1446 | pub const EEPM1: RegisterBits = RegisterBits::new(1<<5); 1447 | 1448 | pub const EERIE: RegisterBits = RegisterBits::new(0x8); 1449 | pub const EERIE0: RegisterBits = RegisterBits::new(1<<3); 1450 | 1451 | pub const EEMPE: RegisterBits = RegisterBits::new(0x4); 1452 | pub const EEMPE0: RegisterBits = RegisterBits::new(1<<2); 1453 | 1454 | pub const EEPE: RegisterBits = RegisterBits::new(0x2); 1455 | pub const EEPE0: RegisterBits = RegisterBits::new(1<<1); 1456 | 1457 | pub const EERE: RegisterBits = RegisterBits::new(0x1); 1458 | pub const EERE0: RegisterBits = RegisterBits::new(1<<0); 1459 | 1460 | } 1461 | 1462 | impl Register for EECR { 1463 | type T = u8; 1464 | const ADDRESS: *mut u8 = 0x3f as *mut u8; 1465 | } 1466 | pub mod port { 1467 | #![allow(unused_imports)] 1468 | 1469 | use super::*; 1470 | use crate::Pin; 1471 | 1472 | pub struct B0; 1473 | 1474 | impl Pin for B0 { 1475 | /// Port B Data Register. 1476 | type PORT = PORTB; 1477 | /// Port B Data Direction Register. 1478 | type DDR = DDRB; 1479 | /// Port B Input Pins. 1480 | type PIN = PINB; 1481 | /// PB0 1482 | const MASK: u8 = 1<<0; 1483 | } 1484 | 1485 | pub struct B1; 1486 | 1487 | impl Pin for B1 { 1488 | /// Port B Data Register. 1489 | type PORT = PORTB; 1490 | /// Port B Data Direction Register. 1491 | type DDR = DDRB; 1492 | /// Port B Input Pins. 1493 | type PIN = PINB; 1494 | /// PB1 1495 | const MASK: u8 = 1<<1; 1496 | } 1497 | 1498 | pub struct B2; 1499 | 1500 | impl Pin for B2 { 1501 | /// Port B Data Register. 1502 | type PORT = PORTB; 1503 | /// Port B Data Direction Register. 1504 | type DDR = DDRB; 1505 | /// Port B Input Pins. 1506 | type PIN = PINB; 1507 | /// PB2 1508 | const MASK: u8 = 1<<2; 1509 | } 1510 | 1511 | pub struct B3; 1512 | 1513 | impl Pin for B3 { 1514 | /// Port B Data Register. 1515 | type PORT = PORTB; 1516 | /// Port B Data Direction Register. 1517 | type DDR = DDRB; 1518 | /// Port B Input Pins. 1519 | type PIN = PINB; 1520 | /// PB3 1521 | const MASK: u8 = 1<<3; 1522 | } 1523 | 1524 | pub struct B4; 1525 | 1526 | impl Pin for B4 { 1527 | /// Port B Data Register. 1528 | type PORT = PORTB; 1529 | /// Port B Data Direction Register. 1530 | type DDR = DDRB; 1531 | /// Port B Input Pins. 1532 | type PIN = PINB; 1533 | /// PB4 1534 | const MASK: u8 = 1<<4; 1535 | } 1536 | 1537 | pub struct B5; 1538 | 1539 | impl Pin for B5 { 1540 | /// Port B Data Register. 1541 | type PORT = PORTB; 1542 | /// Port B Data Direction Register. 1543 | type DDR = DDRB; 1544 | /// Port B Input Pins. 1545 | type PIN = PINB; 1546 | /// PB5 1547 | const MASK: u8 = 1<<5; 1548 | } 1549 | 1550 | pub struct B6; 1551 | 1552 | impl Pin for B6 { 1553 | /// Port B Data Register. 1554 | type PORT = PORTB; 1555 | /// Port B Data Direction Register. 1556 | type DDR = DDRB; 1557 | /// Port B Input Pins. 1558 | type PIN = PINB; 1559 | /// PB6 1560 | const MASK: u8 = 1<<6; 1561 | } 1562 | 1563 | pub struct B7; 1564 | 1565 | impl Pin for B7 { 1566 | /// Port B Data Register. 1567 | type PORT = PORTB; 1568 | /// Port B Data Direction Register. 1569 | type DDR = DDRB; 1570 | /// Port B Input Pins. 1571 | type PIN = PINB; 1572 | /// PB7 1573 | const MASK: u8 = 1<<7; 1574 | } 1575 | 1576 | pub struct C0; 1577 | 1578 | impl Pin for C0 { 1579 | /// Port C Data Register. 1580 | type PORT = PORTC; 1581 | /// Port C Data Direction Register. 1582 | type DDR = DDRC; 1583 | /// Port C Input Pins. 1584 | type PIN = PINC; 1585 | /// PC0 1586 | const MASK: u8 = 1<<0; 1587 | } 1588 | 1589 | pub struct C1; 1590 | 1591 | impl Pin for C1 { 1592 | /// Port C Data Register. 1593 | type PORT = PORTC; 1594 | /// Port C Data Direction Register. 1595 | type DDR = DDRC; 1596 | /// Port C Input Pins. 1597 | type PIN = PINC; 1598 | /// PC1 1599 | const MASK: u8 = 1<<1; 1600 | } 1601 | 1602 | pub struct C2; 1603 | 1604 | impl Pin for C2 { 1605 | /// Port C Data Register. 1606 | type PORT = PORTC; 1607 | /// Port C Data Direction Register. 1608 | type DDR = DDRC; 1609 | /// Port C Input Pins. 1610 | type PIN = PINC; 1611 | /// PC2 1612 | const MASK: u8 = 1<<2; 1613 | } 1614 | 1615 | pub struct C3; 1616 | 1617 | impl Pin for C3 { 1618 | /// Port C Data Register. 1619 | type PORT = PORTC; 1620 | /// Port C Data Direction Register. 1621 | type DDR = DDRC; 1622 | /// Port C Input Pins. 1623 | type PIN = PINC; 1624 | /// PC3 1625 | const MASK: u8 = 1<<3; 1626 | } 1627 | 1628 | pub struct C4; 1629 | 1630 | impl Pin for C4 { 1631 | /// Port C Data Register. 1632 | type PORT = PORTC; 1633 | /// Port C Data Direction Register. 1634 | type DDR = DDRC; 1635 | /// Port C Input Pins. 1636 | type PIN = PINC; 1637 | /// PC4 1638 | const MASK: u8 = 1<<4; 1639 | } 1640 | 1641 | pub struct C5; 1642 | 1643 | impl Pin for C5 { 1644 | /// Port C Data Register. 1645 | type PORT = PORTC; 1646 | /// Port C Data Direction Register. 1647 | type DDR = DDRC; 1648 | /// Port C Input Pins. 1649 | type PIN = PINC; 1650 | /// PC5 1651 | const MASK: u8 = 1<<5; 1652 | } 1653 | 1654 | pub struct C6; 1655 | 1656 | impl Pin for C6 { 1657 | /// Port C Data Register. 1658 | type PORT = PORTC; 1659 | /// Port C Data Direction Register. 1660 | type DDR = DDRC; 1661 | /// Port C Input Pins. 1662 | type PIN = PINC; 1663 | /// PC6 1664 | const MASK: u8 = 1<<6; 1665 | } 1666 | 1667 | pub struct D0; 1668 | 1669 | impl Pin for D0 { 1670 | /// Port D Data Register. 1671 | type PORT = PORTD; 1672 | /// Port D Data Direction Register. 1673 | type DDR = DDRD; 1674 | /// Port D Input Pins. 1675 | type PIN = PIND; 1676 | /// PD0 1677 | const MASK: u8 = 1<<0; 1678 | } 1679 | 1680 | pub struct D1; 1681 | 1682 | impl Pin for D1 { 1683 | /// Port D Data Register. 1684 | type PORT = PORTD; 1685 | /// Port D Data Direction Register. 1686 | type DDR = DDRD; 1687 | /// Port D Input Pins. 1688 | type PIN = PIND; 1689 | /// PD1 1690 | const MASK: u8 = 1<<1; 1691 | } 1692 | 1693 | pub struct D2; 1694 | 1695 | impl Pin for D2 { 1696 | /// Port D Data Register. 1697 | type PORT = PORTD; 1698 | /// Port D Data Direction Register. 1699 | type DDR = DDRD; 1700 | /// Port D Input Pins. 1701 | type PIN = PIND; 1702 | /// PD2 1703 | const MASK: u8 = 1<<2; 1704 | } 1705 | 1706 | pub struct D3; 1707 | 1708 | impl Pin for D3 { 1709 | /// Port D Data Register. 1710 | type PORT = PORTD; 1711 | /// Port D Data Direction Register. 1712 | type DDR = DDRD; 1713 | /// Port D Input Pins. 1714 | type PIN = PIND; 1715 | /// PD3 1716 | const MASK: u8 = 1<<3; 1717 | } 1718 | 1719 | pub struct D4; 1720 | 1721 | impl Pin for D4 { 1722 | /// Port D Data Register. 1723 | type PORT = PORTD; 1724 | /// Port D Data Direction Register. 1725 | type DDR = DDRD; 1726 | /// Port D Input Pins. 1727 | type PIN = PIND; 1728 | /// PD4 1729 | const MASK: u8 = 1<<4; 1730 | } 1731 | 1732 | pub struct D5; 1733 | 1734 | impl Pin for D5 { 1735 | /// Port D Data Register. 1736 | type PORT = PORTD; 1737 | /// Port D Data Direction Register. 1738 | type DDR = DDRD; 1739 | /// Port D Input Pins. 1740 | type PIN = PIND; 1741 | /// PD5 1742 | const MASK: u8 = 1<<5; 1743 | } 1744 | 1745 | pub struct D6; 1746 | 1747 | impl Pin for D6 { 1748 | /// Port D Data Register. 1749 | type PORT = PORTD; 1750 | /// Port D Data Direction Register. 1751 | type DDR = DDRD; 1752 | /// Port D Input Pins. 1753 | type PIN = PIND; 1754 | /// PD6 1755 | const MASK: u8 = 1<<6; 1756 | } 1757 | 1758 | pub struct D7; 1759 | 1760 | impl Pin for D7 { 1761 | /// Port D Data Register. 1762 | type PORT = PORTD; 1763 | /// Port D Data Direction Register. 1764 | type DDR = DDRD; 1765 | /// Port D Input Pins. 1766 | type PIN = PIND; 1767 | /// PD7 1768 | const MASK: u8 = 1<<7; 1769 | } 1770 | 1771 | } 1772 | 1773 | pub struct Spi; 1774 | 1775 | impl modules::HardwareSpi for Spi { 1776 | type SlaveSelect = port::B2; 1777 | type MasterOutSlaveIn = port::B3; 1778 | type MasterInSlaveOut = port::B4; 1779 | type Clock = port::B5; 1780 | type DataRegister = SPDR; 1781 | type StatusRegister = SPSR; 1782 | type ControlRegister = SPCR; 1783 | } 1784 | 1785 | /// The USART0 module. 1786 | pub struct USART0; 1787 | 1788 | impl modules::HardwareUsart for USART0 { 1789 | type DataRegister = UDR0; 1790 | type ControlRegisterA = UCSR0A; 1791 | type ControlRegisterB = UCSR0B; 1792 | type ControlRegisterC = UCSR0C; 1793 | type BaudRateRegister = UBRR0; 1794 | } 1795 | 1796 | /// 8-bit timer. 1797 | pub struct Timer8; 1798 | 1799 | impl modules::Timer8 for Timer8 { 1800 | type CompareA = OCR0A; 1801 | type CompareB = OCR0B; 1802 | type Counter = TCNT0; 1803 | type ControlA = TCCR0A; 1804 | type ControlB = TCCR0B; 1805 | type InterruptMask = TIMSK0; 1806 | type InterruptFlag = TIFR0; 1807 | const CS0: RegisterBits = Self::ControlB::CS00; 1808 | const CS1: RegisterBits = Self::ControlB::CS01; 1809 | const CS2: RegisterBits = Self::ControlB::CS02; 1810 | const WGM0: RegisterBits = Self::ControlA::WGM00; 1811 | const WGM1: RegisterBits = Self::ControlA::WGM01; 1812 | const WGM2: RegisterBits = Self::ControlB::WGM020; 1813 | const OCIEA: RegisterBits = Self::InterruptMask::OCIE0A; 1814 | } 1815 | /// 16-bit timer. 1816 | pub struct Timer16; 1817 | 1818 | impl modules::Timer16 for Timer16 { 1819 | type CompareA = OCR1A; 1820 | type CompareB = OCR1B; 1821 | type Counter = TCNT1; 1822 | type ControlA = TCCR1A; 1823 | type ControlB = TCCR1B; 1824 | type ControlC = TCCR1C; 1825 | type InterruptMask = TIMSK1; 1826 | type InterruptFlag = TIFR1; 1827 | const CS0: RegisterBits = Self::ControlB::CS10; 1828 | const CS1: RegisterBits = Self::ControlB::CS11; 1829 | const CS2: RegisterBits = Self::ControlB::CS12; 1830 | const WGM0: RegisterBits = Self::ControlA::WGM10; 1831 | const WGM1: RegisterBits = Self::ControlA::WGM11; 1832 | const WGM2: RegisterBits = Self::ControlB::WGM10; 1833 | const WGM3: RegisterBits = Self::ControlB::WGM11; 1834 | const OCIEA: RegisterBits = Self::InterruptMask::OCIE1A; 1835 | } 1836 | 1837 | -------------------------------------------------------------------------------- /src/cores/atmega48p.rs: -------------------------------------------------------------------------------- 1 | //! Core for ATmega48P. 2 | 3 | use crate::{modules, RegisterBits, Register}; 4 | 5 | #[allow(non_camel_case_types)] 6 | pub struct EXTENDED; 7 | 8 | impl EXTENDED { 9 | pub const SELFPRGEN: RegisterBits = RegisterBits::new(0x1); 10 | pub const SELFPRGEN0: RegisterBits = RegisterBits::new(1<<0); 11 | 12 | } 13 | 14 | impl Register for EXTENDED { 15 | type T = u8; 16 | const ADDRESS: *mut u8 = 0x2 as *mut u8; 17 | } 18 | #[allow(non_camel_case_types)] 19 | pub struct HIGH; 20 | 21 | impl HIGH { 22 | pub const RSTDISBL: RegisterBits = RegisterBits::new(0x80); 23 | pub const RSTDISBL0: RegisterBits = RegisterBits::new(1<<7); 24 | 25 | pub const DWEN: RegisterBits = RegisterBits::new(0x40); 26 | pub const DWEN0: RegisterBits = RegisterBits::new(1<<6); 27 | 28 | pub const SPIEN: RegisterBits = RegisterBits::new(0x20); 29 | pub const SPIEN0: RegisterBits = RegisterBits::new(1<<5); 30 | 31 | pub const WDTON: RegisterBits = RegisterBits::new(0x10); 32 | pub const WDTON0: RegisterBits = RegisterBits::new(1<<4); 33 | 34 | pub const EESAVE: RegisterBits = RegisterBits::new(0x8); 35 | pub const EESAVE0: RegisterBits = RegisterBits::new(1<<3); 36 | 37 | pub const BODLEVEL: RegisterBits = RegisterBits::new(0x7); 38 | pub const BODLEVEL0: RegisterBits = RegisterBits::new(1<<0); 39 | pub const BODLEVEL1: RegisterBits = RegisterBits::new(1<<1); 40 | pub const BODLEVEL2: RegisterBits = RegisterBits::new(1<<2); 41 | 42 | } 43 | 44 | impl Register for HIGH { 45 | type T = u8; 46 | const ADDRESS: *mut u8 = 0x1 as *mut u8; 47 | } 48 | #[allow(non_camel_case_types)] 49 | pub struct LOW; 50 | 51 | impl LOW { 52 | pub const CKDIV8: RegisterBits = RegisterBits::new(0x80); 53 | pub const CKDIV80: RegisterBits = RegisterBits::new(1<<7); 54 | 55 | pub const CKOUT: RegisterBits = RegisterBits::new(0x40); 56 | pub const CKOUT0: RegisterBits = RegisterBits::new(1<<6); 57 | 58 | pub const SUT_CKSEL: RegisterBits = RegisterBits::new(0x3f); 59 | pub const SUT_CKSEL0: RegisterBits = RegisterBits::new(1<<0); 60 | pub const SUT_CKSEL1: RegisterBits = RegisterBits::new(1<<1); 61 | pub const SUT_CKSEL2: RegisterBits = RegisterBits::new(1<<2); 62 | pub const SUT_CKSEL3: RegisterBits = RegisterBits::new(1<<3); 63 | pub const SUT_CKSEL4: RegisterBits = RegisterBits::new(1<<4); 64 | pub const SUT_CKSEL5: RegisterBits = RegisterBits::new(1<<5); 65 | 66 | } 67 | 68 | impl Register for LOW { 69 | type T = u8; 70 | const ADDRESS: *mut u8 = 0x0 as *mut u8; 71 | } 72 | #[allow(non_camel_case_types)] 73 | pub struct LOCKBIT; 74 | 75 | impl LOCKBIT { 76 | pub const LB: RegisterBits = RegisterBits::new(0x3); 77 | pub const LB0: RegisterBits = RegisterBits::new(1<<0); 78 | pub const LB1: RegisterBits = RegisterBits::new(1<<1); 79 | 80 | } 81 | 82 | impl Register for LOCKBIT { 83 | type T = u8; 84 | const ADDRESS: *mut u8 = 0x0 as *mut u8; 85 | } 86 | #[allow(non_camel_case_types)] 87 | pub struct UDR0; 88 | 89 | impl UDR0 { 90 | } 91 | 92 | impl Register for UDR0 { 93 | type T = u8; 94 | const ADDRESS: *mut u8 = 0xc6 as *mut u8; 95 | } 96 | #[allow(non_camel_case_types)] 97 | pub struct UCSR0A; 98 | 99 | impl UCSR0A { 100 | pub const RXC0: RegisterBits = RegisterBits::new(0x80); 101 | pub const RXC00: RegisterBits = RegisterBits::new(1<<7); 102 | 103 | pub const TXC0: RegisterBits = RegisterBits::new(0x40); 104 | pub const TXC00: RegisterBits = RegisterBits::new(1<<6); 105 | 106 | pub const UDRE0: RegisterBits = RegisterBits::new(0x20); 107 | pub const UDRE00: RegisterBits = RegisterBits::new(1<<5); 108 | 109 | pub const FE0: RegisterBits = RegisterBits::new(0x10); 110 | pub const FE00: RegisterBits = RegisterBits::new(1<<4); 111 | 112 | pub const DOR0: RegisterBits = RegisterBits::new(0x8); 113 | pub const DOR00: RegisterBits = RegisterBits::new(1<<3); 114 | 115 | pub const UPE0: RegisterBits = RegisterBits::new(0x4); 116 | pub const UPE00: RegisterBits = RegisterBits::new(1<<2); 117 | 118 | pub const U2X0: RegisterBits = RegisterBits::new(0x2); 119 | pub const U2X00: RegisterBits = RegisterBits::new(1<<1); 120 | 121 | pub const MPCM0: RegisterBits = RegisterBits::new(0x1); 122 | pub const MPCM00: RegisterBits = RegisterBits::new(1<<0); 123 | 124 | } 125 | 126 | impl Register for UCSR0A { 127 | type T = u8; 128 | const ADDRESS: *mut u8 = 0xc0 as *mut u8; 129 | } 130 | #[allow(non_camel_case_types)] 131 | pub struct UCSR0B; 132 | 133 | impl UCSR0B { 134 | pub const RXCIE0: RegisterBits = RegisterBits::new(0x80); 135 | pub const RXCIE00: RegisterBits = RegisterBits::new(1<<7); 136 | 137 | pub const TXCIE0: RegisterBits = RegisterBits::new(0x40); 138 | pub const TXCIE00: RegisterBits = RegisterBits::new(1<<6); 139 | 140 | pub const UDRIE0: RegisterBits = RegisterBits::new(0x20); 141 | pub const UDRIE00: RegisterBits = RegisterBits::new(1<<5); 142 | 143 | pub const RXEN0: RegisterBits = RegisterBits::new(0x10); 144 | pub const RXEN00: RegisterBits = RegisterBits::new(1<<4); 145 | 146 | pub const TXEN0: RegisterBits = RegisterBits::new(0x8); 147 | pub const TXEN00: RegisterBits = RegisterBits::new(1<<3); 148 | 149 | pub const UCSZ02: RegisterBits = RegisterBits::new(0x4); 150 | pub const UCSZ020: RegisterBits = RegisterBits::new(1<<2); 151 | 152 | pub const RXB80: RegisterBits = RegisterBits::new(0x2); 153 | pub const RXB800: RegisterBits = RegisterBits::new(1<<1); 154 | 155 | pub const TXB80: RegisterBits = RegisterBits::new(0x1); 156 | pub const TXB800: RegisterBits = RegisterBits::new(1<<0); 157 | 158 | } 159 | 160 | impl Register for UCSR0B { 161 | type T = u8; 162 | const ADDRESS: *mut u8 = 0xc1 as *mut u8; 163 | } 164 | #[allow(non_camel_case_types)] 165 | pub struct UCSR0C; 166 | 167 | impl UCSR0C { 168 | pub const UMSEL0: RegisterBits = RegisterBits::new(0xc0); 169 | pub const UMSEL00: RegisterBits = RegisterBits::new(1<<6); 170 | pub const UMSEL01: RegisterBits = RegisterBits::new(1<<7); 171 | 172 | pub const UPM0: RegisterBits = RegisterBits::new(0x30); 173 | pub const UPM00: RegisterBits = RegisterBits::new(1<<4); 174 | pub const UPM01: RegisterBits = RegisterBits::new(1<<5); 175 | 176 | pub const USBS0: RegisterBits = RegisterBits::new(0x8); 177 | pub const USBS00: RegisterBits = RegisterBits::new(1<<3); 178 | 179 | pub const UCSZ0: RegisterBits = RegisterBits::new(0x6); 180 | pub const UCSZ00: RegisterBits = RegisterBits::new(1<<1); 181 | pub const UCSZ01: RegisterBits = RegisterBits::new(1<<2); 182 | 183 | pub const UCPOL0: RegisterBits = RegisterBits::new(0x1); 184 | pub const UCPOL00: RegisterBits = RegisterBits::new(1<<0); 185 | 186 | } 187 | 188 | impl Register for UCSR0C { 189 | type T = u8; 190 | const ADDRESS: *mut u8 = 0xc2 as *mut u8; 191 | } 192 | #[allow(non_camel_case_types)] 193 | pub struct UBRR0; 194 | 195 | impl UBRR0 { 196 | } 197 | 198 | impl Register for UBRR0 { 199 | type T = u16; 200 | const ADDRESS: *mut u16 = 0xc4 as *mut u16; 201 | } 202 | #[allow(non_camel_case_types)] 203 | pub struct TWAMR; 204 | 205 | impl TWAMR { 206 | pub const TWAM: RegisterBits = RegisterBits::new(0xfe); 207 | pub const TWAM0: RegisterBits = RegisterBits::new(1<<1); 208 | pub const TWAM1: RegisterBits = RegisterBits::new(1<<2); 209 | pub const TWAM2: RegisterBits = RegisterBits::new(1<<3); 210 | pub const TWAM3: RegisterBits = RegisterBits::new(1<<4); 211 | pub const TWAM4: RegisterBits = RegisterBits::new(1<<5); 212 | pub const TWAM5: RegisterBits = RegisterBits::new(1<<6); 213 | pub const TWAM6: RegisterBits = RegisterBits::new(1<<7); 214 | 215 | } 216 | 217 | impl Register for TWAMR { 218 | type T = u8; 219 | const ADDRESS: *mut u8 = 0xbd as *mut u8; 220 | } 221 | #[allow(non_camel_case_types)] 222 | pub struct TWBR; 223 | 224 | impl TWBR { 225 | } 226 | 227 | impl Register for TWBR { 228 | type T = u8; 229 | const ADDRESS: *mut u8 = 0xb8 as *mut u8; 230 | } 231 | #[allow(non_camel_case_types)] 232 | pub struct TWCR; 233 | 234 | impl TWCR { 235 | pub const TWINT: RegisterBits = RegisterBits::new(0x80); 236 | pub const TWINT0: RegisterBits = RegisterBits::new(1<<7); 237 | 238 | pub const TWEA: RegisterBits = RegisterBits::new(0x40); 239 | pub const TWEA0: RegisterBits = RegisterBits::new(1<<6); 240 | 241 | pub const TWSTA: RegisterBits = RegisterBits::new(0x20); 242 | pub const TWSTA0: RegisterBits = RegisterBits::new(1<<5); 243 | 244 | pub const TWSTO: RegisterBits = RegisterBits::new(0x10); 245 | pub const TWSTO0: RegisterBits = RegisterBits::new(1<<4); 246 | 247 | pub const TWWC: RegisterBits = RegisterBits::new(0x8); 248 | pub const TWWC0: RegisterBits = RegisterBits::new(1<<3); 249 | 250 | pub const TWEN: RegisterBits = RegisterBits::new(0x4); 251 | pub const TWEN0: RegisterBits = RegisterBits::new(1<<2); 252 | 253 | pub const TWIE: RegisterBits = RegisterBits::new(0x1); 254 | pub const TWIE0: RegisterBits = RegisterBits::new(1<<0); 255 | 256 | } 257 | 258 | impl Register for TWCR { 259 | type T = u8; 260 | const ADDRESS: *mut u8 = 0xbc as *mut u8; 261 | } 262 | #[allow(non_camel_case_types)] 263 | pub struct TWSR; 264 | 265 | impl TWSR { 266 | pub const TWS: RegisterBits = RegisterBits::new(0xf8); 267 | pub const TWS0: RegisterBits = RegisterBits::new(1<<3); 268 | pub const TWS1: RegisterBits = RegisterBits::new(1<<4); 269 | pub const TWS2: RegisterBits = RegisterBits::new(1<<5); 270 | pub const TWS3: RegisterBits = RegisterBits::new(1<<6); 271 | pub const TWS4: RegisterBits = RegisterBits::new(1<<7); 272 | 273 | pub const TWPS: RegisterBits = RegisterBits::new(0x3); 274 | pub const TWPS0: RegisterBits = RegisterBits::new(1<<0); 275 | pub const TWPS1: RegisterBits = RegisterBits::new(1<<1); 276 | 277 | } 278 | 279 | impl Register for TWSR { 280 | type T = u8; 281 | const ADDRESS: *mut u8 = 0xb9 as *mut u8; 282 | } 283 | #[allow(non_camel_case_types)] 284 | pub struct TWDR; 285 | 286 | impl TWDR { 287 | } 288 | 289 | impl Register for TWDR { 290 | type T = u8; 291 | const ADDRESS: *mut u8 = 0xbb as *mut u8; 292 | } 293 | #[allow(non_camel_case_types)] 294 | pub struct TWAR; 295 | 296 | impl TWAR { 297 | pub const TWA: RegisterBits = RegisterBits::new(0xfe); 298 | pub const TWA0: RegisterBits = RegisterBits::new(1<<1); 299 | pub const TWA1: RegisterBits = RegisterBits::new(1<<2); 300 | pub const TWA2: RegisterBits = RegisterBits::new(1<<3); 301 | pub const TWA3: RegisterBits = RegisterBits::new(1<<4); 302 | pub const TWA4: RegisterBits = RegisterBits::new(1<<5); 303 | pub const TWA5: RegisterBits = RegisterBits::new(1<<6); 304 | pub const TWA6: RegisterBits = RegisterBits::new(1<<7); 305 | 306 | pub const TWGCE: RegisterBits = RegisterBits::new(0x1); 307 | pub const TWGCE0: RegisterBits = RegisterBits::new(1<<0); 308 | 309 | } 310 | 311 | impl Register for TWAR { 312 | type T = u8; 313 | const ADDRESS: *mut u8 = 0xba as *mut u8; 314 | } 315 | #[allow(non_camel_case_types)] 316 | pub struct TIMSK1; 317 | 318 | impl TIMSK1 { 319 | pub const ICIE1: RegisterBits = RegisterBits::new(0x20); 320 | pub const ICIE10: RegisterBits = RegisterBits::new(1<<5); 321 | 322 | pub const OCIE1B: RegisterBits = RegisterBits::new(0x4); 323 | pub const OCIE1B0: RegisterBits = RegisterBits::new(1<<2); 324 | 325 | pub const OCIE1A: RegisterBits = RegisterBits::new(0x2); 326 | pub const OCIE1A0: RegisterBits = RegisterBits::new(1<<1); 327 | 328 | pub const TOIE1: RegisterBits = RegisterBits::new(0x1); 329 | pub const TOIE10: RegisterBits = RegisterBits::new(1<<0); 330 | 331 | } 332 | 333 | impl Register for TIMSK1 { 334 | type T = u8; 335 | const ADDRESS: *mut u8 = 0x6f as *mut u8; 336 | } 337 | #[allow(non_camel_case_types)] 338 | pub struct TIFR1; 339 | 340 | impl TIFR1 { 341 | pub const ICF1: RegisterBits = RegisterBits::new(0x20); 342 | pub const ICF10: RegisterBits = RegisterBits::new(1<<5); 343 | 344 | pub const OCF1B: RegisterBits = RegisterBits::new(0x4); 345 | pub const OCF1B0: RegisterBits = RegisterBits::new(1<<2); 346 | 347 | pub const OCF1A: RegisterBits = RegisterBits::new(0x2); 348 | pub const OCF1A0: RegisterBits = RegisterBits::new(1<<1); 349 | 350 | pub const TOV1: RegisterBits = RegisterBits::new(0x1); 351 | pub const TOV10: RegisterBits = RegisterBits::new(1<<0); 352 | 353 | } 354 | 355 | impl Register for TIFR1 { 356 | type T = u8; 357 | const ADDRESS: *mut u8 = 0x36 as *mut u8; 358 | } 359 | #[allow(non_camel_case_types)] 360 | pub struct TCCR1A; 361 | 362 | impl TCCR1A { 363 | pub const COM1A: RegisterBits = RegisterBits::new(0xc0); 364 | pub const COM1A0: RegisterBits = RegisterBits::new(1<<6); 365 | pub const COM1A1: RegisterBits = RegisterBits::new(1<<7); 366 | 367 | pub const COM1B: RegisterBits = RegisterBits::new(0x30); 368 | pub const COM1B0: RegisterBits = RegisterBits::new(1<<4); 369 | pub const COM1B1: RegisterBits = RegisterBits::new(1<<5); 370 | 371 | pub const WGM1: RegisterBits = RegisterBits::new(0x3); 372 | pub const WGM10: RegisterBits = RegisterBits::new(1<<0); 373 | pub const WGM11: RegisterBits = RegisterBits::new(1<<1); 374 | 375 | } 376 | 377 | impl Register for TCCR1A { 378 | type T = u8; 379 | const ADDRESS: *mut u8 = 0x80 as *mut u8; 380 | } 381 | #[allow(non_camel_case_types)] 382 | pub struct TCCR1B; 383 | 384 | impl TCCR1B { 385 | pub const ICNC1: RegisterBits = RegisterBits::new(0x80); 386 | pub const ICNC10: RegisterBits = RegisterBits::new(1<<7); 387 | 388 | pub const ICES1: RegisterBits = RegisterBits::new(0x40); 389 | pub const ICES10: RegisterBits = RegisterBits::new(1<<6); 390 | 391 | pub const WGM1: RegisterBits = RegisterBits::new(0x18); 392 | pub const WGM10: RegisterBits = RegisterBits::new(1<<3); 393 | pub const WGM11: RegisterBits = RegisterBits::new(1<<4); 394 | 395 | pub const CS1: RegisterBits = RegisterBits::new(0x7); 396 | pub const CS10: RegisterBits = RegisterBits::new(1<<0); 397 | pub const CS11: RegisterBits = RegisterBits::new(1<<1); 398 | pub const CS12: RegisterBits = RegisterBits::new(1<<2); 399 | 400 | } 401 | 402 | impl Register for TCCR1B { 403 | type T = u8; 404 | const ADDRESS: *mut u8 = 0x81 as *mut u8; 405 | } 406 | #[allow(non_camel_case_types)] 407 | pub struct TCCR1C; 408 | 409 | impl TCCR1C { 410 | pub const FOC1A: RegisterBits = RegisterBits::new(0x80); 411 | pub const FOC1A0: RegisterBits = RegisterBits::new(1<<7); 412 | 413 | pub const FOC1B: RegisterBits = RegisterBits::new(0x40); 414 | pub const FOC1B0: RegisterBits = RegisterBits::new(1<<6); 415 | 416 | } 417 | 418 | impl Register for TCCR1C { 419 | type T = u8; 420 | const ADDRESS: *mut u8 = 0x82 as *mut u8; 421 | } 422 | #[allow(non_camel_case_types)] 423 | pub struct TCNT1; 424 | 425 | impl TCNT1 { 426 | } 427 | 428 | impl Register for TCNT1 { 429 | type T = u16; 430 | const ADDRESS: *mut u16 = 0x84 as *mut u16; 431 | } 432 | #[allow(non_camel_case_types)] 433 | pub struct OCR1A; 434 | 435 | impl OCR1A { 436 | } 437 | 438 | impl Register for OCR1A { 439 | type T = u16; 440 | const ADDRESS: *mut u16 = 0x88 as *mut u16; 441 | } 442 | #[allow(non_camel_case_types)] 443 | pub struct OCR1B; 444 | 445 | impl OCR1B { 446 | } 447 | 448 | impl Register for OCR1B { 449 | type T = u16; 450 | const ADDRESS: *mut u16 = 0x8a as *mut u16; 451 | } 452 | #[allow(non_camel_case_types)] 453 | pub struct ICR1; 454 | 455 | impl ICR1 { 456 | } 457 | 458 | impl Register for ICR1 { 459 | type T = u16; 460 | const ADDRESS: *mut u16 = 0x86 as *mut u16; 461 | } 462 | #[allow(non_camel_case_types)] 463 | pub struct TIMSK2; 464 | 465 | impl TIMSK2 { 466 | pub const OCIE2B: RegisterBits = RegisterBits::new(0x4); 467 | pub const OCIE2B0: RegisterBits = RegisterBits::new(1<<2); 468 | 469 | pub const OCIE2A: RegisterBits = RegisterBits::new(0x2); 470 | pub const OCIE2A0: RegisterBits = RegisterBits::new(1<<1); 471 | 472 | pub const TOIE2: RegisterBits = RegisterBits::new(0x1); 473 | pub const TOIE20: RegisterBits = RegisterBits::new(1<<0); 474 | 475 | } 476 | 477 | impl Register for TIMSK2 { 478 | type T = u8; 479 | const ADDRESS: *mut u8 = 0x70 as *mut u8; 480 | } 481 | #[allow(non_camel_case_types)] 482 | pub struct TIFR2; 483 | 484 | impl TIFR2 { 485 | pub const OCF2B: RegisterBits = RegisterBits::new(0x4); 486 | pub const OCF2B0: RegisterBits = RegisterBits::new(1<<2); 487 | 488 | pub const OCF2A: RegisterBits = RegisterBits::new(0x2); 489 | pub const OCF2A0: RegisterBits = RegisterBits::new(1<<1); 490 | 491 | pub const TOV2: RegisterBits = RegisterBits::new(0x1); 492 | pub const TOV20: RegisterBits = RegisterBits::new(1<<0); 493 | 494 | } 495 | 496 | impl Register for TIFR2 { 497 | type T = u8; 498 | const ADDRESS: *mut u8 = 0x37 as *mut u8; 499 | } 500 | #[allow(non_camel_case_types)] 501 | pub struct TCCR2A; 502 | 503 | impl TCCR2A { 504 | pub const COM2A: RegisterBits = RegisterBits::new(0xc0); 505 | pub const COM2A0: RegisterBits = RegisterBits::new(1<<6); 506 | pub const COM2A1: RegisterBits = RegisterBits::new(1<<7); 507 | 508 | pub const COM2B: RegisterBits = RegisterBits::new(0x30); 509 | pub const COM2B0: RegisterBits = RegisterBits::new(1<<4); 510 | pub const COM2B1: RegisterBits = RegisterBits::new(1<<5); 511 | 512 | pub const WGM2: RegisterBits = RegisterBits::new(0x3); 513 | pub const WGM20: RegisterBits = RegisterBits::new(1<<0); 514 | pub const WGM21: RegisterBits = RegisterBits::new(1<<1); 515 | 516 | } 517 | 518 | impl Register for TCCR2A { 519 | type T = u8; 520 | const ADDRESS: *mut u8 = 0xb0 as *mut u8; 521 | } 522 | #[allow(non_camel_case_types)] 523 | pub struct TCCR2B; 524 | 525 | impl TCCR2B { 526 | pub const FOC2A: RegisterBits = RegisterBits::new(0x80); 527 | pub const FOC2A0: RegisterBits = RegisterBits::new(1<<7); 528 | 529 | pub const FOC2B: RegisterBits = RegisterBits::new(0x40); 530 | pub const FOC2B0: RegisterBits = RegisterBits::new(1<<6); 531 | 532 | pub const WGM22: RegisterBits = RegisterBits::new(0x8); 533 | pub const WGM220: RegisterBits = RegisterBits::new(1<<3); 534 | 535 | pub const CS2: RegisterBits = RegisterBits::new(0x7); 536 | pub const CS20: RegisterBits = RegisterBits::new(1<<0); 537 | pub const CS21: RegisterBits = RegisterBits::new(1<<1); 538 | pub const CS22: RegisterBits = RegisterBits::new(1<<2); 539 | 540 | } 541 | 542 | impl Register for TCCR2B { 543 | type T = u8; 544 | const ADDRESS: *mut u8 = 0xb1 as *mut u8; 545 | } 546 | #[allow(non_camel_case_types)] 547 | pub struct TCNT2; 548 | 549 | impl TCNT2 { 550 | } 551 | 552 | impl Register for TCNT2 { 553 | type T = u8; 554 | const ADDRESS: *mut u8 = 0xb2 as *mut u8; 555 | } 556 | #[allow(non_camel_case_types)] 557 | pub struct OCR2B; 558 | 559 | impl OCR2B { 560 | } 561 | 562 | impl Register for OCR2B { 563 | type T = u8; 564 | const ADDRESS: *mut u8 = 0xb4 as *mut u8; 565 | } 566 | #[allow(non_camel_case_types)] 567 | pub struct OCR2A; 568 | 569 | impl OCR2A { 570 | } 571 | 572 | impl Register for OCR2A { 573 | type T = u8; 574 | const ADDRESS: *mut u8 = 0xb3 as *mut u8; 575 | } 576 | #[allow(non_camel_case_types)] 577 | pub struct ASSR; 578 | 579 | impl ASSR { 580 | pub const EXCLK: RegisterBits = RegisterBits::new(0x40); 581 | pub const EXCLK0: RegisterBits = RegisterBits::new(1<<6); 582 | 583 | pub const AS2: RegisterBits = RegisterBits::new(0x20); 584 | pub const AS20: RegisterBits = RegisterBits::new(1<<5); 585 | 586 | pub const TCN2UB: RegisterBits = RegisterBits::new(0x10); 587 | pub const TCN2UB0: RegisterBits = RegisterBits::new(1<<4); 588 | 589 | pub const OCR2AUB: RegisterBits = RegisterBits::new(0x8); 590 | pub const OCR2AUB0: RegisterBits = RegisterBits::new(1<<3); 591 | 592 | pub const OCR2BUB: RegisterBits = RegisterBits::new(0x4); 593 | pub const OCR2BUB0: RegisterBits = RegisterBits::new(1<<2); 594 | 595 | pub const TCR2AUB: RegisterBits = RegisterBits::new(0x2); 596 | pub const TCR2AUB0: RegisterBits = RegisterBits::new(1<<1); 597 | 598 | pub const TCR2BUB: RegisterBits = RegisterBits::new(0x1); 599 | pub const TCR2BUB0: RegisterBits = RegisterBits::new(1<<0); 600 | 601 | } 602 | 603 | impl Register for ASSR { 604 | type T = u8; 605 | const ADDRESS: *mut u8 = 0xb6 as *mut u8; 606 | } 607 | #[allow(non_camel_case_types)] 608 | pub struct ADMUX; 609 | 610 | impl ADMUX { 611 | pub const REFS: RegisterBits = RegisterBits::new(0xc0); 612 | pub const REFS0: RegisterBits = RegisterBits::new(1<<6); 613 | pub const REFS1: RegisterBits = RegisterBits::new(1<<7); 614 | 615 | pub const ADLAR: RegisterBits = RegisterBits::new(0x20); 616 | pub const ADLAR0: RegisterBits = RegisterBits::new(1<<5); 617 | 618 | pub const MUX: RegisterBits = RegisterBits::new(0xf); 619 | pub const MUX0: RegisterBits = RegisterBits::new(1<<0); 620 | pub const MUX1: RegisterBits = RegisterBits::new(1<<1); 621 | pub const MUX2: RegisterBits = RegisterBits::new(1<<2); 622 | pub const MUX3: RegisterBits = RegisterBits::new(1<<3); 623 | 624 | } 625 | 626 | impl Register for ADMUX { 627 | type T = u8; 628 | const ADDRESS: *mut u8 = 0x7c as *mut u8; 629 | } 630 | #[allow(non_camel_case_types)] 631 | pub struct ADC; 632 | 633 | impl ADC { 634 | } 635 | 636 | impl Register for ADC { 637 | type T = u16; 638 | const ADDRESS: *mut u16 = 0x78 as *mut u16; 639 | } 640 | #[allow(non_camel_case_types)] 641 | pub struct ADCSRA; 642 | 643 | impl ADCSRA { 644 | pub const ADEN: RegisterBits = RegisterBits::new(0x80); 645 | pub const ADEN0: RegisterBits = RegisterBits::new(1<<7); 646 | 647 | pub const ADSC: RegisterBits = RegisterBits::new(0x40); 648 | pub const ADSC0: RegisterBits = RegisterBits::new(1<<6); 649 | 650 | pub const ADATE: RegisterBits = RegisterBits::new(0x20); 651 | pub const ADATE0: RegisterBits = RegisterBits::new(1<<5); 652 | 653 | pub const ADIF: RegisterBits = RegisterBits::new(0x10); 654 | pub const ADIF0: RegisterBits = RegisterBits::new(1<<4); 655 | 656 | pub const ADIE: RegisterBits = RegisterBits::new(0x8); 657 | pub const ADIE0: RegisterBits = RegisterBits::new(1<<3); 658 | 659 | pub const ADPS: RegisterBits = RegisterBits::new(0x7); 660 | pub const ADPS0: RegisterBits = RegisterBits::new(1<<0); 661 | pub const ADPS1: RegisterBits = RegisterBits::new(1<<1); 662 | pub const ADPS2: RegisterBits = RegisterBits::new(1<<2); 663 | 664 | } 665 | 666 | impl Register for ADCSRA { 667 | type T = u8; 668 | const ADDRESS: *mut u8 = 0x7a as *mut u8; 669 | } 670 | #[allow(non_camel_case_types)] 671 | pub struct ADCSRB; 672 | 673 | impl ADCSRB { 674 | pub const ACME: RegisterBits = RegisterBits::new(0x40); 675 | pub const ACME0: RegisterBits = RegisterBits::new(1<<6); 676 | 677 | pub const ADTS: RegisterBits = RegisterBits::new(0x7); 678 | pub const ADTS0: RegisterBits = RegisterBits::new(1<<0); 679 | pub const ADTS1: RegisterBits = RegisterBits::new(1<<1); 680 | pub const ADTS2: RegisterBits = RegisterBits::new(1<<2); 681 | 682 | } 683 | 684 | impl Register for ADCSRB { 685 | type T = u8; 686 | const ADDRESS: *mut u8 = 0x7b as *mut u8; 687 | } 688 | #[allow(non_camel_case_types)] 689 | pub struct DIDR0; 690 | 691 | impl DIDR0 { 692 | pub const ADC5D: RegisterBits = RegisterBits::new(0x20); 693 | pub const ADC5D0: RegisterBits = RegisterBits::new(1<<5); 694 | 695 | pub const ADC4D: RegisterBits = RegisterBits::new(0x10); 696 | pub const ADC4D0: RegisterBits = RegisterBits::new(1<<4); 697 | 698 | pub const ADC3D: RegisterBits = RegisterBits::new(0x8); 699 | pub const ADC3D0: RegisterBits = RegisterBits::new(1<<3); 700 | 701 | pub const ADC2D: RegisterBits = RegisterBits::new(0x4); 702 | pub const ADC2D0: RegisterBits = RegisterBits::new(1<<2); 703 | 704 | pub const ADC1D: RegisterBits = RegisterBits::new(0x2); 705 | pub const ADC1D0: RegisterBits = RegisterBits::new(1<<1); 706 | 707 | pub const ADC0D: RegisterBits = RegisterBits::new(0x1); 708 | pub const ADC0D0: RegisterBits = RegisterBits::new(1<<0); 709 | 710 | } 711 | 712 | impl Register for DIDR0 { 713 | type T = u8; 714 | const ADDRESS: *mut u8 = 0x7e as *mut u8; 715 | } 716 | #[allow(non_camel_case_types)] 717 | pub struct ACSR; 718 | 719 | impl ACSR { 720 | pub const ACD: RegisterBits = RegisterBits::new(0x80); 721 | pub const ACD0: RegisterBits = RegisterBits::new(1<<7); 722 | 723 | pub const ACBG: RegisterBits = RegisterBits::new(0x40); 724 | pub const ACBG0: RegisterBits = RegisterBits::new(1<<6); 725 | 726 | pub const ACO: RegisterBits = RegisterBits::new(0x20); 727 | pub const ACO0: RegisterBits = RegisterBits::new(1<<5); 728 | 729 | pub const ACI: RegisterBits = RegisterBits::new(0x10); 730 | pub const ACI0: RegisterBits = RegisterBits::new(1<<4); 731 | 732 | pub const ACIE: RegisterBits = RegisterBits::new(0x8); 733 | pub const ACIE0: RegisterBits = RegisterBits::new(1<<3); 734 | 735 | pub const ACIC: RegisterBits = RegisterBits::new(0x4); 736 | pub const ACIC0: RegisterBits = RegisterBits::new(1<<2); 737 | 738 | pub const ACIS: RegisterBits = RegisterBits::new(0x3); 739 | pub const ACIS0: RegisterBits = RegisterBits::new(1<<0); 740 | pub const ACIS1: RegisterBits = RegisterBits::new(1<<1); 741 | 742 | } 743 | 744 | impl Register for ACSR { 745 | type T = u8; 746 | const ADDRESS: *mut u8 = 0x50 as *mut u8; 747 | } 748 | #[allow(non_camel_case_types)] 749 | pub struct DIDR1; 750 | 751 | impl DIDR1 { 752 | pub const AIN1D: RegisterBits = RegisterBits::new(0x2); 753 | pub const AIN1D0: RegisterBits = RegisterBits::new(1<<1); 754 | 755 | pub const AIN0D: RegisterBits = RegisterBits::new(0x1); 756 | pub const AIN0D0: RegisterBits = RegisterBits::new(1<<0); 757 | 758 | } 759 | 760 | impl Register for DIDR1 { 761 | type T = u8; 762 | const ADDRESS: *mut u8 = 0x7f as *mut u8; 763 | } 764 | #[allow(non_camel_case_types)] 765 | pub struct PORTB; 766 | 767 | impl PORTB { 768 | } 769 | 770 | impl Register for PORTB { 771 | type T = u8; 772 | const ADDRESS: *mut u8 = 0x25 as *mut u8; 773 | } 774 | #[allow(non_camel_case_types)] 775 | pub struct DDRB; 776 | 777 | impl DDRB { 778 | } 779 | 780 | impl Register for DDRB { 781 | type T = u8; 782 | const ADDRESS: *mut u8 = 0x24 as *mut u8; 783 | } 784 | #[allow(non_camel_case_types)] 785 | pub struct PINB; 786 | 787 | impl PINB { 788 | } 789 | 790 | impl Register for PINB { 791 | type T = u8; 792 | const ADDRESS: *mut u8 = 0x23 as *mut u8; 793 | } 794 | #[allow(non_camel_case_types)] 795 | pub struct PORTC; 796 | 797 | impl PORTC { 798 | } 799 | 800 | impl Register for PORTC { 801 | type T = u8; 802 | const ADDRESS: *mut u8 = 0x28 as *mut u8; 803 | } 804 | #[allow(non_camel_case_types)] 805 | pub struct DDRC; 806 | 807 | impl DDRC { 808 | } 809 | 810 | impl Register for DDRC { 811 | type T = u8; 812 | const ADDRESS: *mut u8 = 0x27 as *mut u8; 813 | } 814 | #[allow(non_camel_case_types)] 815 | pub struct PINC; 816 | 817 | impl PINC { 818 | } 819 | 820 | impl Register for PINC { 821 | type T = u8; 822 | const ADDRESS: *mut u8 = 0x26 as *mut u8; 823 | } 824 | #[allow(non_camel_case_types)] 825 | pub struct PORTD; 826 | 827 | impl PORTD { 828 | } 829 | 830 | impl Register for PORTD { 831 | type T = u8; 832 | const ADDRESS: *mut u8 = 0x2b as *mut u8; 833 | } 834 | #[allow(non_camel_case_types)] 835 | pub struct DDRD; 836 | 837 | impl DDRD { 838 | } 839 | 840 | impl Register for DDRD { 841 | type T = u8; 842 | const ADDRESS: *mut u8 = 0x2a as *mut u8; 843 | } 844 | #[allow(non_camel_case_types)] 845 | pub struct PIND; 846 | 847 | impl PIND { 848 | } 849 | 850 | impl Register for PIND { 851 | type T = u8; 852 | const ADDRESS: *mut u8 = 0x29 as *mut u8; 853 | } 854 | #[allow(non_camel_case_types)] 855 | pub struct OCR0B; 856 | 857 | impl OCR0B { 858 | } 859 | 860 | impl Register for OCR0B { 861 | type T = u8; 862 | const ADDRESS: *mut u8 = 0x48 as *mut u8; 863 | } 864 | #[allow(non_camel_case_types)] 865 | pub struct OCR0A; 866 | 867 | impl OCR0A { 868 | } 869 | 870 | impl Register for OCR0A { 871 | type T = u8; 872 | const ADDRESS: *mut u8 = 0x47 as *mut u8; 873 | } 874 | #[allow(non_camel_case_types)] 875 | pub struct TCNT0; 876 | 877 | impl TCNT0 { 878 | } 879 | 880 | impl Register for TCNT0 { 881 | type T = u8; 882 | const ADDRESS: *mut u8 = 0x46 as *mut u8; 883 | } 884 | #[allow(non_camel_case_types)] 885 | pub struct TCCR0B; 886 | 887 | impl TCCR0B { 888 | pub const FOC0A: RegisterBits = RegisterBits::new(0x80); 889 | pub const FOC0A0: RegisterBits = RegisterBits::new(1<<7); 890 | 891 | pub const FOC0B: RegisterBits = RegisterBits::new(0x40); 892 | pub const FOC0B0: RegisterBits = RegisterBits::new(1<<6); 893 | 894 | pub const WGM02: RegisterBits = RegisterBits::new(0x8); 895 | pub const WGM020: RegisterBits = RegisterBits::new(1<<3); 896 | 897 | pub const CS0: RegisterBits = RegisterBits::new(0x7); 898 | pub const CS00: RegisterBits = RegisterBits::new(1<<0); 899 | pub const CS01: RegisterBits = RegisterBits::new(1<<1); 900 | pub const CS02: RegisterBits = RegisterBits::new(1<<2); 901 | 902 | } 903 | 904 | impl Register for TCCR0B { 905 | type T = u8; 906 | const ADDRESS: *mut u8 = 0x45 as *mut u8; 907 | } 908 | #[allow(non_camel_case_types)] 909 | pub struct TCCR0A; 910 | 911 | impl TCCR0A { 912 | pub const COM0A: RegisterBits = RegisterBits::new(0xc0); 913 | pub const COM0A0: RegisterBits = RegisterBits::new(1<<6); 914 | pub const COM0A1: RegisterBits = RegisterBits::new(1<<7); 915 | 916 | pub const COM0B: RegisterBits = RegisterBits::new(0x30); 917 | pub const COM0B0: RegisterBits = RegisterBits::new(1<<4); 918 | pub const COM0B1: RegisterBits = RegisterBits::new(1<<5); 919 | 920 | pub const WGM0: RegisterBits = RegisterBits::new(0x3); 921 | pub const WGM00: RegisterBits = RegisterBits::new(1<<0); 922 | pub const WGM01: RegisterBits = RegisterBits::new(1<<1); 923 | 924 | } 925 | 926 | impl Register for TCCR0A { 927 | type T = u8; 928 | const ADDRESS: *mut u8 = 0x44 as *mut u8; 929 | } 930 | #[allow(non_camel_case_types)] 931 | pub struct TIMSK0; 932 | 933 | impl TIMSK0 { 934 | pub const OCIE0B: RegisterBits = RegisterBits::new(0x4); 935 | pub const OCIE0B0: RegisterBits = RegisterBits::new(1<<2); 936 | 937 | pub const OCIE0A: RegisterBits = RegisterBits::new(0x2); 938 | pub const OCIE0A0: RegisterBits = RegisterBits::new(1<<1); 939 | 940 | pub const TOIE0: RegisterBits = RegisterBits::new(0x1); 941 | pub const TOIE00: RegisterBits = RegisterBits::new(1<<0); 942 | 943 | } 944 | 945 | impl Register for TIMSK0 { 946 | type T = u8; 947 | const ADDRESS: *mut u8 = 0x6e as *mut u8; 948 | } 949 | #[allow(non_camel_case_types)] 950 | pub struct TIFR0; 951 | 952 | impl TIFR0 { 953 | pub const OCF0B: RegisterBits = RegisterBits::new(0x4); 954 | pub const OCF0B0: RegisterBits = RegisterBits::new(1<<2); 955 | 956 | pub const OCF0A: RegisterBits = RegisterBits::new(0x2); 957 | pub const OCF0A0: RegisterBits = RegisterBits::new(1<<1); 958 | 959 | pub const TOV0: RegisterBits = RegisterBits::new(0x1); 960 | pub const TOV00: RegisterBits = RegisterBits::new(1<<0); 961 | 962 | } 963 | 964 | impl Register for TIFR0 { 965 | type T = u8; 966 | const ADDRESS: *mut u8 = 0x35 as *mut u8; 967 | } 968 | #[allow(non_camel_case_types)] 969 | pub struct EICRA; 970 | 971 | impl EICRA { 972 | pub const ISC1: RegisterBits = RegisterBits::new(0xc); 973 | pub const ISC10: RegisterBits = RegisterBits::new(1<<2); 974 | pub const ISC11: RegisterBits = RegisterBits::new(1<<3); 975 | 976 | pub const ISC0: RegisterBits = RegisterBits::new(0x3); 977 | pub const ISC00: RegisterBits = RegisterBits::new(1<<0); 978 | pub const ISC01: RegisterBits = RegisterBits::new(1<<1); 979 | 980 | } 981 | 982 | impl Register for EICRA { 983 | type T = u8; 984 | const ADDRESS: *mut u8 = 0x69 as *mut u8; 985 | } 986 | #[allow(non_camel_case_types)] 987 | pub struct EIMSK; 988 | 989 | impl EIMSK { 990 | pub const INT: RegisterBits = RegisterBits::new(0x3); 991 | pub const INT0: RegisterBits = RegisterBits::new(1<<0); 992 | pub const INT1: RegisterBits = RegisterBits::new(1<<1); 993 | 994 | } 995 | 996 | impl Register for EIMSK { 997 | type T = u8; 998 | const ADDRESS: *mut u8 = 0x3d as *mut u8; 999 | } 1000 | #[allow(non_camel_case_types)] 1001 | pub struct EIFR; 1002 | 1003 | impl EIFR { 1004 | pub const INTF: RegisterBits = RegisterBits::new(0x3); 1005 | pub const INTF0: RegisterBits = RegisterBits::new(1<<0); 1006 | pub const INTF1: RegisterBits = RegisterBits::new(1<<1); 1007 | 1008 | } 1009 | 1010 | impl Register for EIFR { 1011 | type T = u8; 1012 | const ADDRESS: *mut u8 = 0x3c as *mut u8; 1013 | } 1014 | #[allow(non_camel_case_types)] 1015 | pub struct PCICR; 1016 | 1017 | impl PCICR { 1018 | pub const PCIE: RegisterBits = RegisterBits::new(0x7); 1019 | pub const PCIE0: RegisterBits = RegisterBits::new(1<<0); 1020 | pub const PCIE1: RegisterBits = RegisterBits::new(1<<1); 1021 | pub const PCIE2: RegisterBits = RegisterBits::new(1<<2); 1022 | 1023 | } 1024 | 1025 | impl Register for PCICR { 1026 | type T = u8; 1027 | const ADDRESS: *mut u8 = 0x68 as *mut u8; 1028 | } 1029 | #[allow(non_camel_case_types)] 1030 | pub struct PCMSK2; 1031 | 1032 | impl PCMSK2 { 1033 | pub const PCINT: RegisterBits = RegisterBits::new(0xff); 1034 | pub const PCINT0: RegisterBits = RegisterBits::new(1<<0); 1035 | pub const PCINT1: RegisterBits = RegisterBits::new(1<<1); 1036 | pub const PCINT2: RegisterBits = RegisterBits::new(1<<2); 1037 | pub const PCINT3: RegisterBits = RegisterBits::new(1<<3); 1038 | pub const PCINT4: RegisterBits = RegisterBits::new(1<<4); 1039 | pub const PCINT5: RegisterBits = RegisterBits::new(1<<5); 1040 | pub const PCINT6: RegisterBits = RegisterBits::new(1<<6); 1041 | pub const PCINT7: RegisterBits = RegisterBits::new(1<<7); 1042 | 1043 | } 1044 | 1045 | impl Register for PCMSK2 { 1046 | type T = u8; 1047 | const ADDRESS: *mut u8 = 0x6d as *mut u8; 1048 | } 1049 | #[allow(non_camel_case_types)] 1050 | pub struct PCMSK1; 1051 | 1052 | impl PCMSK1 { 1053 | pub const PCINT: RegisterBits = RegisterBits::new(0x7f); 1054 | pub const PCINT0: RegisterBits = RegisterBits::new(1<<0); 1055 | pub const PCINT1: RegisterBits = RegisterBits::new(1<<1); 1056 | pub const PCINT2: RegisterBits = RegisterBits::new(1<<2); 1057 | pub const PCINT3: RegisterBits = RegisterBits::new(1<<3); 1058 | pub const PCINT4: RegisterBits = RegisterBits::new(1<<4); 1059 | pub const PCINT5: RegisterBits = RegisterBits::new(1<<5); 1060 | pub const PCINT6: RegisterBits = RegisterBits::new(1<<6); 1061 | 1062 | } 1063 | 1064 | impl Register for PCMSK1 { 1065 | type T = u8; 1066 | const ADDRESS: *mut u8 = 0x6c as *mut u8; 1067 | } 1068 | #[allow(non_camel_case_types)] 1069 | pub struct PCMSK0; 1070 | 1071 | impl PCMSK0 { 1072 | pub const PCINT: RegisterBits = RegisterBits::new(0xff); 1073 | pub const PCINT0: RegisterBits = RegisterBits::new(1<<0); 1074 | pub const PCINT1: RegisterBits = RegisterBits::new(1<<1); 1075 | pub const PCINT2: RegisterBits = RegisterBits::new(1<<2); 1076 | pub const PCINT3: RegisterBits = RegisterBits::new(1<<3); 1077 | pub const PCINT4: RegisterBits = RegisterBits::new(1<<4); 1078 | pub const PCINT5: RegisterBits = RegisterBits::new(1<<5); 1079 | pub const PCINT6: RegisterBits = RegisterBits::new(1<<6); 1080 | pub const PCINT7: RegisterBits = RegisterBits::new(1<<7); 1081 | 1082 | } 1083 | 1084 | impl Register for PCMSK0 { 1085 | type T = u8; 1086 | const ADDRESS: *mut u8 = 0x6b as *mut u8; 1087 | } 1088 | #[allow(non_camel_case_types)] 1089 | pub struct PCIFR; 1090 | 1091 | impl PCIFR { 1092 | pub const PCIF: RegisterBits = RegisterBits::new(0x7); 1093 | pub const PCIF0: RegisterBits = RegisterBits::new(1<<0); 1094 | pub const PCIF1: RegisterBits = RegisterBits::new(1<<1); 1095 | pub const PCIF2: RegisterBits = RegisterBits::new(1<<2); 1096 | 1097 | } 1098 | 1099 | impl Register for PCIFR { 1100 | type T = u8; 1101 | const ADDRESS: *mut u8 = 0x3b as *mut u8; 1102 | } 1103 | #[allow(non_camel_case_types)] 1104 | pub struct SPDR; 1105 | 1106 | impl SPDR { 1107 | } 1108 | 1109 | impl Register for SPDR { 1110 | type T = u8; 1111 | const ADDRESS: *mut u8 = 0x4e as *mut u8; 1112 | } 1113 | #[allow(non_camel_case_types)] 1114 | pub struct SPSR; 1115 | 1116 | impl SPSR { 1117 | pub const SPIF: RegisterBits = RegisterBits::new(0x80); 1118 | pub const SPIF0: RegisterBits = RegisterBits::new(1<<7); 1119 | 1120 | pub const WCOL: RegisterBits = RegisterBits::new(0x40); 1121 | pub const WCOL0: RegisterBits = RegisterBits::new(1<<6); 1122 | 1123 | pub const SPI2X: RegisterBits = RegisterBits::new(0x1); 1124 | pub const SPI2X0: RegisterBits = RegisterBits::new(1<<0); 1125 | 1126 | } 1127 | 1128 | impl Register for SPSR { 1129 | type T = u8; 1130 | const ADDRESS: *mut u8 = 0x4d as *mut u8; 1131 | } 1132 | #[allow(non_camel_case_types)] 1133 | pub struct SPCR; 1134 | 1135 | impl SPCR { 1136 | pub const SPIE: RegisterBits = RegisterBits::new(0x80); 1137 | pub const SPIE0: RegisterBits = RegisterBits::new(1<<7); 1138 | 1139 | pub const SPE: RegisterBits = RegisterBits::new(0x40); 1140 | pub const SPE0: RegisterBits = RegisterBits::new(1<<6); 1141 | 1142 | pub const DORD: RegisterBits = RegisterBits::new(0x20); 1143 | pub const DORD0: RegisterBits = RegisterBits::new(1<<5); 1144 | 1145 | pub const MSTR: RegisterBits = RegisterBits::new(0x10); 1146 | pub const MSTR0: RegisterBits = RegisterBits::new(1<<4); 1147 | 1148 | pub const CPOL: RegisterBits = RegisterBits::new(0x8); 1149 | pub const CPOL0: RegisterBits = RegisterBits::new(1<<3); 1150 | 1151 | pub const CPHA: RegisterBits = RegisterBits::new(0x4); 1152 | pub const CPHA0: RegisterBits = RegisterBits::new(1<<2); 1153 | 1154 | pub const SPR: RegisterBits = RegisterBits::new(0x3); 1155 | pub const SPR0: RegisterBits = RegisterBits::new(1<<0); 1156 | pub const SPR1: RegisterBits = RegisterBits::new(1<<1); 1157 | 1158 | } 1159 | 1160 | impl Register for SPCR { 1161 | type T = u8; 1162 | const ADDRESS: *mut u8 = 0x4c as *mut u8; 1163 | } 1164 | #[allow(non_camel_case_types)] 1165 | pub struct WDTCSR; 1166 | 1167 | impl WDTCSR { 1168 | pub const WDIF: RegisterBits = RegisterBits::new(0x80); 1169 | pub const WDIF0: RegisterBits = RegisterBits::new(1<<7); 1170 | 1171 | pub const WDIE: RegisterBits = RegisterBits::new(0x40); 1172 | pub const WDIE0: RegisterBits = RegisterBits::new(1<<6); 1173 | 1174 | pub const WDP: RegisterBits = RegisterBits::new(0x27); 1175 | pub const WDP0: RegisterBits = RegisterBits::new(1<<0); 1176 | pub const WDP1: RegisterBits = RegisterBits::new(1<<1); 1177 | pub const WDP2: RegisterBits = RegisterBits::new(1<<2); 1178 | pub const WDP3: RegisterBits = RegisterBits::new(1<<5); 1179 | 1180 | pub const WDCE: RegisterBits = RegisterBits::new(0x10); 1181 | pub const WDCE0: RegisterBits = RegisterBits::new(1<<4); 1182 | 1183 | pub const WDE: RegisterBits = RegisterBits::new(0x8); 1184 | pub const WDE0: RegisterBits = RegisterBits::new(1<<3); 1185 | 1186 | } 1187 | 1188 | impl Register for WDTCSR { 1189 | type T = u8; 1190 | const ADDRESS: *mut u8 = 0x60 as *mut u8; 1191 | } 1192 | #[allow(non_camel_case_types)] 1193 | pub struct EEARL; 1194 | 1195 | impl EEARL { 1196 | } 1197 | 1198 | impl Register for EEARL { 1199 | type T = u8; 1200 | const ADDRESS: *mut u8 = 0x41 as *mut u8; 1201 | } 1202 | #[allow(non_camel_case_types)] 1203 | pub struct EEDR; 1204 | 1205 | impl EEDR { 1206 | } 1207 | 1208 | impl Register for EEDR { 1209 | type T = u8; 1210 | const ADDRESS: *mut u8 = 0x40 as *mut u8; 1211 | } 1212 | #[allow(non_camel_case_types)] 1213 | pub struct EECR; 1214 | 1215 | impl EECR { 1216 | pub const EEPM: RegisterBits = RegisterBits::new(0x30); 1217 | pub const EEPM0: RegisterBits = RegisterBits::new(1<<4); 1218 | pub const EEPM1: RegisterBits = RegisterBits::new(1<<5); 1219 | 1220 | pub const EERIE: RegisterBits = RegisterBits::new(0x8); 1221 | pub const EERIE0: RegisterBits = RegisterBits::new(1<<3); 1222 | 1223 | pub const EEMPE: RegisterBits = RegisterBits::new(0x4); 1224 | pub const EEMPE0: RegisterBits = RegisterBits::new(1<<2); 1225 | 1226 | pub const EEPE: RegisterBits = RegisterBits::new(0x2); 1227 | pub const EEPE0: RegisterBits = RegisterBits::new(1<<1); 1228 | 1229 | pub const EERE: RegisterBits = RegisterBits::new(0x1); 1230 | pub const EERE0: RegisterBits = RegisterBits::new(1<<0); 1231 | 1232 | } 1233 | 1234 | impl Register for EECR { 1235 | type T = u8; 1236 | const ADDRESS: *mut u8 = 0x3f as *mut u8; 1237 | } 1238 | #[allow(non_camel_case_types)] 1239 | pub struct PRR; 1240 | 1241 | impl PRR { 1242 | pub const PRTWI: RegisterBits = RegisterBits::new(0x80); 1243 | pub const PRTWI0: RegisterBits = RegisterBits::new(1<<7); 1244 | 1245 | pub const PRTIM2: RegisterBits = RegisterBits::new(0x40); 1246 | pub const PRTIM20: RegisterBits = RegisterBits::new(1<<6); 1247 | 1248 | pub const PRTIM0: RegisterBits = RegisterBits::new(0x20); 1249 | pub const PRTIM00: RegisterBits = RegisterBits::new(1<<5); 1250 | 1251 | pub const PRTIM1: RegisterBits = RegisterBits::new(0x8); 1252 | pub const PRTIM10: RegisterBits = RegisterBits::new(1<<3); 1253 | 1254 | pub const PRSPI: RegisterBits = RegisterBits::new(0x4); 1255 | pub const PRSPI0: RegisterBits = RegisterBits::new(1<<2); 1256 | 1257 | pub const PRUSART0: RegisterBits = RegisterBits::new(0x2); 1258 | pub const PRUSART00: RegisterBits = RegisterBits::new(1<<1); 1259 | 1260 | pub const PRADC: RegisterBits = RegisterBits::new(0x1); 1261 | pub const PRADC0: RegisterBits = RegisterBits::new(1<<0); 1262 | 1263 | } 1264 | 1265 | impl Register for PRR { 1266 | type T = u8; 1267 | const ADDRESS: *mut u8 = 0x64 as *mut u8; 1268 | } 1269 | #[allow(non_camel_case_types)] 1270 | pub struct OSCCAL; 1271 | 1272 | impl OSCCAL { 1273 | pub const OSCCAL: RegisterBits = RegisterBits::new(0xff); 1274 | pub const OSCCAL0: RegisterBits = RegisterBits::new(1<<0); 1275 | pub const OSCCAL1: RegisterBits = RegisterBits::new(1<<1); 1276 | pub const OSCCAL2: RegisterBits = RegisterBits::new(1<<2); 1277 | pub const OSCCAL3: RegisterBits = RegisterBits::new(1<<3); 1278 | pub const OSCCAL4: RegisterBits = RegisterBits::new(1<<4); 1279 | pub const OSCCAL5: RegisterBits = RegisterBits::new(1<<5); 1280 | pub const OSCCAL6: RegisterBits = RegisterBits::new(1<<6); 1281 | pub const OSCCAL7: RegisterBits = RegisterBits::new(1<<7); 1282 | 1283 | } 1284 | 1285 | impl Register for OSCCAL { 1286 | type T = u8; 1287 | const ADDRESS: *mut u8 = 0x66 as *mut u8; 1288 | } 1289 | #[allow(non_camel_case_types)] 1290 | pub struct CLKPR; 1291 | 1292 | impl CLKPR { 1293 | pub const CLKPCE: RegisterBits = RegisterBits::new(0x80); 1294 | pub const CLKPCE0: RegisterBits = RegisterBits::new(1<<7); 1295 | 1296 | pub const CLKPS: RegisterBits = RegisterBits::new(0xf); 1297 | pub const CLKPS0: RegisterBits = RegisterBits::new(1<<0); 1298 | pub const CLKPS1: RegisterBits = RegisterBits::new(1<<1); 1299 | pub const CLKPS2: RegisterBits = RegisterBits::new(1<<2); 1300 | pub const CLKPS3: RegisterBits = RegisterBits::new(1<<3); 1301 | 1302 | } 1303 | 1304 | impl Register for CLKPR { 1305 | type T = u8; 1306 | const ADDRESS: *mut u8 = 0x61 as *mut u8; 1307 | } 1308 | #[allow(non_camel_case_types)] 1309 | pub struct SREG; 1310 | 1311 | impl SREG { 1312 | pub const I: RegisterBits = RegisterBits::new(0x80); 1313 | pub const I0: RegisterBits = RegisterBits::new(1<<7); 1314 | 1315 | pub const T: RegisterBits = RegisterBits::new(0x40); 1316 | pub const T0: RegisterBits = RegisterBits::new(1<<6); 1317 | 1318 | pub const H: RegisterBits = RegisterBits::new(0x20); 1319 | pub const H0: RegisterBits = RegisterBits::new(1<<5); 1320 | 1321 | pub const S: RegisterBits = RegisterBits::new(0x10); 1322 | pub const S0: RegisterBits = RegisterBits::new(1<<4); 1323 | 1324 | pub const V: RegisterBits = RegisterBits::new(0x8); 1325 | pub const V0: RegisterBits = RegisterBits::new(1<<3); 1326 | 1327 | pub const N: RegisterBits = RegisterBits::new(0x4); 1328 | pub const N0: RegisterBits = RegisterBits::new(1<<2); 1329 | 1330 | pub const Z: RegisterBits = RegisterBits::new(0x2); 1331 | pub const Z0: RegisterBits = RegisterBits::new(1<<1); 1332 | 1333 | pub const C: RegisterBits = RegisterBits::new(0x1); 1334 | pub const C0: RegisterBits = RegisterBits::new(1<<0); 1335 | 1336 | } 1337 | 1338 | impl Register for SREG { 1339 | type T = u8; 1340 | const ADDRESS: *mut u8 = 0x5f as *mut u8; 1341 | } 1342 | #[allow(non_camel_case_types)] 1343 | pub struct SP; 1344 | 1345 | impl SP { 1346 | } 1347 | 1348 | impl Register for SP { 1349 | type T = u16; 1350 | const ADDRESS: *mut u16 = 0x5d as *mut u16; 1351 | } 1352 | #[allow(non_camel_case_types)] 1353 | pub struct SPMCSR; 1354 | 1355 | impl SPMCSR { 1356 | pub const SPMIE: RegisterBits = RegisterBits::new(0x80); 1357 | pub const SPMIE0: RegisterBits = RegisterBits::new(1<<7); 1358 | 1359 | pub const RWWSB: RegisterBits = RegisterBits::new(0x40); 1360 | pub const RWWSB0: RegisterBits = RegisterBits::new(1<<6); 1361 | 1362 | pub const RWWSRE: RegisterBits = RegisterBits::new(0x10); 1363 | pub const RWWSRE0: RegisterBits = RegisterBits::new(1<<4); 1364 | 1365 | pub const BLBSET: RegisterBits = RegisterBits::new(0x8); 1366 | pub const BLBSET0: RegisterBits = RegisterBits::new(1<<3); 1367 | 1368 | pub const PGWRT: RegisterBits = RegisterBits::new(0x4); 1369 | pub const PGWRT0: RegisterBits = RegisterBits::new(1<<2); 1370 | 1371 | pub const PGERS: RegisterBits = RegisterBits::new(0x2); 1372 | pub const PGERS0: RegisterBits = RegisterBits::new(1<<1); 1373 | 1374 | pub const SELFPRGEN: RegisterBits = RegisterBits::new(0x1); 1375 | pub const SELFPRGEN0: RegisterBits = RegisterBits::new(1<<0); 1376 | 1377 | } 1378 | 1379 | impl Register for SPMCSR { 1380 | type T = u8; 1381 | const ADDRESS: *mut u8 = 0x57 as *mut u8; 1382 | } 1383 | #[allow(non_camel_case_types)] 1384 | pub struct MCUCR; 1385 | 1386 | impl MCUCR { 1387 | pub const BODS: RegisterBits = RegisterBits::new(0x40); 1388 | pub const BODS0: RegisterBits = RegisterBits::new(1<<6); 1389 | 1390 | pub const BODSE: RegisterBits = RegisterBits::new(0x20); 1391 | pub const BODSE0: RegisterBits = RegisterBits::new(1<<5); 1392 | 1393 | pub const PUD: RegisterBits = RegisterBits::new(0x10); 1394 | pub const PUD0: RegisterBits = RegisterBits::new(1<<4); 1395 | 1396 | } 1397 | 1398 | impl Register for MCUCR { 1399 | type T = u8; 1400 | const ADDRESS: *mut u8 = 0x55 as *mut u8; 1401 | } 1402 | #[allow(non_camel_case_types)] 1403 | pub struct MCUSR; 1404 | 1405 | impl MCUSR { 1406 | pub const WDRF: RegisterBits = RegisterBits::new(0x8); 1407 | pub const WDRF0: RegisterBits = RegisterBits::new(1<<3); 1408 | 1409 | pub const BORF: RegisterBits = RegisterBits::new(0x4); 1410 | pub const BORF0: RegisterBits = RegisterBits::new(1<<2); 1411 | 1412 | pub const EXTRF: RegisterBits = RegisterBits::new(0x2); 1413 | pub const EXTRF0: RegisterBits = RegisterBits::new(1<<1); 1414 | 1415 | pub const PORF: RegisterBits = RegisterBits::new(0x1); 1416 | pub const PORF0: RegisterBits = RegisterBits::new(1<<0); 1417 | 1418 | } 1419 | 1420 | impl Register for MCUSR { 1421 | type T = u8; 1422 | const ADDRESS: *mut u8 = 0x54 as *mut u8; 1423 | } 1424 | #[allow(non_camel_case_types)] 1425 | pub struct SMCR; 1426 | 1427 | impl SMCR { 1428 | pub const SM: RegisterBits = RegisterBits::new(0xe); 1429 | pub const SM0: RegisterBits = RegisterBits::new(1<<1); 1430 | pub const SM1: RegisterBits = RegisterBits::new(1<<2); 1431 | pub const SM2: RegisterBits = RegisterBits::new(1<<3); 1432 | 1433 | pub const SE: RegisterBits = RegisterBits::new(0x1); 1434 | pub const SE0: RegisterBits = RegisterBits::new(1<<0); 1435 | 1436 | } 1437 | 1438 | impl Register for SMCR { 1439 | type T = u8; 1440 | const ADDRESS: *mut u8 = 0x53 as *mut u8; 1441 | } 1442 | #[allow(non_camel_case_types)] 1443 | pub struct GPIOR2; 1444 | 1445 | impl GPIOR2 { 1446 | } 1447 | 1448 | impl Register for GPIOR2 { 1449 | type T = u8; 1450 | const ADDRESS: *mut u8 = 0x4b as *mut u8; 1451 | } 1452 | #[allow(non_camel_case_types)] 1453 | pub struct GPIOR1; 1454 | 1455 | impl GPIOR1 { 1456 | } 1457 | 1458 | impl Register for GPIOR1 { 1459 | type T = u8; 1460 | const ADDRESS: *mut u8 = 0x4a as *mut u8; 1461 | } 1462 | #[allow(non_camel_case_types)] 1463 | pub struct GPIOR0; 1464 | 1465 | impl GPIOR0 { 1466 | } 1467 | 1468 | impl Register for GPIOR0 { 1469 | type T = u8; 1470 | const ADDRESS: *mut u8 = 0x3e as *mut u8; 1471 | } 1472 | pub mod port { 1473 | #![allow(unused_imports)] 1474 | 1475 | use super::*; 1476 | use crate::Pin; 1477 | 1478 | pub struct B0; 1479 | 1480 | impl Pin for B0 { 1481 | /// Port B Data Register. 1482 | type PORT = PORTB; 1483 | /// Port B Data Direction Register. 1484 | type DDR = DDRB; 1485 | /// Port B Input Pins. 1486 | type PIN = PINB; 1487 | /// PB0 1488 | const MASK: u8 = 1<<0; 1489 | } 1490 | 1491 | pub struct B1; 1492 | 1493 | impl Pin for B1 { 1494 | /// Port B Data Register. 1495 | type PORT = PORTB; 1496 | /// Port B Data Direction Register. 1497 | type DDR = DDRB; 1498 | /// Port B Input Pins. 1499 | type PIN = PINB; 1500 | /// PB1 1501 | const MASK: u8 = 1<<1; 1502 | } 1503 | 1504 | pub struct B2; 1505 | 1506 | impl Pin for B2 { 1507 | /// Port B Data Register. 1508 | type PORT = PORTB; 1509 | /// Port B Data Direction Register. 1510 | type DDR = DDRB; 1511 | /// Port B Input Pins. 1512 | type PIN = PINB; 1513 | /// PB2 1514 | const MASK: u8 = 1<<2; 1515 | } 1516 | 1517 | pub struct B3; 1518 | 1519 | impl Pin for B3 { 1520 | /// Port B Data Register. 1521 | type PORT = PORTB; 1522 | /// Port B Data Direction Register. 1523 | type DDR = DDRB; 1524 | /// Port B Input Pins. 1525 | type PIN = PINB; 1526 | /// PB3 1527 | const MASK: u8 = 1<<3; 1528 | } 1529 | 1530 | pub struct B4; 1531 | 1532 | impl Pin for B4 { 1533 | /// Port B Data Register. 1534 | type PORT = PORTB; 1535 | /// Port B Data Direction Register. 1536 | type DDR = DDRB; 1537 | /// Port B Input Pins. 1538 | type PIN = PINB; 1539 | /// PB4 1540 | const MASK: u8 = 1<<4; 1541 | } 1542 | 1543 | pub struct B5; 1544 | 1545 | impl Pin for B5 { 1546 | /// Port B Data Register. 1547 | type PORT = PORTB; 1548 | /// Port B Data Direction Register. 1549 | type DDR = DDRB; 1550 | /// Port B Input Pins. 1551 | type PIN = PINB; 1552 | /// PB5 1553 | const MASK: u8 = 1<<5; 1554 | } 1555 | 1556 | pub struct B6; 1557 | 1558 | impl Pin for B6 { 1559 | /// Port B Data Register. 1560 | type PORT = PORTB; 1561 | /// Port B Data Direction Register. 1562 | type DDR = DDRB; 1563 | /// Port B Input Pins. 1564 | type PIN = PINB; 1565 | /// PB6 1566 | const MASK: u8 = 1<<6; 1567 | } 1568 | 1569 | pub struct B7; 1570 | 1571 | impl Pin for B7 { 1572 | /// Port B Data Register. 1573 | type PORT = PORTB; 1574 | /// Port B Data Direction Register. 1575 | type DDR = DDRB; 1576 | /// Port B Input Pins. 1577 | type PIN = PINB; 1578 | /// PB7 1579 | const MASK: u8 = 1<<7; 1580 | } 1581 | 1582 | pub struct C0; 1583 | 1584 | impl Pin for C0 { 1585 | /// Port C Data Register. 1586 | type PORT = PORTC; 1587 | /// Port C Data Direction Register. 1588 | type DDR = DDRC; 1589 | /// Port C Input Pins. 1590 | type PIN = PINC; 1591 | /// PC0 1592 | const MASK: u8 = 1<<0; 1593 | } 1594 | 1595 | pub struct C1; 1596 | 1597 | impl Pin for C1 { 1598 | /// Port C Data Register. 1599 | type PORT = PORTC; 1600 | /// Port C Data Direction Register. 1601 | type DDR = DDRC; 1602 | /// Port C Input Pins. 1603 | type PIN = PINC; 1604 | /// PC1 1605 | const MASK: u8 = 1<<1; 1606 | } 1607 | 1608 | pub struct C2; 1609 | 1610 | impl Pin for C2 { 1611 | /// Port C Data Register. 1612 | type PORT = PORTC; 1613 | /// Port C Data Direction Register. 1614 | type DDR = DDRC; 1615 | /// Port C Input Pins. 1616 | type PIN = PINC; 1617 | /// PC2 1618 | const MASK: u8 = 1<<2; 1619 | } 1620 | 1621 | pub struct C3; 1622 | 1623 | impl Pin for C3 { 1624 | /// Port C Data Register. 1625 | type PORT = PORTC; 1626 | /// Port C Data Direction Register. 1627 | type DDR = DDRC; 1628 | /// Port C Input Pins. 1629 | type PIN = PINC; 1630 | /// PC3 1631 | const MASK: u8 = 1<<3; 1632 | } 1633 | 1634 | pub struct C4; 1635 | 1636 | impl Pin for C4 { 1637 | /// Port C Data Register. 1638 | type PORT = PORTC; 1639 | /// Port C Data Direction Register. 1640 | type DDR = DDRC; 1641 | /// Port C Input Pins. 1642 | type PIN = PINC; 1643 | /// PC4 1644 | const MASK: u8 = 1<<4; 1645 | } 1646 | 1647 | pub struct C5; 1648 | 1649 | impl Pin for C5 { 1650 | /// Port C Data Register. 1651 | type PORT = PORTC; 1652 | /// Port C Data Direction Register. 1653 | type DDR = DDRC; 1654 | /// Port C Input Pins. 1655 | type PIN = PINC; 1656 | /// PC5 1657 | const MASK: u8 = 1<<5; 1658 | } 1659 | 1660 | pub struct C6; 1661 | 1662 | impl Pin for C6 { 1663 | /// Port C Data Register. 1664 | type PORT = PORTC; 1665 | /// Port C Data Direction Register. 1666 | type DDR = DDRC; 1667 | /// Port C Input Pins. 1668 | type PIN = PINC; 1669 | /// PC6 1670 | const MASK: u8 = 1<<6; 1671 | } 1672 | 1673 | pub struct D0; 1674 | 1675 | impl Pin for D0 { 1676 | /// Port D Data Register. 1677 | type PORT = PORTD; 1678 | /// Port D Data Direction Register. 1679 | type DDR = DDRD; 1680 | /// Port D Input Pins. 1681 | type PIN = PIND; 1682 | /// PD0 1683 | const MASK: u8 = 1<<0; 1684 | } 1685 | 1686 | pub struct D1; 1687 | 1688 | impl Pin for D1 { 1689 | /// Port D Data Register. 1690 | type PORT = PORTD; 1691 | /// Port D Data Direction Register. 1692 | type DDR = DDRD; 1693 | /// Port D Input Pins. 1694 | type PIN = PIND; 1695 | /// PD1 1696 | const MASK: u8 = 1<<1; 1697 | } 1698 | 1699 | pub struct D2; 1700 | 1701 | impl Pin for D2 { 1702 | /// Port D Data Register. 1703 | type PORT = PORTD; 1704 | /// Port D Data Direction Register. 1705 | type DDR = DDRD; 1706 | /// Port D Input Pins. 1707 | type PIN = PIND; 1708 | /// PD2 1709 | const MASK: u8 = 1<<2; 1710 | } 1711 | 1712 | pub struct D3; 1713 | 1714 | impl Pin for D3 { 1715 | /// Port D Data Register. 1716 | type PORT = PORTD; 1717 | /// Port D Data Direction Register. 1718 | type DDR = DDRD; 1719 | /// Port D Input Pins. 1720 | type PIN = PIND; 1721 | /// PD3 1722 | const MASK: u8 = 1<<3; 1723 | } 1724 | 1725 | pub struct D4; 1726 | 1727 | impl Pin for D4 { 1728 | /// Port D Data Register. 1729 | type PORT = PORTD; 1730 | /// Port D Data Direction Register. 1731 | type DDR = DDRD; 1732 | /// Port D Input Pins. 1733 | type PIN = PIND; 1734 | /// PD4 1735 | const MASK: u8 = 1<<4; 1736 | } 1737 | 1738 | pub struct D5; 1739 | 1740 | impl Pin for D5 { 1741 | /// Port D Data Register. 1742 | type PORT = PORTD; 1743 | /// Port D Data Direction Register. 1744 | type DDR = DDRD; 1745 | /// Port D Input Pins. 1746 | type PIN = PIND; 1747 | /// PD5 1748 | const MASK: u8 = 1<<5; 1749 | } 1750 | 1751 | pub struct D6; 1752 | 1753 | impl Pin for D6 { 1754 | /// Port D Data Register. 1755 | type PORT = PORTD; 1756 | /// Port D Data Direction Register. 1757 | type DDR = DDRD; 1758 | /// Port D Input Pins. 1759 | type PIN = PIND; 1760 | /// PD6 1761 | const MASK: u8 = 1<<6; 1762 | } 1763 | 1764 | pub struct D7; 1765 | 1766 | impl Pin for D7 { 1767 | /// Port D Data Register. 1768 | type PORT = PORTD; 1769 | /// Port D Data Direction Register. 1770 | type DDR = DDRD; 1771 | /// Port D Input Pins. 1772 | type PIN = PIND; 1773 | /// PD7 1774 | const MASK: u8 = 1<<7; 1775 | } 1776 | 1777 | } 1778 | 1779 | pub struct Spi; 1780 | 1781 | impl modules::HardwareSpi for Spi { 1782 | type SlaveSelect = port::B2; 1783 | type MasterOutSlaveIn = port::B3; 1784 | type MasterInSlaveOut = port::B4; 1785 | type Clock = port::B5; 1786 | type DataRegister = SPDR; 1787 | type StatusRegister = SPSR; 1788 | type ControlRegister = SPCR; 1789 | } 1790 | 1791 | /// The USART0 module. 1792 | pub struct USART0; 1793 | 1794 | impl modules::HardwareUsart for USART0 { 1795 | type DataRegister = UDR0; 1796 | type ControlRegisterA = UCSR0A; 1797 | type ControlRegisterB = UCSR0B; 1798 | type ControlRegisterC = UCSR0C; 1799 | type BaudRateRegister = UBRR0; 1800 | } 1801 | 1802 | /// 8-bit timer. 1803 | pub struct Timer8; 1804 | 1805 | impl modules::Timer8 for Timer8 { 1806 | type CompareA = OCR0A; 1807 | type CompareB = OCR0B; 1808 | type Counter = TCNT0; 1809 | type ControlA = TCCR0A; 1810 | type ControlB = TCCR0B; 1811 | type InterruptMask = TIMSK0; 1812 | type InterruptFlag = TIFR0; 1813 | const CS0: RegisterBits = Self::ControlB::CS00; 1814 | const CS1: RegisterBits = Self::ControlB::CS01; 1815 | const CS2: RegisterBits = Self::ControlB::CS02; 1816 | const WGM0: RegisterBits = Self::ControlA::WGM00; 1817 | const WGM1: RegisterBits = Self::ControlA::WGM01; 1818 | const WGM2: RegisterBits = Self::ControlB::WGM020; 1819 | const OCIEA: RegisterBits = Self::InterruptMask::OCIE0A; 1820 | } 1821 | /// 16-bit timer. 1822 | pub struct Timer16; 1823 | 1824 | impl modules::Timer16 for Timer16 { 1825 | type CompareA = OCR1A; 1826 | type CompareB = OCR1B; 1827 | type Counter = TCNT1; 1828 | type ControlA = TCCR1A; 1829 | type ControlB = TCCR1B; 1830 | type ControlC = TCCR1C; 1831 | type InterruptMask = TIMSK1; 1832 | type InterruptFlag = TIFR1; 1833 | const CS0: RegisterBits = Self::ControlB::CS10; 1834 | const CS1: RegisterBits = Self::ControlB::CS11; 1835 | const CS2: RegisterBits = Self::ControlB::CS12; 1836 | const WGM0: RegisterBits = Self::ControlA::WGM10; 1837 | const WGM1: RegisterBits = Self::ControlA::WGM11; 1838 | const WGM2: RegisterBits = Self::ControlB::WGM10; 1839 | const WGM3: RegisterBits = Self::ControlB::WGM11; 1840 | const OCIEA: RegisterBits = Self::InterruptMask::OCIE1A; 1841 | } 1842 | 1843 | -------------------------------------------------------------------------------- /src/cores/mod.rs: -------------------------------------------------------------------------------- 1 | //! The primary module containing microcontroller-specific core definitions 2 | 3 | /// The ATmega88. 4 | #[cfg(any(avr_mcu_atmega88, feature = "all-mcus"))] pub mod atmega88; 5 | #[cfg(avr_mcu_atmega88)] pub use self::atmega88 as current; 6 | 7 | /// The ATmega48A. 8 | #[cfg(any(avr_mcu_atmega48a, feature = "all-mcus"))] pub mod atmega48a; 9 | #[cfg(avr_mcu_atmega48a)] pub use self::atmega48a as current; 10 | 11 | /// The ATmega168A. 12 | #[cfg(any(avr_mcu_atmega168a, feature = "all-mcus"))] pub mod atmega168a; 13 | #[cfg(avr_mcu_atmega168a)] pub use self::atmega168a as current; 14 | 15 | /// The ATmega88P. 16 | #[cfg(any(avr_mcu_atmega88p, feature = "all-mcus"))] pub mod atmega88p; 17 | #[cfg(avr_mcu_atmega88p)] pub use self::atmega88p as current; 18 | 19 | /// The ATmega168P. 20 | #[cfg(any(avr_mcu_atmega168p, feature = "all-mcus"))] pub mod atmega168p; 21 | #[cfg(avr_mcu_atmega168p)] pub use self::atmega168p as current; 22 | 23 | /// The ATmega88PA. 24 | #[cfg(any(avr_mcu_atmega88pa, feature = "all-mcus"))] pub mod atmega88pa; 25 | #[cfg(avr_mcu_atmega88pa)] pub use self::atmega88pa as current; 26 | 27 | /// The ATmega168. 28 | #[cfg(any(avr_mcu_atmega168, feature = "all-mcus"))] pub mod atmega168; 29 | #[cfg(avr_mcu_atmega168)] pub use self::atmega168 as current; 30 | 31 | /// The ATmega328P. 32 | #[cfg(any(avr_mcu_atmega328p, feature = "all-mcus"))] pub mod atmega328p; 33 | #[cfg(avr_mcu_atmega328p)] pub use self::atmega328p as current; 34 | 35 | /// The ATmega48PA. 36 | #[cfg(any(avr_mcu_atmega48pa, feature = "all-mcus"))] pub mod atmega48pa; 37 | #[cfg(avr_mcu_atmega48pa)] pub use self::atmega48pa as current; 38 | 39 | /// The ATmega168PA. 40 | #[cfg(any(avr_mcu_atmega168pa, feature = "all-mcus"))] pub mod atmega168pa; 41 | #[cfg(avr_mcu_atmega168pa)] pub use self::atmega168pa as current; 42 | 43 | /// The ATmega48P. 44 | #[cfg(any(avr_mcu_atmega48p, feature = "all-mcus"))] pub mod atmega48p; 45 | #[cfg(avr_mcu_atmega48p)] pub use self::atmega48p as current; 46 | 47 | /// The ATmega328. 48 | /// 49 | /// This device is chosen as the default when the crate is targeting non-AVR devices. 50 | #[cfg(any(avr_mcu_atmega328, feature = "all-mcus", not(target_arch = "avr")))] pub mod atmega328; 51 | #[cfg(any(avr_mcu_atmega328, not(target_arch = "avr")))] pub use self::atmega328 as current; 52 | 53 | /// The ATmega88A. 54 | #[cfg(any(avr_mcu_atmega88a, feature = "all-mcus"))] pub mod atmega88a; 55 | #[cfg(avr_mcu_atmega88a)] pub use self::atmega88a as current; 56 | 57 | /// The ATmega48. 58 | #[cfg(any(avr_mcu_atmega48, feature = "all-mcus"))] pub mod atmega48; 59 | #[cfg(avr_mcu_atmega48)] pub use self::atmega48 as current; 60 | 61 | 62 | -------------------------------------------------------------------------------- /src/interrupt.rs: -------------------------------------------------------------------------------- 1 | //! Routines for managing interrupts. 2 | 3 | use core::arch::asm; 4 | use core::prelude::v1::*; 5 | use core::marker::PhantomData; 6 | 7 | /// Helper struct that automatically restores interrupts 8 | /// on drop. 9 | struct DisableInterrupts(PhantomData<()>); 10 | 11 | /// Executes a closure, disabling interrupts until its completion. 12 | /// 13 | /// Restores interrupts after the closure has completed 14 | /// execution. 15 | #[inline(always)] 16 | pub fn without_interrupts(f: F) -> T 17 | where F: FnOnce() -> T 18 | { 19 | let _disabled = DisableInterrupts::new(); 20 | f() 21 | } 22 | 23 | impl DisableInterrupts { 24 | #[inline(always)] 25 | pub fn new() -> DisableInterrupts { 26 | unsafe { asm!("CLI") } 27 | DisableInterrupts(PhantomData) 28 | } 29 | } 30 | 31 | impl Drop for DisableInterrupts { 32 | #[inline(always)] 33 | fn drop(&mut self) { 34 | unsafe { asm!("SEI") } 35 | } 36 | } 37 | 38 | -------------------------------------------------------------------------------- /src/legacy/mod.rs: -------------------------------------------------------------------------------- 1 | //! Legacy code. 2 | //! 3 | //! The code in here needs to be cleaned up and rewritten to use 4 | //! the new core-based API. 5 | //! 6 | //! Once a replacement exists, these legacy modules may be removed 7 | //! in a major release! 8 | 9 | pub mod serial; 10 | 11 | -------------------------------------------------------------------------------- /src/legacy/serial.rs: -------------------------------------------------------------------------------- 1 | //! A serial. 2 | //! 3 | //! *WARNING* The current implementation of this will only work on ATmega328. 4 | 5 | use core::prelude::v1::*; 6 | use core::ptr::{read_volatile, write_volatile}; 7 | 8 | pub enum CharacterSize { 9 | FiveBits, 10 | SixBits, 11 | SevenBits, 12 | EightBits, 13 | NineBits, 14 | } 15 | 16 | impl CharacterSize { 17 | /// Returns bits for UCSR0B, UCSR0C 18 | #[inline] 19 | fn bits(&self) -> (u8, u8) { 20 | use self::CharacterSize::*; 21 | 22 | match *self { 23 | FiveBits => (0 , 0 | 0 ), 24 | SixBits => (0 , 0 | UCSZ00), 25 | SevenBits => (0 , UCSZ01 | 0 ), 26 | EightBits => (0 , UCSZ01 | UCSZ00), 27 | // Reserved => (UCSZ02, 0 | 0 ), 28 | // Reserved => (UCSZ02, 0 | UCSZ00), 29 | // Reserved => (UCSZ02, UCSZ01 | 0 ), 30 | NineBits => (UCSZ02, UCSZ01 | UCSZ00), 31 | } 32 | } 33 | 34 | #[inline] 35 | fn mask() -> (u8, u8) { 36 | (!(UCSZ01 | UCSZ00), !(UCSZ02)) 37 | } 38 | } 39 | 40 | pub enum Mode { 41 | Asynchronous, 42 | Synchronous, 43 | MasterSpi, 44 | } 45 | 46 | impl Mode { 47 | #[inline] 48 | fn bits(&self) -> u8 { 49 | use self::Mode::*; 50 | 51 | match *self { 52 | Asynchronous => 0 | 0, 53 | Synchronous => 0 | UMSEL00, 54 | // Reserved => UMSEL01 | 0, 55 | MasterSpi => UMSEL01 | UMSEL00, 56 | } 57 | } 58 | 59 | #[inline] 60 | fn mask() -> u8 { 61 | !(UMSEL01 | UMSEL00) 62 | } 63 | } 64 | 65 | pub enum Parity { 66 | Disabled, 67 | Even, 68 | Odd, 69 | } 70 | 71 | impl Parity { 72 | #[inline] 73 | fn bits(&self) -> u8 { 74 | use self::Parity::*; 75 | 76 | match *self { 77 | Disabled => 0 | 0, 78 | // Reserved => 0 | UPM00, 79 | Even => UPM01 | 0, 80 | Odd => UPM01 | UPM00, 81 | } 82 | } 83 | 84 | #[inline] 85 | fn mask() -> u8 { 86 | !(UPM01 | UPM00) 87 | } 88 | } 89 | 90 | pub enum StopBits { 91 | OneBit, 92 | TwoBits, 93 | } 94 | 95 | impl StopBits { 96 | #[inline] 97 | fn bits(&self) -> u8 { 98 | use self::StopBits::*; 99 | 100 | match *self { 101 | OneBit => 0, 102 | TwoBits => USBS0, 103 | } 104 | } 105 | 106 | #[inline] 107 | fn mask() -> u8 { 108 | !USBS0 109 | } 110 | } 111 | 112 | /// A serial connection. 113 | /// *WARNING* The current implementation of this will only work on ATmega328. 114 | pub struct Serial { 115 | ubrr: u16, 116 | a: u8, 117 | b: u8, 118 | c: u8, 119 | } 120 | 121 | impl Serial { 122 | #[inline] 123 | pub fn new(ubrr: u16) -> Self { 124 | Serial { 125 | ubrr: ubrr, 126 | a: 0, 127 | b: 0, 128 | c: 0, 129 | } 130 | } 131 | 132 | #[inline] 133 | pub fn character_size(mut self, character_size: CharacterSize) -> Self { 134 | let (b, c) = CharacterSize::mask(); 135 | self.b &= b; 136 | self.c &= c; 137 | 138 | let (b, c) = character_size.bits(); 139 | self.b |= b; 140 | self.c |= c; 141 | 142 | self 143 | } 144 | 145 | #[inline] 146 | pub fn mode(mut self, mode: Mode) -> Self { 147 | self.c &= Mode::mask(); 148 | self.c |= mode.bits(); 149 | self 150 | } 151 | 152 | #[inline] 153 | pub fn parity(mut self, parity: Parity) -> Self { 154 | self.c &= Parity::mask(); 155 | self.c |= parity.bits(); 156 | self 157 | } 158 | 159 | #[inline] 160 | pub fn stop_bits(mut self, stop_bits: StopBits) -> Self { 161 | self.c &= StopBits::mask(); 162 | self.c |= stop_bits.bits(); 163 | self 164 | } 165 | 166 | #[inline] 167 | pub fn configure(self) { 168 | unsafe { 169 | // Set Baud rate 170 | write_volatile(UBRR0, self.ubrr); 171 | 172 | write_volatile(UCSR0A, self.a); 173 | write_volatile(UCSR0B, self.b | RXEN0 | TXEN0); 174 | write_volatile(UCSR0C, self.c); 175 | } 176 | } 177 | } 178 | 179 | #[inline] 180 | pub fn ready_to_transmit() -> bool { 181 | unsafe { (read_volatile(UCSR0A) & UDRE0) != 0 } 182 | } 183 | 184 | #[inline] 185 | fn do_write(byte: u8) { 186 | unsafe { write_volatile(UDR0, byte); } 187 | } 188 | 189 | /// Does a blocking transfer of one byte 190 | #[inline] 191 | pub fn transmit(byte: u8) { 192 | while !ready_to_transmit() {} 193 | do_write(byte); 194 | } 195 | 196 | #[inline] 197 | pub fn try_transmit(byte: u8) -> Result<(), ()> { 198 | if ready_to_transmit() { 199 | do_write(byte); 200 | Ok(()) 201 | } else { 202 | Err(()) 203 | } 204 | } 205 | 206 | #[inline] 207 | pub fn ready_to_receive() -> bool { 208 | unsafe { (read_volatile(UCSR0A) & RXC0) != 0 } 209 | } 210 | 211 | #[inline] 212 | fn do_read() -> u8 { 213 | unsafe { read_volatile(UDR0) } 214 | } 215 | 216 | /// Does a blocking read of one byte 217 | #[inline] 218 | pub fn receive() -> u8 { 219 | while !ready_to_receive() {} 220 | do_read() 221 | } 222 | 223 | #[inline] 224 | pub fn try_receive() -> Option { 225 | if ready_to_receive() { 226 | Some(do_read()) 227 | } else { 228 | None 229 | } 230 | } 231 | 232 | // Dirty hack. 233 | // We should write this out and use the neat build-script method instead. 234 | use self::hack::*; 235 | mod hack { 236 | macro_rules! bit { 237 | (-, $pos:expr) => {}; 238 | ($name:ident, $pos:expr) => { 239 | pub const $name: u8 = 1 << $pos; 240 | }; 241 | } 242 | 243 | macro_rules! register { 244 | ($address:expr, $name:ident, [$b7:tt, $b6:tt, $b5:tt, $b4:tt, $b3:tt, $b2:tt, $b1:tt, $b0:tt]) => { 245 | register!($address, $name); 246 | bit!($b7, 7); 247 | bit!($b6, 6); 248 | bit!($b5, 5); 249 | bit!($b4, 4); 250 | bit!($b3, 3); 251 | bit!($b2, 2); 252 | bit!($b1, 1); 253 | bit!($b0, 0); 254 | }; 255 | ($address:expr, $name:ident) => { 256 | pub const $name: *mut u8 = $address as *mut u8; 257 | }; 258 | } 259 | 260 | register!(0xC6, UDR0); 261 | register!(0xC4, UBRR0L); 262 | register!(0xC2, UCSR0C, [UMSEL01, UMSEL00, UPM01, UPM00, USBS0, UCSZ01, UCSZ00, - ]); 263 | register!(0xC1, UCSR0B, [-, -, -, RXEN0, TXEN0, UCSZ02, -, - ]); 264 | register!(0xC0, UCSR0A, [RXC0, -, UDRE0, -, -, -, -, - ]); 265 | 266 | // 16-bit register pairs 267 | pub const UBRR0: *mut u16 = UBRR0L as *mut u16; 268 | } 269 | -------------------------------------------------------------------------------- /src/lib.rs: -------------------------------------------------------------------------------- 1 | //! Definitions of register addresses and bits within those registers 2 | 3 | #![feature(asm_experimental_arch)] 4 | #![feature(associated_type_defaults)] 5 | #![feature(lang_items)] 6 | #![feature(proc_macro_hygiene)] 7 | 8 | #![no_std] 9 | 10 | #[cfg(feature = "avr-std-stub")] extern crate avr_std_stub; 11 | 12 | extern crate const_env__value as const_env; 13 | 14 | pub use self::register::{Register, RegisterBits, RegisterValue}; 15 | pub use self::pin::{DataDirection, Pin}; 16 | 17 | pub mod prelude; 18 | pub mod legacy; 19 | /// Low level register-based API for device-specific operations. 20 | pub mod cores; 21 | pub mod interrupt; 22 | pub mod modules; 23 | 24 | /// Configuration for the currently-targeted microcontroller. 25 | pub use avr_config as config; 26 | 27 | /// Delay routines. 28 | pub use avr_delay as delay; 29 | 30 | mod register; 31 | mod pin; 32 | 33 | -------------------------------------------------------------------------------- /src/modules/mod.rs: -------------------------------------------------------------------------------- 1 | //! Modules that can be implemented for specific cores. 2 | 3 | pub use self::spi::HardwareSpi; 4 | pub use self::timer::{ 5 | Timer8, Timer8Setup, ClockSource8, WaveformGenerationMode8, 6 | Timer16, Timer16Setup, ClockSource16, WaveformGenerationMode16, 7 | }; 8 | pub use self::usart::HardwareUsart; 9 | 10 | mod spi; 11 | mod timer; 12 | mod usart; 13 | 14 | -------------------------------------------------------------------------------- /src/modules/spi/clock.rs: -------------------------------------------------------------------------------- 1 | use crate::config; 2 | 3 | /// A clock mask. 4 | /// 5 | /// The format looks like this 6 | /// 7 | /// ``` 8 | /// 0b00000<1><0><2x> 9 | /// ``` 10 | /// 11 | /// Where 12 | /// 13 | /// * `1` is the value of the `SPR1` bit 14 | /// * `0` is the value of the `SPR0` bit 15 | /// * `2x` indicates if double speed mode is enabled 16 | #[derive(Copy, Clone)] 17 | pub struct ClockMask(pub u8); 18 | 19 | impl ClockMask { 20 | /// Gets the clock mask for a specific baute rate. 21 | pub fn with_clock(spi_clock: u32) -> ClockMask { 22 | let mut divider_bits = if spi_clock >= config::CPU_FREQUENCY_HZ / 2 { 23 | 0 24 | } else if spi_clock >= config::CPU_FREQUENCY_HZ / 4 { 25 | 1 26 | } else if spi_clock >= config::CPU_FREQUENCY_HZ / 8 { 27 | 2 28 | } else if spi_clock >= config::CPU_FREQUENCY_HZ / 16 { 29 | 3 30 | } else if spi_clock >= config::CPU_FREQUENCY_HZ / 32 { 31 | 4 32 | } else if spi_clock >= config::CPU_FREQUENCY_HZ / 64 { 33 | 5 34 | } else { 35 | 6 36 | }; 37 | 38 | // Invert the SPI2X bit 39 | divider_bits ^= 0x1; 40 | 41 | // Compensate for the duplicate F_osc/64 42 | if divider_bits == 6 { 43 | divider_bits = 7; 44 | } 45 | ClockMask(divider_bits) 46 | } 47 | 48 | pub fn control_register_mask(self) -> u8 { 49 | // SPR1 and SPR0 50 | // These both form bits 1 and 0 of the control register. 51 | (self.0 & 0b110) >> 1 52 | } 53 | 54 | pub fn status_register_mask(self) -> u8 { 55 | // SPI2x 56 | // This forms bit 0 of the status register. 57 | self.0 & 0b1 58 | } 59 | } 60 | 61 | -------------------------------------------------------------------------------- /src/modules/spi/mod.rs: -------------------------------------------------------------------------------- 1 | mod clock; 2 | 3 | 4 | // FIXME: Start using this module or delete!!! 5 | #[allow(dead_code)] mod settings; 6 | 7 | use crate::{Register, Pin}; 8 | 9 | /// An SPI module. 10 | /// 11 | /// Information at [maxembedded.com](http://maxembedded.com/2013/11/the-spi-of-the-avr/). 12 | pub trait HardwareSpi { 13 | type MasterInSlaveOut: Pin; 14 | type MasterOutSlaveIn: Pin; 15 | type Clock: Pin; 16 | type SlaveSelect: Pin; 17 | 18 | /// The SPI control register. 19 | type ControlRegister: Register; 20 | /// The SPI status register. 21 | type StatusRegister: Register; 22 | /// The SPI data register. 23 | type DataRegister: Register; 24 | 25 | /// Sets up the SPI as a master. 26 | fn setup_master(clock: u32) { 27 | // Setup DDR registers. 28 | Self::MasterInSlaveOut::set_input(); 29 | Self::MasterOutSlaveIn::set_output(); 30 | Self::Clock::set_output(); 31 | Self::SlaveSelect::set_input(); 32 | 33 | Self::set_master(); 34 | Self::enable_interrupt(); 35 | Self::setup_common(clock) 36 | } 37 | 38 | /// Sets up the SPI as a slave. 39 | fn setup_slave(clock: u32) { 40 | // Setup DDR registers. 41 | Self::MasterInSlaveOut::set_output(); 42 | Self::MasterOutSlaveIn::set_input(); 43 | Self::Clock::set_input(); 44 | Self::SlaveSelect::set_input(); 45 | 46 | Self::set_slave(); 47 | Self::setup_common(clock) 48 | } 49 | 50 | fn setup_common(clock: u32) { 51 | Self::set_clock(clock); 52 | Self::enable() 53 | } 54 | 55 | /// Sets the clock speed. 56 | fn set_clock(clock: u32) { 57 | let mask = clock::ClockMask::with_clock(clock); 58 | Self::ControlRegister::set_mask_raw(mask.control_register_mask()); 59 | Self::StatusRegister::set_mask_raw(mask.status_register_mask()); 60 | } 61 | 62 | /// Enables interrupts for the spi module. 63 | #[inline(always)] 64 | fn enable_interrupt() { 65 | Self::ControlRegister::set_mask_raw(settings::control_register::INTERRUPT_ENABLE); 66 | } 67 | 68 | /// Disables interrupts for the spi module. 69 | #[inline(always)] 70 | fn disable_interrupt() { 71 | Self::ControlRegister::unset_mask_raw(settings::control_register::INTERRUPT_ENABLE); 72 | } 73 | 74 | /// Enables the SPI. 75 | #[inline(always)] 76 | fn enable() { 77 | Self::ControlRegister::set_mask_raw(settings::control_register::ENABLE); 78 | } 79 | 80 | /// Disables the SPI. 81 | #[inline(always)] 82 | fn disable() { 83 | Self::ControlRegister::unset_mask_raw(settings::control_register::ENABLE); 84 | } 85 | 86 | /// Enables least-significant-bit first. 87 | #[inline(always)] 88 | fn set_lsb() { 89 | Self::ControlRegister::set_mask_raw(settings::control_register::DATA_ORDER_LSB); 90 | } 91 | 92 | /// Enables most-significant-bit first. 93 | #[inline(always)] 94 | fn set_msb() { 95 | Self::ControlRegister::unset_mask_raw(settings::control_register::DATA_ORDER_LSB); 96 | } 97 | 98 | /// Enables master mode. 99 | #[inline(always)] 100 | fn set_master() { 101 | Self::ControlRegister::set_mask_raw(settings::control_register::MASTER); 102 | } 103 | 104 | /// Enables slave mode. 105 | #[inline(always)] 106 | fn set_slave() { 107 | Self::ControlRegister::unset_mask_raw(settings::control_register::MASTER); 108 | } 109 | 110 | /// Enables double speed mode. 111 | #[inline(always)] 112 | fn enable_double_speed() { 113 | Self::StatusRegister::set_mask_raw(settings::status_register::SPI2X); 114 | } 115 | 116 | /// Disables double speed mode. 117 | #[inline(always)] 118 | fn disable_double_speed() { 119 | Self::StatusRegister::unset_mask_raw(settings::status_register::SPI2X); 120 | } 121 | 122 | /// Checks if there is a write collision. 123 | #[inline(always)] 124 | fn is_write_collision() -> bool { 125 | Self::StatusRegister::is_mask_set_raw(settings::status_register::WCOL) 126 | } 127 | 128 | /// Sends a byte through the serial. 129 | #[inline(always)] 130 | fn send_byte(byte: u8) { 131 | Self::DataRegister::write(byte); 132 | Self::StatusRegister::wait_until_mask_set_raw(settings::status_register::SPIF); 133 | } 134 | 135 | /// Reads a byte from the serial. 136 | #[inline(always)] 137 | fn receive_byte() -> u8 { 138 | Self::StatusRegister::wait_until_mask_set_raw(settings::status_register::SPIF); 139 | Self::DataRegister::read() 140 | } 141 | 142 | /// Sends and receives a byte. 143 | #[inline(always)] 144 | fn send_receive(byte: u8) -> u8 { 145 | Self::DataRegister::write(byte); 146 | Self::StatusRegister::wait_until_mask_set_raw(settings::status_register::SPIF); 147 | Self::DataRegister::read() 148 | } 149 | } 150 | 151 | -------------------------------------------------------------------------------- /src/modules/spi/settings.rs: -------------------------------------------------------------------------------- 1 | use super::clock::ClockMask; 2 | 3 | #[derive(Copy, Clone)] 4 | pub enum BitOrder { 5 | /// The least significant bit is sent first. 6 | LeastSignificantBit, 7 | /// The most significant bit is sent first. 8 | MostSignificantBit, 9 | } 10 | 11 | #[derive(Copy, Clone)] 12 | pub enum ClockPhase { 13 | LeadingEdge, 14 | TrailingEdge, 15 | } 16 | 17 | /// SPI settings. 18 | #[derive(Copy, Clone)] 19 | pub struct Settings { 20 | /// Whether the SPI module is enabled. 21 | enabled: bool, 22 | /// Whether to be configured as a master or slave. 23 | master: bool, 24 | /// The clock speed. 25 | clock: u32, 26 | /// The bit ordering. 27 | bit_order: BitOrder, 28 | /// The clock phase. 29 | clock_phase: ClockPhase, 30 | /// Whether interrupts should be enabled. 31 | enable_interrupts: bool, 32 | } 33 | 34 | impl Settings { 35 | /// Gets the default settings for the master. 36 | pub fn master() -> Self { 37 | Settings { 38 | master: true, 39 | ..Default::default() 40 | } 41 | } 42 | 43 | /// Gets the default settings for the slave. 44 | pub fn slave() -> Self { 45 | Settings { 46 | master: false, 47 | ..Default::default() 48 | } 49 | } 50 | 51 | pub fn control_register_bits(self) -> u8 { 52 | let mut bits = 0; 53 | 54 | bits |= self.clock().control_register_mask(); 55 | 56 | if self.enable_interrupts { 57 | bits |= control_register::INTERRUPT_ENABLE 58 | } 59 | if self.enabled { 60 | bits |= control_register::ENABLE 61 | } 62 | if let ClockPhase::LeadingEdge = self.clock_phase { 63 | bits |= control_register::CPHA; 64 | } 65 | 66 | if let BitOrder::LeastSignificantBit = self.bit_order { 67 | bits |= control_register::DATA_ORDER_LSB; 68 | } 69 | bits 70 | } 71 | 72 | pub fn status_register_bits(self) -> u8 { 73 | let mut bits = 0; 74 | 75 | bits |= self.clock().status_register_mask(); 76 | bits 77 | } 78 | 79 | fn clock(self) -> ClockMask { 80 | ClockMask::with_clock(self.clock) 81 | } 82 | } 83 | 84 | impl Default for Settings { 85 | fn default() -> Settings { 86 | Settings { 87 | enabled: true, 88 | master: true, 89 | // same as Arduino default in `SPI.h`. 90 | clock: 4_000_000, 91 | bit_order: BitOrder::MostSignificantBit, 92 | clock_phase: ClockPhase::LeadingEdge, 93 | enable_interrupts: false, 94 | } 95 | } 96 | } 97 | 98 | /// Constants for the control register. 99 | #[allow(dead_code)] 100 | pub mod control_register { 101 | /// Set if interrupts are enabled. 102 | pub const INTERRUPT_ENABLE: u8 = 1<<7; 103 | /// Set if the SPI module is enabled. 104 | pub const ENABLE: u8 = 1<<6; 105 | /// Set if data is sent in LSB format. 106 | pub const DATA_ORDER_LSB: u8 = 1<<5; 107 | /// Set if we are configuring a master. 108 | pub const MASTER: u8 = 1<<4; 109 | /// Clock polarity. 110 | pub const CPOL: u8 = 1<<3; 111 | /// Clock phase. 112 | pub const CPHA: u8 = 1<<2; 113 | /// Clock rate select 1. 114 | pub const SPR1: u8 = 1<<1; 115 | /// Clock rate select 2. 116 | pub const SPR0: u8 = 1<<0; 117 | } 118 | 119 | /// Constants for the status register. 120 | #[allow(dead_code)] 121 | pub mod status_register { 122 | /// SPI interrupt flag. 123 | pub const SPIF: u8 = 1<<7; 124 | /// Write collision flag. 125 | pub const WCOL: u8 = 1<<6; 126 | /// SPI double speed mode. 127 | pub const SPI2X: u8 = 1<<0; 128 | } 129 | 130 | -------------------------------------------------------------------------------- /src/modules/timer/mod.rs: -------------------------------------------------------------------------------- 1 | pub use self::timer8::{ 2 | ClockSource as ClockSource8, Timer8, Timer8Setup, 3 | WaveformGenerationMode as WaveformGenerationMode8, 4 | }; 5 | pub use self::timer16::{ 6 | ClockSource as ClockSource16, Timer16, Timer16Setup, 7 | WaveformGenerationMode as WaveformGenerationMode16, 8 | }; 9 | 10 | mod timer8; 11 | mod timer16; 12 | -------------------------------------------------------------------------------- /src/modules/timer/timer16.rs: -------------------------------------------------------------------------------- 1 | use crate::{RegisterBits, Register}; 2 | use core::marker; 3 | 4 | /// A 16-bit timer. 5 | pub trait Timer16 : Sized { 6 | /// The first compare register. 7 | /// For example, OCR0A. 8 | type CompareA: Register; 9 | 10 | /// The second compare register. 11 | /// For example, OCR0B. 12 | type CompareB: Register; 13 | 14 | /// The counter register. 15 | /// 16 | /// For example, TCNT0. 17 | type Counter: Register; 18 | 19 | /// The first control register. 20 | /// 21 | /// For example, TCCR0A. 22 | type ControlA: Register; 23 | 24 | /// The second control register. 25 | /// 26 | /// For example, TCCR0B. 27 | type ControlB: Register; 28 | 29 | /// The third control register. 30 | /// 31 | /// For example, TCCR0C. 32 | type ControlC: Register; 33 | 34 | /// The interrupt mask register. 35 | /// 36 | /// For example, TIMSK0. 37 | type InterruptMask: Register; 38 | 39 | /// The interrupt flag register. 40 | /// 41 | /// For example, TIFR0. 42 | type InterruptFlag: Register; 43 | 44 | const CS0: RegisterBits; 45 | const CS1: RegisterBits; 46 | const CS2: RegisterBits; 47 | 48 | const WGM0: RegisterBits; 49 | const WGM1: RegisterBits; 50 | const WGM2: RegisterBits; 51 | const WGM3: RegisterBits; 52 | 53 | const OCIEA: RegisterBits; 54 | 55 | fn setup() -> Timer16Setup { Timer16Setup::new() } 56 | } 57 | 58 | pub enum ClockSource { 59 | None, 60 | Prescale1, 61 | Prescale8, 62 | Prescale64, 63 | Prescale256, 64 | Prescale1024, 65 | ExternalFalling, 66 | ExternalRising, 67 | } 68 | 69 | impl ClockSource { 70 | fn bits(&self) -> RegisterBits { 71 | use self::ClockSource::*; 72 | 73 | match *self { 74 | None => RegisterBits::zero() | RegisterBits::zero() | RegisterBits::zero(), 75 | Prescale1 => RegisterBits::zero() | RegisterBits::zero() | T::CS0, 76 | Prescale8 => RegisterBits::zero() | T::CS1 | RegisterBits::zero(), 77 | Prescale64 => RegisterBits::zero() | T::CS1 | T::CS0, 78 | Prescale256 => T::CS2 | RegisterBits::zero() | RegisterBits::zero(), 79 | Prescale1024 => T::CS2 | RegisterBits::zero() | T::CS0, 80 | ExternalFalling => T::CS2 | T::CS1 | RegisterBits::zero(), 81 | ExternalRising => T::CS2 | T::CS1 | T::CS0, 82 | } 83 | } 84 | 85 | #[inline] 86 | fn mask() -> RegisterBits { 87 | !(T::CS2 | T::CS1 | T::CS0) 88 | } 89 | } 90 | 91 | pub enum WaveformGenerationMode { 92 | Normal, 93 | PwmPhaseCorrect8Bit, 94 | PwmPhaseCorrect9Bit, 95 | PwmPhaseCorrect10Bit, 96 | ClearOnTimerMatchOutputCompare, 97 | FastPwm8Bit, 98 | FastPwm9Bit, 99 | FastPwm10Bit, 100 | PwmPhaseAndFrequencyCorrectInputCapture, 101 | PwmPhaseAndFrequencyCorrectOutputCompare, 102 | PwmPhaseCorrectInputCapture, 103 | PwmPhaseCorrectOutputCompare, 104 | ClearOnTimerMatchInputCapture, 105 | FastPwmInputCapture, 106 | FastPwmOutputCompare, 107 | } 108 | 109 | impl WaveformGenerationMode { 110 | /// Returns bits for TCCR1A, TCCR1B 111 | #[inline] 112 | fn bits(&self) -> (RegisterBits, RegisterBits) { 113 | use self::WaveformGenerationMode::*; 114 | use RegisterBits as B; 115 | 116 | // It makes more sense to return bytes (A,B), but the manual 117 | // lists the table as (B,A). We match the manual here for 118 | // inspection purposes and flip the values for sanity 119 | // purposes. 120 | let (b, a) = match *self { 121 | Normal => (B::zero() | B::zero(), B::zero() | B::zero()), 122 | PwmPhaseCorrect8Bit => (B::zero() | B::zero(), B::zero() | T::WGM0), 123 | PwmPhaseCorrect9Bit => (B::zero() | B::zero(), T::WGM1 | B::zero()), 124 | PwmPhaseCorrect10Bit => (B::zero() | B::zero(), T::WGM1 | T::WGM0), 125 | ClearOnTimerMatchOutputCompare => (B::zero() | T::WGM2, B::zero() | B::zero()), 126 | FastPwm8Bit => (B::zero() | T::WGM2, B::zero() | T::WGM0), 127 | FastPwm9Bit => (B::zero() | T::WGM2, T::WGM1 | B::zero()), 128 | FastPwm10Bit => (B::zero() | T::WGM2, T::WGM1 | T::WGM0), 129 | PwmPhaseAndFrequencyCorrectInputCapture => (T::WGM3 | B::zero(), B::zero() | B::zero()), 130 | PwmPhaseAndFrequencyCorrectOutputCompare => (T::WGM3 | B::zero(), B::zero() | T::WGM0), 131 | PwmPhaseCorrectInputCapture => (T::WGM3 | B::zero(), T::WGM1 | B::zero()), 132 | PwmPhaseCorrectOutputCompare => (T::WGM3 | B::zero(), T::WGM1 | T::WGM0), 133 | ClearOnTimerMatchInputCapture => (T::WGM3 | T::WGM2, B::zero() | B::zero()), 134 | // Reserved => (T::WGM3 | T::WGM2, B::zero() | T::WGM0), 135 | FastPwmInputCapture => (T::WGM3 | T::WGM2, T::WGM1 | B::zero()), 136 | FastPwmOutputCompare => (T::WGM3 | T::WGM2, T::WGM1 | T::WGM0), 137 | }; 138 | 139 | (a, b) 140 | } 141 | 142 | #[inline] 143 | fn mask() -> (RegisterBits, RegisterBits) { 144 | (!(T::WGM0 | T::WGM1), !(T::WGM2 | T::WGM3)) 145 | } 146 | } 147 | 148 | pub struct Timer16Setup { 149 | a: RegisterBits, 150 | b: RegisterBits, 151 | c: RegisterBits, 152 | output_compare_1: Option, 153 | _phantom: marker::PhantomData, 154 | } 155 | 156 | impl Timer16Setup { 157 | #[inline] 158 | pub fn new() -> Self { 159 | Timer16Setup { 160 | a: RegisterBits::zero(), 161 | b: RegisterBits::zero(), 162 | c: RegisterBits::zero(), 163 | output_compare_1: None, 164 | _phantom: marker::PhantomData, 165 | } 166 | } 167 | 168 | #[inline] 169 | pub fn clock_source(mut self, source: ClockSource) -> Self { 170 | self.b &= ClockSource::mask::(); 171 | self.b |= source.bits::(); 172 | self 173 | } 174 | 175 | #[inline] 176 | pub fn waveform_generation_mode(mut self, mode: WaveformGenerationMode) -> Self { 177 | let (a, b) = WaveformGenerationMode::mask::(); 178 | self.a &= a; 179 | self.b &= b; 180 | 181 | let (a, b) = mode.bits::(); 182 | self.a |= a; 183 | self.b |= b; 184 | 185 | self 186 | } 187 | 188 | #[inline] 189 | pub fn output_compare_1(mut self, value: Option) -> Self { 190 | self.output_compare_1 = value; 191 | self 192 | } 193 | 194 | #[inline] 195 | pub fn configure(self) { 196 | T::ControlA::write(self.a); 197 | T::ControlB::write(self.b); 198 | T::ControlC::write(self.c); 199 | 200 | // Reset counter to zero 201 | T::Counter::write(0u16); 202 | 203 | if let Some(v) = self.output_compare_1 { 204 | // Set the match 205 | T::CompareA::write(v); 206 | 207 | // Enable compare interrupt 208 | T::InterruptMask::set(T::OCIEA); 209 | } 210 | } 211 | } 212 | -------------------------------------------------------------------------------- /src/modules/timer/timer8.rs: -------------------------------------------------------------------------------- 1 | use crate::{RegisterBits, Register}; 2 | use core::marker; 3 | 4 | /// A 8-bit timer. 5 | pub trait Timer8 : Sized { 6 | /// The first compare register. 7 | /// For example, OCR0A. 8 | type CompareA: Register; 9 | 10 | /// The second compare register. 11 | /// For example, OCR0B. 12 | type CompareB: Register; 13 | 14 | /// The counter register. 15 | /// 16 | /// For example, TCNT0. 17 | type Counter: Register; 18 | 19 | /// The first control register. 20 | /// 21 | /// For example, TCCR0A. 22 | type ControlA: Register; 23 | 24 | /// The second control register. 25 | /// 26 | /// For example, TCCR0B. 27 | type ControlB: Register; 28 | 29 | /// The interrupt mask register. 30 | /// 31 | /// For example, TIMSK0. 32 | type InterruptMask: Register; 33 | 34 | /// The interrupt flag register. 35 | /// 36 | /// For example, TIFR0. 37 | type InterruptFlag: Register; 38 | 39 | /// Bit 0 of the clock select mask. 40 | const CS0: RegisterBits; 41 | /// Bit 1 of the clock select mask. 42 | const CS1: RegisterBits; 43 | /// Bit 2 of the clock select mask. 44 | const CS2: RegisterBits; 45 | 46 | /// Bit 0 of the waveform generation mode mask. 47 | const WGM0: RegisterBits; 48 | /// Bit 1 of the waveform generation mode mask. 49 | const WGM1: RegisterBits; 50 | /// Bit 2 of the waveform generation mode mask. 51 | const WGM2: RegisterBits; 52 | 53 | /// Output compare interrupt enable flag. 54 | const OCIEA: RegisterBits; 55 | } 56 | 57 | pub enum ClockSource { 58 | None, 59 | Prescale1, 60 | Prescale8, 61 | Prescale64, 62 | Prescale256, 63 | Prescale1024, 64 | ExternalFalling, 65 | ExternalRising, 66 | } 67 | 68 | impl ClockSource { 69 | fn bits(&self) -> RegisterBits { 70 | use self::ClockSource::*; 71 | 72 | match *self { 73 | None => RegisterBits::zero() | RegisterBits::zero() | RegisterBits::zero(), 74 | Prescale1 => RegisterBits::zero() | RegisterBits::zero() | T::CS0, 75 | Prescale8 => RegisterBits::zero() | T::CS1 | RegisterBits::zero(), 76 | Prescale64 => RegisterBits::zero() | T::CS1 | T::CS0, 77 | Prescale256 => T::CS2 | RegisterBits::zero() | RegisterBits::zero(), 78 | Prescale1024 => T::CS2 | RegisterBits::zero() | T::CS0, 79 | ExternalFalling => T::CS2 | T::CS1 | RegisterBits::zero(), 80 | ExternalRising => T::CS2 | T::CS1 | T::CS0, 81 | } 82 | } 83 | 84 | #[inline] 85 | fn mask() -> RegisterBits { 86 | !(T::CS2 | T::CS1 | T::CS0) 87 | } 88 | } 89 | 90 | pub enum WaveformGenerationMode { 91 | Normal, 92 | PwmPhaseCorrect, 93 | ClearOnTimerMatchOutputCompare, 94 | FastPwm , 95 | PwmPhaseCorrectOutputCompare, 96 | FastPwmOutputCompare, 97 | } 98 | 99 | impl WaveformGenerationMode { 100 | /// Returns bits for TCCR0A, TCCR0B 101 | #[inline] 102 | fn bits(&self) -> (RegisterBits, RegisterBits) { 103 | use self::WaveformGenerationMode::*; 104 | 105 | // It makes more sense to return bytes (A,B), but the manual 106 | // lists the table as (B,A). We match the manual here for 107 | // inspection purposes and flip the values for sanity 108 | // purposes. 109 | let (b, a) = match *self { 110 | Normal => (RegisterBits::zero(), RegisterBits::zero() | RegisterBits::zero()), 111 | PwmPhaseCorrect => (RegisterBits::zero(), RegisterBits::zero() | T::WGM0), 112 | ClearOnTimerMatchOutputCompare => (RegisterBits::zero(), T::WGM1 | RegisterBits::zero()), 113 | FastPwm => (RegisterBits::zero(), T::WGM1 | T::WGM0), 114 | // Reserved => (T::WGM2, RegisterBits::zero() | RegisterBits::zero()), 115 | PwmPhaseCorrectOutputCompare => (T::WGM2, RegisterBits::zero() | T::WGM0), 116 | // Reserved => (T::WGM2, T::WGM1 | RegisterBits::zero())), 117 | FastPwmOutputCompare => (T::WGM2, T::WGM1 | T::WGM0), 118 | }; 119 | 120 | (a, b) 121 | } 122 | 123 | #[inline] 124 | fn mask() -> (RegisterBits, RegisterBits) { 125 | (!(T::WGM0 | T::WGM1), !(T::WGM2)) 126 | } 127 | } 128 | 129 | pub struct Timer8Setup { 130 | a: RegisterBits, 131 | b: RegisterBits, 132 | output_compare_1: Option, 133 | _phantom: marker::PhantomData, 134 | } 135 | 136 | impl Timer8Setup { 137 | #[inline] 138 | pub fn new() -> Self { 139 | Timer8Setup { 140 | a: RegisterBits::zero(), 141 | b: RegisterBits::zero(), 142 | output_compare_1: None, 143 | _phantom: marker::PhantomData, 144 | } 145 | } 146 | 147 | #[inline] 148 | pub fn clock_source(mut self, source: ClockSource) -> Self { 149 | self.b &= ClockSource::mask::(); 150 | self.b |= source.bits::(); 151 | self 152 | } 153 | 154 | #[inline] 155 | pub fn waveform_generation_mode(mut self, mode: WaveformGenerationMode) -> Self { 156 | let (a, b) = WaveformGenerationMode::mask::(); 157 | self.a &= a; 158 | self.b &= b; 159 | 160 | let (a, b) = mode.bits::(); 161 | self.a |= a; 162 | self.b |= b; 163 | 164 | self 165 | } 166 | 167 | #[inline] 168 | pub fn output_compare_1(mut self, value: Option) -> Self { 169 | self.output_compare_1 = value; 170 | self 171 | } 172 | 173 | #[inline] 174 | pub fn configure(self) { 175 | T::ControlA::write(self.a); 176 | T::ControlB::write(self.b); 177 | 178 | // Reset counter to zero 179 | T::Counter::write(0); 180 | 181 | if let Some(v) = self.output_compare_1 { 182 | // Set the match 183 | T::CompareA::write(v); 184 | 185 | // Enable compare interrupt 186 | T::InterruptMask::set(T::OCIEA); 187 | } 188 | } 189 | } 190 | -------------------------------------------------------------------------------- /src/modules/usart.rs: -------------------------------------------------------------------------------- 1 | use crate::Register; 2 | 3 | pub trait HardwareUsart { 4 | /// The USART data register. 5 | type DataRegister: Register; 6 | /// USART control and status register A. 7 | type ControlRegisterA: Register; 8 | /// USART control and status register B. 9 | type ControlRegisterB: Register; 10 | /// USART control and status register C. 11 | type ControlRegisterC: Register; 12 | /// USART baud rate register. 13 | type BaudRateRegister: Register; 14 | } 15 | -------------------------------------------------------------------------------- /src/pin.rs: -------------------------------------------------------------------------------- 1 | use crate::Register; 2 | 3 | /// Represents whether a pin is an input or an output. 4 | pub enum DataDirection { 5 | /// The pin is exclusively used for reading signals. 6 | Input, 7 | /// The pin is exclusively used for sending signals. 8 | Output, 9 | } 10 | 11 | /// An IO pin. 12 | pub trait Pin { 13 | /// The associated data direction register. 14 | type DDR: Register; 15 | /// The associated port register. 16 | type PORT: Register; 17 | 18 | /// 19 | /// Reads from the register will read input bits. 20 | /// Writes to the register will toggle bits. 21 | type PIN: Register; 22 | /// The mask of the pin used for accessing registers. 23 | const MASK: u8; 24 | 25 | /// Sets the data direction of the pin. 26 | #[inline(always)] 27 | fn set_direction(direction: DataDirection) { 28 | match direction { 29 | DataDirection::Input => Self::set_input(), 30 | DataDirection::Output => Self::set_output(), 31 | } 32 | } 33 | 34 | /// Sets the pin up as an input. 35 | #[inline(always)] 36 | fn set_input() { 37 | Self::DDR::unset_mask_raw(Self::MASK); 38 | } 39 | 40 | /// Sets the pin up as an output. 41 | #[inline(always)] 42 | fn set_output() { 43 | Self::DDR::set_mask_raw(Self::MASK); 44 | } 45 | 46 | /// Set the pin to high. 47 | /// 48 | /// The pin must be configured as an output. 49 | #[inline(always)] 50 | fn set_high() { 51 | Self::PORT::set_mask_raw(Self::MASK); 52 | } 53 | 54 | /// Set the pin to low. 55 | /// 56 | /// The pin must be configured as an output. 57 | #[inline(always)] 58 | fn set_low() { 59 | Self::PORT::unset_mask_raw(Self::MASK); 60 | } 61 | 62 | /// Toggles the pin. 63 | /// 64 | /// The pin must be configured as an output. 65 | #[inline(always)] 66 | fn toggle() { 67 | // FIXME: We can optimise this on post-2006 AVRs. 68 | // http://www.avrfreaks.net/forum/toggle-state-output-pin 69 | // set(Self::PIN, Self::MASK); 70 | Self::PORT::toggle_raw(Self::MASK); 71 | } 72 | 73 | /// Check if the pin is currently high. 74 | /// 75 | /// The pin must be configured as an input. 76 | #[inline(always)] 77 | fn is_high() -> bool { 78 | Self::PIN::is_mask_set_raw(Self::MASK) 79 | } 80 | 81 | /// Checks if the pin is currently low. 82 | /// 83 | /// The pin must be configured as an input. 84 | #[inline(always)] 85 | fn is_low() -> bool { 86 | Self::PIN::is_clear_raw(Self::MASK) 87 | } 88 | } 89 | 90 | -------------------------------------------------------------------------------- /src/prelude.rs: -------------------------------------------------------------------------------- 1 | //! Re-exports commonly-used APIs that can be imported at once. 2 | 3 | pub use crate::interrupt::without_interrupts; 4 | 5 | -------------------------------------------------------------------------------- /src/register.rs: -------------------------------------------------------------------------------- 1 | use core::{cmp, convert, marker, ops}; 2 | 3 | /// A value that a register can store. 4 | /// 5 | /// All registers are either `u8` or `u16`. 6 | pub trait RegisterValue : Copy + Clone + 7 | ops::BitAnd + 8 | ops::BitAndAssign + 9 | ops::BitOr + 10 | ops::BitOrAssign + 11 | ops::BitXor + 12 | ops::BitXorAssign + 13 | ops::Not + 14 | cmp::PartialEq + cmp::Eq + 15 | cmp::PartialOrd + cmp::Ord + 16 | convert::From { 17 | } 18 | 19 | /// A register. 20 | pub trait Register : Sized { 21 | /// The type that can represent the value of the register. 22 | type T: RegisterValue; 23 | /// The type representing a set of bits that may be manipulated 24 | /// within the register. 25 | type RegisterBits = RegisterBits; 26 | 27 | /// The address of the register. 28 | const ADDRESS: *mut Self::T; 29 | 30 | /// Writes a value to the register. 31 | #[inline(always)] 32 | fn write(value: V) where V: Into { 33 | unsafe { 34 | core::ptr::write_volatile(Self::ADDRESS, value.into()); 35 | } 36 | } 37 | 38 | /// Reads the value of the register. 39 | #[inline(always)] 40 | fn read() -> Self::T { 41 | unsafe { core::ptr::read_volatile(Self::ADDRESS) } 42 | } 43 | 44 | /// Sets a set of bits to `1` in the register. 45 | fn set(bits: RegisterBits) { 46 | Self::set_mask_raw(bits.mask); 47 | } 48 | 49 | /// Sets a bitmask in a register. 50 | /// 51 | /// This is equivalent to `r |= mask`. 52 | #[inline(always)] 53 | fn set_mask_raw(mask: Self::T) { 54 | unsafe { 55 | core::ptr::write_volatile(Self::ADDRESS, core::ptr::read_volatile(Self::ADDRESS) | mask); 56 | } 57 | } 58 | 59 | /// Unsets a set of bits in the register. 60 | /// 61 | /// All of the bits will be set to `0`. 62 | fn unset(bits: RegisterBits) { 63 | Self::unset_mask_raw(bits.mask); 64 | } 65 | 66 | /// Clears a bitmask from a register. 67 | /// 68 | /// This is equivalent to `r &= !mask`. 69 | #[inline(always)] 70 | fn unset_mask_raw(mask: Self::T) { 71 | unsafe { 72 | core::ptr::write_volatile(Self::ADDRESS, core::ptr::read_volatile(Self::ADDRESS) & !mask) 73 | } 74 | } 75 | 76 | /// Toggles a set of bits within the register. 77 | /// 78 | /// All specified bits which were previously `0` will become 79 | /// `1`, and all specified bits that were previous `1` will 80 | /// become `0`. 81 | fn toggle(mask: RegisterBits) { 82 | Self::toggle_raw(mask.mask); 83 | } 84 | 85 | /// Toggles a mask in the register. 86 | /// 87 | /// This is equivalent to `r ^= mask`. 88 | #[inline(always)] 89 | fn toggle_raw(mask: Self::T) { 90 | unsafe { 91 | core::ptr::write_volatile(Self::ADDRESS, core::ptr::read_volatile(Self::ADDRESS) ^ mask) 92 | } 93 | } 94 | 95 | /// Checks if a set of bits are enabled. 96 | /// 97 | /// All specifed bits must be set for this function 98 | /// to return `true`. 99 | fn is_set(bits: RegisterBits) -> bool { 100 | Self::is_mask_set_raw(bits.mask) 101 | } 102 | 103 | /// Checks if a mask is set in the register. 104 | /// 105 | /// This is equivalent to `(r & mask) == mask`. 106 | #[inline(always)] 107 | fn is_mask_set_raw(mask: Self::T) -> bool { 108 | unsafe { 109 | (core::ptr::read_volatile(Self::ADDRESS) & mask) == mask 110 | } 111 | } 112 | 113 | /// Checks if a set of bits are not set. 114 | /// 115 | /// All specified bits must be `0` for this 116 | /// function to return `true`. 117 | fn is_clear(mask: RegisterBits) -> bool { 118 | Self::is_clear_raw(mask.mask) 119 | } 120 | 121 | /// Checks if a mask is clear in the register. 122 | /// 123 | /// This is equivalent to `(r & mask) == 0`. 124 | #[inline(always)] 125 | fn is_clear_raw(mask: Self::T) -> bool { 126 | unsafe { 127 | (core::ptr::read_volatile(Self::ADDRESS) & mask) == Self::T::from(0) 128 | } 129 | } 130 | 131 | /// Waits until a set of bits are set in the register. 132 | /// 133 | /// This function will block until all bits that are set in 134 | /// the mask are also set in the register. 135 | fn wait_until_set(bits: RegisterBits) { 136 | Self::wait_until_mask_set_raw(bits.mask); 137 | } 138 | 139 | /// Waits until a bit mask is set in the register. 140 | /// 141 | /// This function will block until all bits that are set in 142 | /// the mask are also set in the register. 143 | #[inline(always)] 144 | fn wait_until_mask_set_raw(mask: Self::T) { 145 | wait_until(|| Self::is_mask_set_raw(mask)) 146 | } 147 | } 148 | 149 | /// Represents a set of bits within a specific register. 150 | #[derive(Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)] 151 | pub struct RegisterBits { 152 | /// The raw bitmask. 153 | mask: R::T, 154 | _phantom: marker::PhantomData, 155 | } 156 | 157 | impl RegisterBits where R: Register { 158 | /// Creates a new register mask. 159 | pub const fn new(mask: R::T) -> Self { 160 | RegisterBits { mask, _phantom: marker::PhantomData } 161 | } 162 | 163 | pub fn zero() -> Self { 164 | RegisterBits::new(0u8.into()) 165 | } 166 | } 167 | 168 | impl ops::BitOr for RegisterBits where R: Register 169 | { 170 | type Output = Self; 171 | 172 | fn bitor(self, rhs: Self) -> Self { 173 | RegisterBits::new(self.mask | rhs.mask) 174 | } 175 | } 176 | 177 | impl ops::BitOrAssign for RegisterBits where R: Register { 178 | fn bitor_assign(&mut self, rhs: Self) { 179 | self.mask |= rhs.mask; 180 | } 181 | } 182 | 183 | impl ops::BitAnd for RegisterBits where R: Register 184 | { 185 | type Output = Self; 186 | 187 | fn bitand(self, rhs: Self) -> Self { 188 | RegisterBits::new(self.mask & rhs.mask) 189 | } 190 | } 191 | 192 | impl ops::BitAndAssign for RegisterBits where R: Register { 193 | fn bitand_assign(&mut self, rhs: Self) { 194 | self.mask &= rhs.mask; 195 | } 196 | } 197 | 198 | impl ops::Not for RegisterBits where R: Register { 199 | type Output = Self; 200 | 201 | fn not(self) -> Self { 202 | RegisterBits::new(!self.mask) 203 | } 204 | } 205 | 206 | impl From> for u8 where R: Register { 207 | fn from(other: RegisterBits) -> u8 { other.mask } 208 | } 209 | 210 | impl From> for u16 where R: Register { 211 | fn from(other: RegisterBits) -> u16 { other.mask } 212 | } 213 | 214 | impl RegisterValue for u8 { } 215 | impl RegisterValue for u16 { } 216 | 217 | /// Waits until some condition is true of the register. 218 | #[inline(always)] 219 | fn wait_until(mut f: F) 220 | where F: FnMut() -> bool { 221 | loop { 222 | if f() { 223 | break; 224 | } 225 | } 226 | } 227 | 228 | --------------------------------------------------------------------------------