Coder Social home page Coder Social logo

avr-device's Introduction

avr-device crates.io page docs.rs Continuous Integration

Auto-generated wrappers around registers for AVR microcontrollers.

Usage

Add the following to Cargo.toml:

[dependencies.avr-device]
version = "0.5.4"
features = ["atmega32u4"]

Via the feature you can select which chip you want the register specifications for. The following list is what is currently supported:

ATmega ATmega USB ATmega 0,1 Series AT90 ATtiny
atmega8 atmega8u2 atmega4808 at90usb1286 attiny13a
atmega48p atmega32u4 atmega4809 attiny167
atmega64 avr64du32 attiny202
atmega644 avr64du28 attiny402
atmega88p attiny404
atmega16 attiny44a
atmega168 attiny84
atmega324pa attiny85
atmega328p attiny88
atmega328pb attiny816
atmega32a attiny828
atmega1280 attiny841
atmega1284p attiny84a
atmega128a attiny861
atmega128rfa1 attiny1614
atmega2560 attiny2313
atmega164pa attiny2313a

Build Instructions

The version on crates.io is pre-built. The following is only necessary when trying to build this crate from source.

You need to have atdf2svd (= 0.4.0), svd2rust (= 0.28), form (>= 0.8), rustfmt(for the nightly toolchain) and svdtools (>= 0.1.9) installed:

cargo install atdf2svd --version 0.4.0
cargo install svd2rust --version 0.28.0
cargo install form
rustup component add --toolchain nightly rustfmt
pip3 install --user svdtools

# check svdtools
svd --version
# if a "command not found" error is printed instead of a version,
# either svdtools is installed incorrectly, or its installation path is missing from the PATH variable.
# Temporary solution to PATH variable issue is to manually add the path. Like so:
export PATH=$PATH:~/.local/bin

Next, clone this repo and build the device definitions:

git clone https://github.com/Rahix/avr-device
cd avr-device
make
# You can build for just one specific chip using
# make atmega32u4
# I suggest building documentation as well
cargo +nightly doc --features <chip> --open

Internals

avr-device is generated using atdf2svd and svd2rust. The vendor-provided atdf files can be found in vendor/. The intermediate svd files are patched by svdpatch.py (Adapted from svdpatch.py in stm32-rs) with device-dependent patches in patch/, mainly to improve undescriptive names and missing descriptions.

Adding a new Chip

To add a new chip, download the atdf from http://packs.download.atmel.com/ (or avr-mcu/packs/) and place it in vendor/. Be sure to name it like the Rust module that should be generated. Next, you need to integrate it into the base crate and build system. Follow what was done in commit 290613454fbd ("Add basic support for ATmega64"). Please adhere to the alphabetical sorting that is present so far.

Next, you must create a <chipname>.yaml in patch/ which has at least the following content:

_svd: ../svd/<chipname>.svd

If more patches need to be applied (most likely!), they should be added into this file as well. The patching format is documented in the svdtools README. Ideally, try to reuse the exisiting patches in patch/common/ or patch/timer/.

Finally, try building the crate for your MCU with make <chipname>.

License

avr-device is licensed under either of

at your option.

The vendored atdf files are licensed under the Apache License, Version 2.0 (LICENSE-VENDOR).

avr-device's People

Contributors

agausmann avatar couchand avatar daandekoningkrekels avatar dalpil avatar dependabot[bot] avatar explicite avatar gpgreen avatar jaxter184 avatar jonahbron avatar khimaros avatar lights0123 avatar lperlaki avatar mbuesch avatar michaeldarr avatar n-eq avatar no111u3 avatar nzrosto avatar octycs avatar patryk27 avatar peacememories avatar pitaj avatar plastik-flasche avatar quentinmit avatar rahix avatar rutherther avatar snakeoilsalesman avatar the6p4c avatar torrancew avatar tronje avatar zettascript avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

avr-device's Issues

Better Mutex

We're currently relying on the mutex type from bare-metal which is actually being removed upstream so now is a good time to think about adding a similar mechanism here and maybe improving it. For starters, I'd want the mutex to actually hand out &mut _ references because 99% of use-cases need this.

It would be interesting to explore the concept of a critical-section handle a bit more:

  • Maybe ISRs should optionally get a cs-handle as an argument as nothing could interrupt them?
  • Even further, maybe main should get a cs-handle in the beginning? Interrupts are disabled so it would be sound. Then, later an interrupt::enable() function should consume the handle when enabling interrupts for the first time. Is there a problem I'm missing?

attiny_hal::pac::exint::pcmsk::W missing BitWriterRaw implementation?

Hello,

I'm only a rookie, but this seems strange for me: When I want to change the PCMSK register, there is no way to access single bits, like there is e.g. for the GIMSK:

            self.exint.gimsk.modify(|_, w| w.pcie().set_bit()); // Good
            self.exint.pcmsk.modify(|_, w| w.bits(1)); // Not so good

There aren't even constants for the single bits…

I'd expect to be able to do this:

            self.exint.pcmsk.modify(|_, w| w.pcint0().set_bit());

Am I right?

Patch-file needed, else "No rule to make target..."

Trying to integrate the attiny412, whilest executing make I got the error make: *** No rule to make target 'src/devices/attiny412/mod.rs', needed by 'attiny412'. Stop..

After creating the file patch/attiny412.yaml with following content

_svd: ../svd/attiny412.svd

Is it possible that a patch file must always be created? If so, this should be added to the README.md

Field Access Ranges

Right now, all fields which span more than one bit and which do not have a value-group associated in the atdf will get a range added to mark all values as allowed:

<writeConstraint>
  <range>
    <minimum>0</minimum>
     <maximum>3</maximum>
  </range>
</writeConstraint>

The responsible code is this:

https://github.com/Rahix/atdf2svd/blob/c7eb572c4ea12033bc2b9ccfe23d22ea2d859554/src/atdf/field.rs#L28-L40

Unfortunately, this will lead to issues further down the line, when trying to add enumerated values using svdpatch.py: The range will still exist, next to the values, which makes svd2rust believe writing this field is safe.

Right now, the only workaround is to completely remove a field and re-add it, which is error-prone and not very flexible.

Question now is, whether this is an issue here in atdf2svd or should rather be fixed downstream in the patch-tool. @octycs, what is your opinion?

atmega328 (no p) support?

I'm uncertain if this omission is because nobody (else) has wanted to use rust with one or that there's no need for explicit support because it is so similar to the 328p? I guess I'm particularly surprised because the vanilla atmega328 is the only atmega with built-in support for the (nightly) toolchain. Is there some simple configuration option that would allow me to use this chip with rust libraries that depend on avr-device? In particular I'm wanting to use atmega-hal. I apologize if the solution to this is obvious and trivial but I'm new to rust and wanting to try it with a MC project.

Renesas RA4M1 support

Arduino UNO R4 WiFi featuring Renesas RA4M1 chip came out recently. Are you thinking of adding support for it?

Build is not compatible with svd2rust > 0.14.0

More recent versions of svd2rust emit a lot of stuff into lib.rs which gets overwritten by the avr-device Makefile. I think the intent is that the output of svd2rust should be treated as a standalone crate. Would it be possible to generate several crates and have avr-device depend on all of them, to avoid compatibility issues going forward?

Support for ATmega169*

I'm currently working on adding support for the ATmega169* mcus in my atmega169p branch.

Now I came to a problem, maybe a misunderstanding, I'm in hope you could clarify...

Shouldn't this

lcdcra.write(|w| w.lcdie().set_bit());

has the same result like

lcdcra.modify(|_, w| w.lcdie().set_bit());

???
I'm thinking of it would set the single LCDIE bit to 1 and all other bits have the same value like before.

And if not, why not, or what is the purpose of lcdcra.write_with_zero(|w| w.lcdie().set_bit()) then?
lcdcra.write(|w| w.lcdie().set_bit()) and lcdcra.write_with_zero(|w| w.lcdie().set_bit()) seems to do here the same.
It sets only the single bit and all other controlable bits to 0.
At least for this register. The LCDCRA and LCDCCR are the only ones I have a problem with the nulling so far.
Did I anything wrong in patching?
I'm checking this with the old atmega169 (out of support and so no atdf provided). I've copied and modified the atmega169p.atdf file for the changes between the two.

design question

i'm not sure but modules with same name (for example TC8_ASYNC) seems to have same features even across different boards

however, to get these generalized(i think it's done on atmega-hal tho) i'd imagine it's easier to use struct to store register address or etc
and define constant value for each mcus and boards ( also use generic consts for minor differences in modules)

this will prevent complex macro works and feature bounding
(if you impl for one struct type it will work on all boards?)

Get rid of `avr-libc` dependency

Right now we use the CRT and other bits from avr-libc. Let's rewrite it in Rust, also to support devices which avr-libc currently does not support.

ATMega328P Support

Opening another issue here for stuff specifically related to this repo

Related to: Rahix/avr-hal#2

@Rahix In your first comment on that issue you said the first place to start is working on the chip patch. I see that there is already an atmega328p patch file, but it has fewer _includes. My guess is that it's incomplete in its current form.

Luckily, the ATmega328P is very similar to the already implemented ATmega32U4. This should mean that you can for the most part copy the patches from that chip.

That sounds good... the only issue is that I don't know where to find the differences between the 32u4 and the 328p. Is that info I can find in the data sheet? Or documented elsewhere on the Microchip website? Again please pardon my extreme ignorance here.

lgt8fx

Please add support for lgt8f328p and other boards.

`critical-section` support

In attempting to integrate the avr-hal ecosystem with embedded-nal, I ran into a series of hurdles involving heapless,atomic-polyfill and critical-section.

Ultimately, if avr-device were to implement the API provided by embassy-rs/critical-section, integrating with embedded-nal and its dependencies would be greatly simplified.

Would you be open to a PR that makes the required (minor) changes to avr_device::interrupt to accomodate this? I can see two main ways to go about it:

Option 1: Add support for AVR targets to critical-section by having it depend upon avr_device when building for the AVR platform

The main missing piece here would be a public API that critical-section can use to read the GIE field of SREG. Since this register is not exposed by avr_device, we would need to surface it in some way or another (either a public method that invokes the underlying LLVM assembler, or exposing it in a way more consistent with the SVD-backed registers. This would open the possibility of migrating the avr_device::interrupt::free API to the critical_section::with API, which is equivalent in signature, but not in name.

Side note: I'm unsure on the rationale for patching SREG out of SVDs. Is it simply a matter of not wanting the exposure to be a safe API?

Option 2: Implement critical-section via its custom-impl feature, entirely in avr_device

I believe this would be less ergonomic for users who inadvertently pull in both, but could be mistaken here, as I haven't had a lot of exposure to the nuances of Cargo features & how they propagate in complex dependency graphs. The only change to the avr-device API in this case would be the net-new implementation of the trait provided by critical-section (which closely mirrors the existing interrupt API).

In either case I'm more than willing to write the patches, both to avr_device and to critical-section, but wanted to see if there was a preferred direction on your end.

Restructure Crate

I have noticed that my approach of mutably exclusive feature flags does not really work well. This is most apparent from the following code:

avr-device/src/lib.rs

Lines 40 to 66 in f77864d

#[cfg(any(
all(feature = "atmega1280", any(
feature = "atmega8",
feature = "atmega328p",
feature = "atmega32u4",
feature = "attiny85",
)),
all(feature = "atmega8", any(
feature = "atmega1280",
feature = "atmega328p",
feature = "atmega32u4",
feature = "attiny85",
)),
all(feature = "atmega328p", any(
feature = "atmega1280",
feature = "atmega8",
feature = "atmega32u4",
feature = "attiny85",
)),
all(feature = "atmega32u4", any(
feature = "atmega1280",
feature = "atmega8",
feature = "atmega329p",
feature = "attiny85",
)),
))]
compile_error!("You cannot select multiple chips at once!");

This code will explode with more and more chips being added.

Instead, I think we should restructure the crate to allow building for multiple chips at once. This will never be necessary in practice but it will make building documentation (#16) and overally ergonomics much better.

My idea is to change the current structure:

mod avr_device {
    // The selected chip
    mod atmega32u4 { }
    pub use atmega32u4::*;

    pub mod interrupt { }
}

to the following:

mod avr_device {
    // Any chip which was selected
    pub mod atmega32u4 { }
    pub mod attiny85 { }

    pub mod interrupt { }
}

For downstream usage, it would change from this:

extern crate avr_device as atmega32u4;

fn main() -> ! {
    let dp = atmega32u4::Peripherals::take().unwrap();
    loop { }
}

to this:

pub use avr_device::atmega32u4;

fn main() -> ! {
    let dp = atmega32u4::Peripherals::take().unwrap();
    loop { }
}

@jonahbron, @peacememories, @octycs: Any input?

ATxmega128A1 support

Hello,

I tried to add support for the ATxmega128A1, but the ATxmega128A1.atdf I get errors while I execute make.
e.g. size not found on <register-group name="CH0" name-in-module="DMA_CH"...
Am I missing something?

Arduino hangs when trying to read FUSE bits

When trying to read the fuse bits via dp.FUSE.low.read().bits(); (it seems like .read() may be causing the issue) the Arduino Uno halts on that line, never continuing or panicking.
It seems like this also happens when reading other fuse bits.

Is this to be expected or is this a bug? I know that the fuse bits are special however I assumed that if they are accessible in then they should also be readable, or at the very least cause a panic.

Edit: When running in release mode the program does not hang, however I've noticed that the register values aren't consistent, E.g. printing the ext register in hex will make the low registers value 0, whereas printing it as a u8 will cause the low register to be 250.

    let _val = dp.FUSE.high.read().bits();
    ufmt::uwriteln!(&mut serial, "high! {}", _val).unwrap();
    let _val = dp.FUSE.extended.read().bits();
    ufmt::uwriteln!(&mut serial, "ext! {}", _val).unwrap();
    let _val = dp.FUSE.low.read().bits();
    ufmt::uwriteln!(&mut serial, "low! {}", _val).unwrap();

Add static-mut vodoo from cortex-m-rt

cortex-m-rt has a really nice feature where static mut variables in main() and interrupts are transformed into a safe &'static mut _ reference. It would be great to add the same here.

Ideally the common code can be split out from cortex-m-rt so we can reuse it without duplication.

Add support for more devices

Hi, because I want to use avr-device and avr-hal for some projects I need more supported devices. I want to add devices, beginning with "classic" ATmegas like ATmega16 and 32, ATmega2561 and some others.

Any requirements, guidelines or suggestions before I start?

FORM step fails on `svd2rust` versions 0.18 and newer

It seems that these 2 lines (in src/devices/attiny202/mod.full.rs) are new in 0.18:

use generic :: * ; # [doc = "Common register and bit access and modify traits"]
pub mod generic ; # [doc (hidden)]

And this causes the FORM step to fail with (at signs removed to make make echo the commands):

-e 	SVD2RUST	attiny202
echo -e "\tFORM\t\tattiny202"
-e 	FORM		attiny202
RUST_LOG=WARN form -i src/devices/attiny202/mod.full.rs -o src/devices/attiny202 >/dev/null
rm src/devices/attiny202/mod.full.rs
mv src/devices/attiny202/lib.rs src/devices/attiny202/mod.rs
RUSTUP_TOOLCHAIN=nightly rustfmt src/devices/attiny202/mod.rs
Error writing files: failed to resolve mod `generic`: /home/…/avr-device/src/devices/attiny202 does not exist
make: *** [Makefile:47: src/devices/attiny202/mod.rs] Error 1

Escaping/Renaming `ASYNC` register

Trying to compile for attiny412 following error occurs, due to the naming of the ASYNC register in the TCB0 and TCD0 peripheral:

error: expected identifier, found keyword `async`
   --> src/devices/attiny412/tcb0/ctrlb.rs:248:12
    |
248 |     pub fn async(&self) -> ASYNC_R {
    |            ^^^^^ expected identifier, found keyword
    |
help: you can escape reserved keywords to use them as identifiers
    |
248 |     pub fn r#async(&self) -> ASYNC_R {
    |            ^^^^^^^

error: expected identifier, found keyword `async`
   --> src/devices/attiny412/tcb0/ctrlb.rs:270:12
    |
270 |     pub fn async(&mut self) -> ASYNC_W {
    |            ^^^^^ expected identifier, found keyword
    |
help: you can escape reserved keywords to use them as identifiers
    |
270 |     pub fn r#async(&mut self) -> ASYNC_W {
    |            ^^^^^^^

error: expected identifier, found keyword `async`
   --> src/devices/attiny412/tcd0/evctrla.rs:256:12
    |
256 |     pub fn async(self) -> &'a mut W {
    |            ^^^^^ expected identifier, found keyword
    |
help: you can escape reserved keywords to use them as identifiers
    |
256 |     pub fn r#async(self) -> &'a mut W {
    |            ^^^^^^^

error: expected identifier, found keyword `async`
   --> src/devices/attiny412/tcd0/evctrlb.rs:256:12
    |
256 |     pub fn async(self) -> &'a mut W {
    |            ^^^^^ expected identifier, found keyword
    |
help: you can escape reserved keywords to use them as identifiers
    |
256 |     pub fn r#async(self) -> &'a mut W {
    |            ^^^^^^^

Not sure if this should be fixed in atdf2svd by renaming ASYNC registers, or here.

docs.rs build broken for 0.3.3

See https://docs.rs/crate/avr-device/0.3.3/builds/556355.

I suspect we finally hit the memory limit. When building locally, rustc memory usage spikes up to over 4GiB so this seems very likely...

What should we do? I have a few ideas:

  1. Only build docs with a select number of chips enabled. I guess we could just choose the most used AVR microcontrollers and only provide online docs for those. For other chips people can build documentation locally using
    cargo doc --features atmega328p --open
  2. Find out why memory usage is so high? I'm not sure if there is anything we can do about it short of changing the codegen in svd2rust...
  3. Ask the docs.rs team to increase the limits. Honestly, I am not a fan of this because the solution doesn't scale when more chips get added in the future...

Possible rust compilation issue ?

Hi,

I'm posting here first because I have an unexpected result on some code I wrote. It looks like a compiler issue but as I'm learning Rust, maybe it's just me doing dumb things :D. Could you please tell me is this is a misusage on my end before I raise the issue upstream ?

The code is here.

Basically, it consists of a RefCell that is written in an interrupt, and read on the main loop. The initial value is 0, and set to > 0 on the interrup. The main loop turns on the LED if the value is >0. So it starts off and then turns on.

(sorry for the rather strange code; I started removing logic to make a minimum MVP)

However, when there is no code on the else branch, the LED never turns on. If we put some code (like a nop, or something else) then it works as expected.

For the sake of simplicity, I created two examples:

  • GOOD, with a nop in the else branch -> LED turns on.
  • BAD with nothing on the else branch -> LED stays off.

I tried to debug the compilation, and I see that:

MIR

The runtime optimized after MIR (006.000) looks okay on both cases:

GOOD:

    bb14: {
        StorageLive(_25);
        StorageLive(_26);
        StorageLive(_27);
        _27 = const {alloc1: *mut RefCell<u8>};
        _26 = &mut (*_27);
        _25 = RefCell::<u8>::get_mut(move _26) -> [return: bb15, unwind unreachable];
    }

    bb15: {
        StorageDead(_26);
        _24 = (*_25);
        StorageDead(_27);
        StorageDead(_25);
        StorageLive(_28);
        _28 = Gt(_24, const 0_u8);
        switchInt(move _28) -> [0: bb19, otherwise: bb16];
    }

    bb16: {
        StorageLive(_30);
        StorageLive(_31);
        StorageLive(_32);
        _32 = &(_1.9: avr_device::atmega328p::PORTD);
        _31 = <PORTD as Deref>::deref(move _32) -> [return: bb17, unwind unreachable];
    }

    bb17: {
        StorageDead(_32);
        _30 = &((*_31).2: avr_device::generic::Reg<avr_device::atmega328p::portd::portd::PORTD_SPEC>);
        _29 = Reg::<PORTD_SPEC>::modify::<[closure@src/main.rs:58:35: 58:41]>(move _30, const ZeroSized: [closure@src/main.rs:58:35: 58:41]) -> [return: bb18, unwind unreachable];
    }

    bb18: {
        StorageDead(_30);
        StorageDead(_31);
        goto -> bb20;
    }

    bb19: {
        asm!("444444:", options((empty))) -> [return: bb20, unwind unreachable];
    }

    bb20: {
        StorageDead(_28);
        goto -> bb14;
    }

BAD:

   bb14: {
        StorageLive(_25);
        StorageLive(_26);
        StorageLive(_27);
        _27 = const {alloc1: *mut RefCell<u8>};
        _26 = &mut (*_27);
        _25 = RefCell::<u8>::get_mut(move _26) -> [return: bb15, unwind unreachable];
    }

    bb15: {
        StorageDead(_26);
        _24 = (*_25);
        StorageDead(_27);
        StorageDead(_25);
        StorageLive(_28);
        _28 = Gt(_24, const 0_u8);
        switchInt(move _28) -> [0: bb19, otherwise: bb16];
    }

    bb16: {
        StorageLive(_30);
        StorageLive(_31);
        StorageLive(_32);
        _32 = &(_1.9: avr_device::atmega328p::PORTD);
        _31 = <PORTD as Deref>::deref(move _32) -> [return: bb17, unwind unreachable];
    }

    bb17: {
        StorageDead(_32);
        _30 = &((*_31).2: avr_device::generic::Reg<avr_device::atmega328p::portd::portd::PORTD_SPEC>);
        _29 = Reg::<PORTD_SPEC>::modify::<[closure@src/main.rs:58:35: 58:41]>(move _30, const ZeroSized: [closure@src/main.rs:58:35: 58:41]) -> [return: bb18, unwind unreachable];
    }

    bb18: {
        StorageDead(_30);
        StorageDead(_31);
        goto -> bb19;
    }

    bb19: {
        StorageDead(_28);
        goto -> bb14;
    }

Basically, the diff is in bb18/bb19

LLVM-IR:

GOOD:

  br label %bb14, !dbg !3347
bb14:                                             ; preds = %bb19, %bb16, %"_ZN4core6option15Option$LT$T$GT$6unwrap17h450249f892692cf5E.exit"
  %wait_qty = load i8, ptr @_ZN12mega328_test3CTR17hd094fa9ca712b679E.0, align 1, !dbg !3349, !noundef !358
  call addrspace(1) void @llvm.dbg.value(metadata i8 %wait_qty, metadata !2947, metadata !DIExpression()), !dbg !3350
  %_28.not = icmp eq i8 %wait_qty, 0, !dbg !3351
  br i1 %_28.not, label %bb19, label %bb16, !dbg !3351

BAD:

  %wait_qty.pre1 = load i8, ptr @_ZN12mega328_test3CTR17hd094fa9ca712b679E.0, align 1, !dbg !3349
  br label %bb14, !dbg !3347

bb14:                                             ; preds = %bb14, %bb16, %"_ZN4core6option15Option$LT$T$GT$6unwrap17h450249f892692cf5E.exit"
  %wait_qty = phi i8 [ %wait_qty.pre1, %"_ZN4core6option15Option$LT$T$GT$6unwrap17h450249f892692cf5E.exit" ], [ %wait_qty.pre, %bb16 ], [ 0, %bb14 ], !dbg !3349
  call addrspace(1) void @llvm.dbg.value(metadata i8 %wait_qty, metadata !2947, metadata !DIExpression()), !dbg !3350
  %_28.not = icmp eq i8 %wait_qty, 0, !dbg !3351
  br i1 %_28.not, label %bb14, label %bb16, !dbg !3351

I don't really know LLVM, but the phi i8 that uses [0, %bb14] looks strange to me, making the condition after always true ?

Assembly

BAD:

    loop {
        let wait_qty: u8;
        unsafe { wait_qty = *CTR.get_mut(); };
  24:   80 91 00 00     lds     r24, 0x0000     ; 0x800000 <__SREG__+0x7fffc1>

        if wait_qty > 0 {
  28:   80 30           cpi     r24, 0x00       ; 0
  2a:   81 2d           mov     r24, r1
  2c:   01 f0           breq    .+0             ; 0x2e <_ZN12mega328_test20__avr_device_rt_main17h8ca9fc0fd7a09522E+0x2e>
  2e:   5a 9a           sbi     0x0b, 2 ; 11
  30:   00 c0           rjmp    .+0             ; 0x32 <_ZN12mega328_test20__avr_device_rt_main17h8ca9fc0fd7a09522E+0x32>

To be honest I don't really understand instruction 24; why would it try to load from 0x0000 ?

What do you think ?

Many thanks for your help !

Publish on Crates.io

Are there plans to publish each chip as packages to Crates.io? Or are we waiting until the project is more stable?

ATmega4809 support

Looks like I need to spend more time on this chip. Require probably same changes as in #26 (comment)

@Rahix can you please advice which topic in atdf2svd I should progress

Warning: Unhandled register node: "<register-group name=\"SINGLE\" offset=\"0\" name-in-module=\"TCA_SINGLE\" union-tag-value=\"0\" ...>"
Warning: Unhandled register node: "<register-group name-in-module=\"TCA_SPLIT\" name=\"SPLIT\" offset=\"0\" union-tag-value=\"1\" ...>"
Error: Register "DIR" has a weird name!
Error: Register "DIRCLR" has a weird name!
Error: Register "DIRSET" has a weird name!
Error: Register "DIRTGL" has a weird name!
Error: Register "IN" has a weird name!
Error: Register "INTFLAGS" has a weird name!
Error: Register "OUT" has a weird name!
Error: Register "OUTCLR" has a weird name!
Error: Register "OUTSET" has a weird name!
Error: Register "OUTTGL" has a weird name!
Error: Register "PIN0CTRL" has a weird name!
Error: Register "PIN1CTRL" has a weird name!
Error: Register "PIN2CTRL" has a weird name!
Error: Register "PIN3CTRL" has a weird name!
Error: Register "PIN4CTRL" has a weird name!
Error: Register "PIN5CTRL" has a weird name!
Error: Register "PIN6CTRL" has a weird name!
Error: Register "PIN7CTRL" has a weird name!
Error: Register "PORTCTRL" has a weird name!
Error: Register "DIR" has a weird name!
Error: Register "DIRCLR" has a weird name!
Error: Register "DIRSET" has a weird name!
Error: Register "DIRTGL" has a weird name!
Error: Register "IN" has a weird name!
Error: Register "INTFLAGS" has a weird name!
Error: Register "OUT" has a weird name!
Error: Register "OUTCLR" has a weird name!
Error: Register "OUTSET" has a weird name!
Error: Register "OUTTGL" has a weird name!
Error: Register "PIN0CTRL" has a weird name!
Error: Register "PIN1CTRL" has a weird name!
Error: Register "PIN2CTRL" has a weird name!
Error: Register "PIN3CTRL" has a weird name!
Error: Register "PIN4CTRL" has a weird name!
Error: Register "PIN5CTRL" has a weird name!
Error: Register "PIN6CTRL" has a weird name!
Error: Register "PIN7CTRL" has a weird name!
Error: Register "PORTCTRL" has a weird name!
Error: Register "DIR" has a weird name!
Error: Register "DIRCLR" has a weird name!
Error: Register "DIRSET" has a weird name!
Error: Register "DIRTGL" has a weird name!
Error: Register "IN" has a weird name!
Error: Register "INTFLAGS" has a weird name!
Error: Register "OUT" has a weird name!
Error: Register "OUTCLR" has a weird name!
Error: Register "OUTSET" has a weird name!
Error: Register "OUTTGL" has a weird name!
Error: Register "PIN0CTRL" has a weird name!
Error: Register "PIN1CTRL" has a weird name!
Error: Register "PIN2CTRL" has a weird name!
Error: Register "PIN3CTRL" has a weird name!
Error: Register "PIN4CTRL" has a weird name!
Error: Register "PIN5CTRL" has a weird name!
Error: Register "PIN6CTRL" has a weird name!
Error: Register "PIN7CTRL" has a weird name!
Error: Register "PORTCTRL" has a weird name!
Error: Register "DIR" has a weird name!
Error: Register "DIRCLR" has a weird name!
Error: Register "DIRSET" has a weird name!
Error: Register "DIRTGL" has a weird name!
Error: Register "IN" has a weird name!
Error: Register "INTFLAGS" has a weird name!
Error: Register "OUT" has a weird name!
Error: Register "OUTCLR" has a weird name!
Error: Register "OUTSET" has a weird name!
Error: Register "OUTTGL" has a weird name!
Error: Register "PIN0CTRL" has a weird name!
Error: Register "PIN1CTRL" has a weird name!
Error: Register "PIN2CTRL" has a weird name!
Error: Register "PIN3CTRL" has a weird name!
Error: Register "PIN4CTRL" has a weird name!
Error: Register "PIN5CTRL" has a weird name!
Error: Register "PIN6CTRL" has a weird name!
Error: Register "PIN7CTRL" has a weird name!
Error: Register "PORTCTRL" has a weird name!
Error: Register "DIR" has a weird name!
Error: Register "DIRCLR" has a weird name!
Error: Register "DIRSET" has a weird name!
Error: Register "DIRTGL" has a weird name!
Error: Register "IN" has a weird name!
Error: Register "INTFLAGS" has a weird name!
Error: Register "OUT" has a weird name!
Error: Register "OUTCLR" has a weird name!
Error: Register "OUTSET" has a weird name!
Error: Register "OUTTGL" has a weird name!
Error: Register "PIN0CTRL" has a weird name!
Error: Register "PIN1CTRL" has a weird name!
Error: Register "PIN2CTRL" has a weird name!
Error: Register "PIN3CTRL" has a weird name!
Error: Register "PIN4CTRL" has a weird name!
Error: Register "PIN5CTRL" has a weird name!
Error: Register "PIN6CTRL" has a weird name!
Error: Register "PIN7CTRL" has a weird name!
Error: Register "PORTCTRL" has a weird name!
Error: Register "DIR" has a weird name!
Error: Register "DIRCLR" has a weird name!
Error: Register "DIRSET" has a weird name!
Error: Register "DIRTGL" has a weird name!
Error: Register "IN" has a weird name!
Error: Register "INTFLAGS" has a weird name!
Error: Register "OUT" has a weird name!
Error: Register "OUTCLR" has a weird name!
Error: Register "OUTSET" has a weird name!
Error: Register "OUTTGL" has a weird name!
Error: Register "PIN0CTRL" has a weird name!
Error: Register "PIN1CTRL" has a weird name!
Error: Register "PIN2CTRL" has a weird name!
Error: Register "PIN3CTRL" has a weird name!
Error: Register "PIN4CTRL" has a weird name!
Error: Register "PIN5CTRL" has a weird name!
Error: Register "PIN6CTRL" has a weird name!
Error: Register "PIN7CTRL" has a weird name!
Error: Register "PORTCTRL" has a weird name!
Warning: Could not apply 'signals_to_port_fields' patch!
Warning: Description missing for peripheral "AC0"
Warning: Description missing for peripheral "ADC0"
Warning: Description missing for peripheral "BOD"
Warning: Description missing for peripheral "CCL"
Warning: Description missing for peripheral "CLKCTRL"
Warning: Description missing for peripheral "CPU"
Warning: Description missing for peripheral "CPUINT"
Warning: Description missing for peripheral "CRCSCAN"
Warning: Description missing for peripheral "EVSYS"
Warning: Description missing for peripheral "FUSE"
Warning: Description missing for peripheral "GPIO"
Warning: Description missing for peripheral "LOCKBIT"
Warning: Description missing for peripheral "NVMCTRL"
Warning: Description missing for peripheral "PORTA"
Warning: Description missing for peripheral "PORTB"
Warning: Description missing for peripheral "PORTC"
Warning: Description missing for peripheral "PORTD"
Warning: Description missing for peripheral "PORTE"
Warning: Description missing for peripheral "PORTF"
Warning: Description missing for peripheral "PORTMUX"
Warning: Description missing for peripheral "RSTCTRL"
Warning: Description missing for peripheral "RTC"
Warning: Description missing for peripheral "SIGROW"
Warning: Description missing for peripheral "SLPCTRL"
Warning: Description missing for peripheral "SPI0"
Warning: Description missing for peripheral "SYSCFG"
Warning: No registers found for peripheral "TCA0"
Warning: Description missing for peripheral "TCB0"
Warning: Description missing for peripheral "TCB1"
Warning: Description missing for peripheral "TCB2"
Warning: Description missing for peripheral "TCB3"
Warning: Description missing for peripheral "TWI0"
Warning: Description missing for peripheral "USART0"
Warning: Description missing for peripheral "USART1"
Warning: Description missing for peripheral "USART2"
Warning: Description missing for peripheral "USART3"
Warning: Description missing for peripheral "USERROW"
Warning: Description missing for peripheral "VPORTA"
Warning: Description missing for peripheral "VPORTB"
Warning: Description missing for peripheral "VPORTC"
Warning: Description missing for peripheral "VPORTD"
Warning: Description missing for peripheral "VPORTE"
Warning: Description missing for peripheral "VPORTF"
Warning: Description missing for peripheral "VREF"
Warning: Description missing for peripheral "WDT"
Warning: Description missing for field "NMI"
Warning: Description missing for field "VLM"
Warning: Description missing for field "CNT"
Warning: Description missing for field "PIT"
Warning: Description missing for field "CCL"
Warning: Description missing for field "LUNF"
Warning: Description missing for field "OVF"
Warning: Description missing for field "HUNF"
Warning: Description missing for field "CMP0"
Warning: Description missing for field "LCMP0"
Warning: Description missing for field "CMP1"
Warning: Description missing for field "LCMP1"
Warning: Description missing for field "CMP2"
Warning: Description missing for field "LCMP2"
Warning: Description missing for field "TWIS"
Warning: Description missing for field "TWIM"
Warning: Description missing for field "AC"
Warning: Description missing for field "RESRDY"
Warning: Description missing for field "WCOMP"
Warning: Description missing for field "EE"
Warning: Description missing for field "PORT"
Warning: Description missing for field "INT"
Warning: Description missing for field "RXC"
Warning: Description missing for field "DRE"
Warning: Description missing for field "TXC"

Documentation Generation

The way this crate works, with chips selected using feature flags, docs.rs will not display any useful documentation. There needs to be a way to generate documentation for this crate in a way that contains all chips at once.

attiny412 support

Hi
I would like to have support for the attiny412. As it is a MCU of the new AVR-1 series, will it work with your tool?

Also am I understanding correctly, that this crate is providing something similar to the "PAC" crates for the different cortex-m MCUs?

Best,
trembel

Sed -i does not work as expected in MacOS

MacOS uses a different version of sed than GNU sed by default, which results in the rather cryptic error unterminated substitute in regular expression when running make in this repo. This is because MacOS sed requires a "backup extension" when using -i, for example -i '' for none. This is of course not supported by GNU sed...^^'

What should we do about this? We could instruct MacOS users to install gsed and use it in place of their normal sed, but this might break other tools that depend on the different behaviour. We could also use perl, awk or a different tool for the few replacements we have.

Release 0.2.3

I think it's time to release 0.2.3 because we have some fixes of register bitfields and other updates.
Thanks

Startup

Right now, the startup is not as pretty as I would like it to be. Ideally, we should add a #[entry] procedural macro as cortex-m did.

Target Specifications

Somewhere in the crate-hierarchy, we need to add the target-specifications for the specific avr mcus. I propose adding them here in avr-device and in case a board needs a modified version, it can add its own as well.

sed - expected context address on macOS

Hi, I've got another "this only works with gnu-sed" situation.
The issue is on this line:

@sed -i'' -e '/^\#\[allow(renamed_and_removed_lints)\]/,+3cuse crate::devices::DEVICE_PERIPHERALS;' $@

,+3c is a gnu-sed specific command, partially explained here, i guess? https://stackoverflow.com/questions/26124650/sed-use-expected-context-address

To be quite honest I don't know what the c does so I'm not sure how to change this so it works on any sed. Maybe it's worth thinking about replacing the sed calls with awk calls altogether since awk seems to work the same on different posix systems.

Interrupts

Right now, there is no support for defining interrupts. As mentioned in Rahix/atmega32u4#2, the new interrupts should look similar to what cortex-m is doing. This means adding another crate for a procedural macro.

Investigate crate-size optimizations

Right now we're calling form and rustfmt to split out the auto-generated modules into many files. I don't think this provides much value as nobody is going to look at those file anyway.

I have a suspicion that we could reduce the crate (download) size a bit by not calling form. For rustfmt on the other hand I am completely unsure whether it helps or not. svd2rust does generate a lot of unnecessary whitespace but I do not know whether rustfmt generates more or less (due to indentation). A rust minifier would of course be the best solution here ;)

16-bit register writes in wrong order

I'm working with an Attiny404 and was setting up PWM which requires writing to 16bit registers.

I was getting unexpected results when setting the PER and CMP1 registers (both 16bit).

I had code that looked like this.

dp.TCA0.per().write(|w| w.bits(400));
dp.TCA0.cmp1().write(|w| w.bits(100));

The PWM frequency would do really weird things. However, if I duplicate each line twice it worked as expected.

dp.TCA0.per().write(|w| w.bits(400));
dp.TCA0.per().write(|w| w.bits(400));
dp.TCA0.cmp1().write(|w| w.bits(100));
dp.TCA0.cmp1().write(|w| w.bits(100));

I believe this is because the AVR requires you to write the upper register before writing the lower register. See https://ww1.microchip.com/downloads/en/Appnotes/doc1493.pdf

The opposite is true for reads (read low then high) so I assume reads are working.

This is my first into to Rust so I'm not exactly sure where to dive in to propose a fix for this. This may even be considered a compiler issue.

EDIT: Doing some experimenting it looks like the Attiny404 requires the low register to be written first. The same is true for reads. This is true for the new 0/1 series AVRs while the older "classic" mega and tiny required writes to be flipped.
https://microchip.my.site.com/s/article/Accessing-16-bit-registers-in-8-bit-AVR-devices

unmatched visibility `pub`

When running cargo +nightly-2019-05-12-x86_64-apple-darwin doc --features atmega328p --open i get the following error:

error: unmatched visibility `pub`
   --> src/devices/atmega328p/mod.rs:329:10
    |
329 | pub(crate) 0: bool = false;
    |          ^

Need write access to PRR register in atmega328p

The vendor provided svd for atmega328p lists the PRR register as read only. The access needs to be read/write so that the peripherals can be powered down.

I will create a pull request to fix this issue, however it is not ready to go yet. I am getting an error in the build when i try to use it, and am not experienced enough in rust to decipher it yet.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.