Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Arduino hangs when trying to read FUSE bits #129

Open
Ayrdim opened this issue May 24, 2023 · 3 comments
Open

Arduino hangs when trying to read FUSE bits #129

Ayrdim opened this issue May 24, 2023 · 3 comments

Comments

@Ayrdim
Copy link

Ayrdim commented May 24, 2023

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();
@Rahix Rahix added the bug Something isn't working label May 31, 2023
@Rahix
Copy link
Owner

Rahix commented Jun 1, 2023

Hi,

can you run a quick test whether other registers behave differently? I have a feeling this might be an issue on compiler side...

@Ayrdim
Copy link
Author

Ayrdim commented Jun 1, 2023

Sure can! Everything seems to work fine when playing around with the interrupt registers:

    dp.TC0.tccr0a.write(|w| w.wgm0().ctc());
    dp.TC0.tccr0b.write(|w| w.cs0().prescale_1024());
    dp.TC0.ocr0a.write(|w| w.bits(255));
    dp.TC0.timsk0.write(|w| w.ocie0a().set_bit());

    let _val = dp.TC0.tccr0a.read().bits();
    ufmt::uwriteln!(&mut serial, "tccr0a.bits() {}", _val).unwrap();
    let _val = dp.TC0.tccr0b.read().bits();
    ufmt::uwriteln!(&mut serial, "tccr0b.bits() {}", _val).unwrap();
    let _val = dp.TC0.ocr0a.read().bits();
    ufmt::uwriteln!(&mut serial, "ocr0a.bits() {}", _val).unwrap();
    let _val = dp.TC0.timsk0.read().bits();
    ufmt::uwriteln!(&mut serial, "timsk0.bits() {}", _val).unwrap();

This will output the following:

tccr0a.bits() 2
tccr0b.bits() 5
ocr0a.bits() 255
timsk0.bits() 2

Appreciate the help!

@Patryk27
Copy link
Contributor

Patryk27 commented Oct 11, 2023

Depending on your uC, reading fuse bits might require extra trickery - e.g. datasheet for atmega328p says:

25.2.2 Reading the Fuse and Lock Bits from Software:
It is possible to read both the fuse and lock bits from software. To read the lock bits, load the Z-pointer with 0x0001 and set the BLBSET and SELFPRGEN bits in SPMCSR. When an LPM instruction is executed within three CPU cycles after the BLBSET and SELFPRGEN bits are set in SPMCSR, the value of the Lock bits will be loaded in the destination register. The BLBSET and SELFPRGEN bits will auto-clear upon completion of reading the lock bits or if no LPM instruction is executed within three CPU cycles or no SPM instruction is executed within four CPU cycles. When BLBSET and SELFPRGEN are cleared, LPM will work as described in the Instruction set manual.

@Rahix Rahix removed the bug Something isn't working label Nov 17, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants