avrdudes / avrdude

AVRDUDE is a utility to program AVR microcontrollers
GNU General Public License v2.0
723 stars 137 forks source link

Fuses and lock bits with unused bits can show spurious write errors #1371

Closed stefanrueger closed 1 year ago

stefanrueger commented 1 year ago

Fuses and lock bits with unused bits can show spurious write errors when writing 0 in the unused bits. Happens both with -U and the terminal, for example, try writing 7 to the efuse of an ATmega2560:

$ avrdude -qqc usbtiny -pm2560 -Uef:w:7:m
 ***failed;
avrdude warning: ignoring mismatch in unused bits of ef
        (device 0xff != input 0x07); to prevent this warning set
        unused bits to 1 when writing (double check with datasheet)

$ echo "w ef 7" | avrdude -qqc usbtiny -pm2560 -t
avrdude> w ef 7
avrdude error: (write) error writing 0x07 at 0x00000, rc=-6

The conciliatory ignoring-mismatch message only happens for classic ISP parts; I predict for modern parts this will be a real error. If you want to test, in modern AVR8X parts unused bits occur in

and in the XMEGAS unused bits are in

Suggested solution: Record bitmask for fuses and lock bits in avrdude.conf and then either of

I prefer the first just in case AVRDUDE gets the bitmask wrong and in case the odd data sheet requires an unused bit to be 0. (Do we want to read all data sheets to know for sure? Probably not)

mcuee commented 1 year ago

@stefanrueger

Just tried on ATtiny817 and it does not seem to throw errors for fuse6.

PS C:\work\avr\avrdude_test\avrdude_bin> .\avrdude -c xplainedpro_updi -p t817 -qqt
avrdude warning: USB device with VID: 0x03eb and PID: 0x2111 not found
avrdude> dump fuses
0000  00 40 01 ff 00 c4 07 00  02                       |.@.......       |
avrdude> write fuse6 06
avrdude> flush
avrdude> dump fuses
0000  00 40 01 ff 00 c4 06 00  02                       |.@.......       |
avrdude> write fuse6 0x0f
avrdude> flush
avrdude> dump fuses
0000  00 40 01 ff 00 c4 0f 00  02                       |.@.......       |
avrdude> write fuse6 0xf7
avrdude> flush
avrdude> dump fuses
0000  00 40 01 ff 00 c4 f7 00  02                       |.@.......       |
avrdude> quit

PS C:\work\avr\avrdude_test\avrdude_bin> .\avrdude -c xplainedpro_updi -p t817 -qqt
avrdude warning: USB device with VID: 0x03eb and PID: 0x2111 not found
avrdude> dump fuses
0000  00 40 01 ff 00 c4 f7 00  02                       |.@.......       |
avrdude> quit

Screenshot 2023-05-29 214148

mcuee commented 1 year ago

Same for fuse2 and fuse5.

PS C:\work\avr\avrdude_test\avrdude_bin> .\avrdude -c xplainedpro_updi -p t817 -qqt
avrdude warning: USB device with VID: 0x03eb and PID: 0x2111 not found
avrdude> dump fuses
0000  00 40 01 ff 00 c4 f7 00  02                       |.@.......       |
avrdude> write fuse2 0b00101001
avrdude> flush
avrdude> dump fuses
0000  00 40 29 ff 00 c4 f7 00  02                       |.@)......       |
avrdude> write fuse5 0b11010111
avrdude> flush
avrdude> dump fuses
0000  00 40 29 ff 00 d7 f7 00  02                       |.@)......       |
avrdude> quit
PS C:\work\avr\avrdude_test\avrdude_bin> .\avrdude -c xplainedpro_updi -p t817 -qqt
avrdude warning: USB device with VID: 0x03eb and PID: 0x2111 not found
avrdude> dump fuses
0000  00 40 29 ff 00 d7 f7 00  02                       |.@)......       |
avrdude> quit

Screenshot 2023-05-29 215049

Screenshot 2023-05-29 215133

stefanrueger commented 1 year ago

Apparently the default for unused bits is 0 in these. So what happens when you set unused bits? Do you get errors?

mcuee commented 1 year ago

Apparently the default for unused bits is 0 in these. So what happens when you set unused bits? Do you get errors?

@stefanrueger

In the above-mentioned test, I have tested both cases and no errors.

stefanrueger commented 1 year ago

both cases and no errors

Aha. This means that the unused fuse bits act as extra memory. So no verification error. Is that generally true for AVRX8 parts? And what about XMEGA?

mcuee commented 1 year ago

both cases and no errors

Aha. This means that the unused fuse bits act as extra memory. So no verification error. Is that generally true for AVRX8 parts? And what about XMEGA?

I wil test an xmega part tomorrow. I tend to think it is the same case.

stefanrueger commented 1 year ago

Given feedback from @mcuee's tests PR #1372 suggests

mcuee commented 1 year ago

I wil test an xmega part tomorrow. I tend to think it is the same case.

@stefanrueger

Here are the test results for ATxmega32A4U and it is not that consistent. The reserved bits will read as 1 and changing the rserved bits to zero is successful for fuse2 and fuse5, but failed on fuse5. I use avrdude git main for this test.

PS C:\work\avr\avrdude_test\avrdude_bin> .\avrdude -c avrispmkii -p x32a4u -qqt
avrdude> dump fuse2
0000  bf                                                |.               |
avrdude> dump fuse4
0000  fe                                                |.               |
avrdude> dump fuse5
0000  ff                                                |.               |
avrdude> write fuse2 0b01100011
avrdude> write fuse4 0b00011110
avrdude error: (write) verification error writing 0x1e at 0x00000 cell=0xfe
avrdude> write fuse5 0b00111111
avrdude> dump fuse2
0000  63                                                |c               |
avrdude> dump fuse4
0000  fe                                                |.               |
avrdude> dump fuse5
0000  3f                                                |?               |
avrdude> quit

The user manual does say the following about the reserved bit. "These bits are unused and reserved for future use. For compatibility with future devices, always write these bits to one when this register is written."

WIth this sentence in the user manual, I think it is safe to extend PR #1372 bitmasks fix to xmega parts as well.

https://ww1.microchip.com/downloads/en/DeviceDoc/Atmel-8331-8-and-16-bit-AVR-Microcontroller-XMEGA-AU_Manual.pdf

mcuee commented 1 year ago

And for ATmega2560, I can reproduce the issue using git main.

PS C:\work\avr\avrdude_test\avrdude_bin> .\avrdude -c usbasp -p m2560 -qqt
avrdude> dump lfuse
0000  f7                                                |.               |
avrdude> dump hfuse
0000  d6                                                |.               |
avrdude> dump efuse
0000  fd                                                |.               |
avrdude> write efuse 0b00000110
avrdude error: (write) error writing 0x06 at 0x00000, rc=-6
avrdude> quit

And indeed PR #1372 is good.

PS C:\work\avr\avrdude_test\avrdude_bin> .\avrdude_pr1372 -C .\avrdude_pr1372.conf -c usbasp -p m2560 -qqt
avrdude> dump efuse
0000  fe                                                |.               |
avrdude> write efuse 0b00000110
avrdude> dump efuse
0000  fe                                                |.               |
avrdude> quit
mcuee commented 1 year ago

Tested anothe moder AVR part AVR128DB48 and its behavior is the same as ATtiny817.

PS C:\work\avr\avrdude_test\avrdude_bin> .\avrdude -c pkobn_updi -p avr128db48 -qqt
avrdude> dump fuses
0000  00 00 00 ff ff c8 0c 00  01                       |...... ..       |
avrdude> write fuse2 0b01111110
avrdude> dump fuse2
0000  7e                                                |~               |
avrdude> write fuse2 00
avrdude>
avrdude> dump fuse2
0000  00                                                |.               |
avrdude> write fuse6 0b11110100
avrdude> dump fuse6
0000  f4                                                |.               |
avrdude> write fuse6 0x0c
avrdude> write fuse5 0b11111010
avrdude> dump fuse5
0000  fa                                                |.               |
avrdude> write fuse5 0xc8
avrdude> dump fuses
0000  00 00 00 ff ff c8 0c 00  01                       |...... ..       |
avrdude> quit
mcuee commented 1 year ago

@stefanrueger

This is my take based on my tests and reading of datasheets.

Given feedback from @mcuee's tests PR #1372 suggests

  • Initialising the unused bits in fuses/lock bits in classic parts only

I think it is good to extend this change to xmega parts as well.

  • With the factory default initval from avrdude.conf
  • If that does not exist read-modify-write using the bits on the device

I think these two are good.