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

Provide cached byte-wise read/write API #1106

Merged
merged 6 commits into from
Oct 5, 2022

Conversation

stefanrueger
Copy link
Collaborator

@stefanrueger stefanrueger commented Oct 2, 2022

Supposed to alleviate Issue #1020.

Provides an API for cached byte-wise access

  • int avr_read_byte_cached(const PROGRAMMER *pgm, const AVRPART *p, const AVRMEM *mem, unsigned long addr, unsigned char *value);
  • int avr_write_byte_cached(const PROGRAMMER *pgm, const AVRPART *p, const AVRMEM *mem, unsigned long addr, unsigned char data);
  • int avr_flush_cache(const PROGRAMMER *pgm, const AVRPART *p);

avr_read_byte_cached()

  • Uses a cache if paged routines available and if memory is EEPROM or flash
  • Otherwise fall back to pgm->read_byte()
  • Out of memory addr: writes the current (page) cache and pretends reading a 0 correctly
  • Out of cache addr: writes the current (page) cache, then reads cache page for addr, and reads the correct byte
  • Cache is automagically created and initialised if needed

avr_write_byte_cached()

  • Uses a cache if paged routines available and if memory is EEPROM or flash
  • Otherwise fall back to pgm->write_byte()
  • Out of memory addr: write current (page) cache and pretend writing correctly
  • Out of cache addr: write current (page) Cache, then fills cache to write to addr
  • Cache is automagically created and initialised if needed

avr_flush_cache()

  • User should call this at the end to finally write all caches to device and free them

The terminal calls pgm->read_byte_cached(), pgm->read_write_cached() and pgm->flush_cache(); these are initialised with avr_read_byte_cached(), avr_write_byte_cached() and avr_flush_cache(). This indirection is useful b/c this cache is implemented with vvv generic paged load/write calls; individual programmers might have a much slicker cache and can overload correspondingly.

Writing the current cache page is a bit tricky. Normally one can use a small cache and write to the device using paged write for those pages that were changed. However, some memories look like NOR memories, ie, they can only write 0 bits, not 1 bits. When this is detected, either page erase is deployed (typically PDI/UPDI parts only), or if that is not available, both EEPROM and flash caches are expanded to cover the full device. This takes some time, of course. When finally at the end the cache is synchronised to the device, again, this takes some time, as a full chip erase is needed followed by writing back both EEPROM and flash memories.

Give it a spin!

Here my simple test (note the time taken for changing the character H to h in flash):

$ echo 'read flash 0x3100 16' | avrdude -qqp m328p -c usbtiny -t
avrdude> read flash 0x3100 16
3100  ff ff ff ff ff ff ff ff  ff ff ff ff ff ff ff ff  |................|

$ echo 'write flash 0x3100 "hello, world\n"' | avrdude -qqp m328p -c usbtiny -t
avrdude> write flash 0x3100 "hello, world\n"
avrdude>

$ echo 'read flash 0x3100 16' | avrdude -qqp m328p -c usbtiny -t
avrdude> read flash 0x3100 16
3100  68 65 6c 6c 6f 2c 20 77  6f 72 6c 64 0a 00 ff ff  |hello, world ...|

$ echo 'write flash 0x3100 "Hello, world\n"' | avrdude -qqp m328p -c usbtiny -t
avrdude> write flash 0x3100 "Hello, world\n"
avrdude>

$ echo 'read flash 0x3100 16' | avrdude -qqp m328p -c usbtiny -t
avrdude> read flash 0x3100 16
3100  48 65 6c 6c 6f 2c 20 77  6f 72 6c 64 0a 00 ff ff  |Hello, world ...|

$ echo 'write flash 0x3100 "hello, world\n"' | avrdude -qqp m328p -c usbtiny -t
avrdude> write flash 0x3100 "hello, world\n"
avrdude> avrdude: expanding cache to all flash and EEPROM (takes time)...
avrdude: erasing chip and writing caches to all flash and EEPROM (takes time)...

$ echo  'read flash 0x3100 16' | avrdude -qqp m328p -c usbtiny -t
avrdude> read flash 0x3100 16
3100  68 65 6c 6c 6f 2c 20 77  6f 72 6c 64 0a 00 ff ff  |hello, world ...|

 - int avr_read_byte_cached(const PROGRAMMER *pgm, const AVRPART *p, const AVRMEM *mem, unsigned long addr, unsigned char *value);
 - int avr_write_byte_cached(const PROGRAMMER *pgm, const AVRPART *p, const AVRMEM *mem, unsigned long addr, unsigned char data);
 - int avr_flush_cache(const PROGRAMMER *pgm, const AVRPART *p);

avr_read_byte_cached()
  - Uses a cache if paged routines available and if memory is EEPROM or flash
  - Otherwise fall back to pgm->read_byte()
  - Out of memory addr: writes the current (page) cache and pretends reading a 0 correctly
  - Out of cache addr: writes the current (page) cache, then reads cache page for addr, and reads the correct byte
  - Cache is automagically created and initialised if needed

avr_write_byte_cached()
  - Uses a cache if paged routines available and if memory is EEPROM or flash
  - Otherwise fall back to pgm->write_byte()
  - Out of memory addr: write current (page) cache and pretend writing correctly
  - Out of cache addr: write current (page) Cache, then fills cache to write to addr
  - Cache is automagically created and initialised if needed

avr_flush_cache()
  - User should call this at the end to finally write all caches to device and free them
@MCUdude
Copy link
Collaborator

MCUdude commented Oct 2, 2022

Cool, I've give it a try tomorrow!

src/Makefile.am Outdated
@@ -92,6 +92,7 @@ libavrdude_a_SOURCES = \
avr.c \
avr910.c \
avr910.h \
avrcache.c \
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A tiny formatting error here. Too many spaces used as indent.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

:) The old tab/space mixup. I had not anticipated this list be written with tabs.

@MCUdude
Copy link
Collaborator

MCUdude commented Oct 2, 2022

I just gave the PR a try using a USBtinyISP and an ATmega2560. It appears to work just fine, but to my surprise, there's no delay when turning 0's into 1's! I'm not getting the avrdude: expanding cache ... info message either.

$ ./avrdude -cusbtiny -patmega2560 -t -B1

avrdude: AVR device initialized and ready to accept instructions

Reading | ################################################## | 100% 0.00s

avrdude: Device signature = 0x1e9801 (probably m2560)
avrdude> erase
>>> erase 
avrdude: erasing chip
avrdude> read flash 0 16
>>> read flash 0 16 

Reading | ################################################## | 100% 0.07s

0000  ff ff ff ff ff ff ff ff  ff ff ff ff ff ff ff ff  |................|

avrdude> write flash 0x00000 "hello world!\n"
>>> write flash 0x00000 "hello world!\n" 

Writing | ################################################## | 100% 0.00s

avrdude> read flash 0 16
>>> read flash 0 16 

Reading | ################################################## | 100% 0.00s

0000  68 65 6c 6c 6f 20 77 6f  72 6c 64 21 0a 00 ff ff  |hello world! ...|

avrdude> write flash 0x00000 "Hello World!\n"
>>> write flash 0x00000 "Hello World!\n" 

Writing | ################################################## | 100% 0.00s

avrdude> read flash 0 16
>>> read flash 0 16 

Reading | ################################################## | 100% 0.00s

0000  48 65 6c 6c 6f 20 57 6f  72 6c 64 21 0a 00 ff ff  |Hello World! ...|

avrdude>

@stefanrueger
Copy link
Collaborator Author

stefanrueger commented Oct 2, 2022

there's no delay when turning 0's into 1's! I'm not getting the avrdude: expanding cache ... info message either.

It's still all in the cache. At this stage AVRDUDE does not yet want to write the flash page. Once that happens (write to addr 1024, eg, or type - [edit] now only on quit), the code realises that this part/programmer/paged write behaves like a NOR memory and expands the cache to cover the full shebang. Then when you finally leave the terminal the code flushes both flash and eeprom to the device (and verifies). Make a tea, it will take minutes with a 2560.

@stefanrueger
Copy link
Collaborator Author

... ahhh and, of course, what also happened is that because you were in a single session the change from h to H and back to h all happened in the cache, not on the device flash, so when you finally quit the last written string was written onto the pristinely erased device, so possible w/out erasing it anew. My examples were different avrdude sessions that, at their respective ends, forced avrdude to synchronise with the device

@mcuee mcuee added bug Something isn't working enhancement New feature or request labels Oct 3, 2022
@MCUdude
Copy link
Collaborator

MCUdude commented Oct 3, 2022

It's still all in the cache. At this stage AVRDUDE does not yet want to write the flash page. Once that happens (write to addr 1024, eg, or type quit), the code realises that this part/programmer/paged write behaves like a NOR memory and expands the cache to cover the full shebang. Then when you finally leave the terminal the code flushes both flash and eeprom to the device (and verifies). Make a tea, it will take minutes with a 2560.

Maybe this info should be printed when using terminal mode to write to flash-like memories? I tend to just hit ctrl+c to quit terminal mode instead of running quit, and was not aware of this.

@mcuee
Copy link
Collaborator

mcuee commented Oct 3, 2022

Initial test with usbasp seems to be good. The current git main will fail but the this PR works fine.

PS C:\work\avr\avrdude_test\avrdude_bin> .\avrdude -c usbasp -qqp t85 -t
avrdude> 'write flash 0x1000 "hello, world\n"'
>>> 'write flash 0x1000 "hello, world\n"'
avrdude.exe (cmd): invalid command 'write flash 0x1000 "hello, world\n"'
avrdude> write flash 0x1000 "hello, world\n"
>>> write flash 0x1000 "hello, world\n"
avrdude.exe (write): error writing 0x68 at 0x01000 cell=0xff
avrdude.exe (write): error writing 0x65 at 0x01001 cell=0xff
avrdude.exe (write): error writing 0x6c at 0x01002 cell=0xff
avrdude.exe (write): error writing 0x6c at 0x01003 cell=0xff
avrdude.exe (write): error writing 0x6f at 0x01004 cell=0xff
avrdude.exe (write): error writing 0x2c at 0x01005 cell=0xff
avrdude.exe (write): error writing 0x20 at 0x01006 cell=0xff
avrdude.exe (write): error writing 0x77 at 0x01007 cell=0xff
avrdude.exe (write): error writing 0x6f at 0x01008 cell=0xff
avrdude.exe (write): error writing 0x72 at 0x01009 cell=0xff
avrdude.exe (write): error writing 0x6c at 0x0100a cell=0xff
avrdude.exe (write): error writing 0x64 at 0x0100b cell=0xff
avrdude.exe (write): error writing 0x0a at 0x0100c cell=0xff
avrdude.exe (write): error writing 0x00 at 0x0100d cell=0xff
avrdude> quit
>>> quit

PS C:\work\avr\avrdude_test\avrdude_bin> .\avrdude_pr1106 -c usbasp -qqp t85 -t
avrdude> write flash 0x1000 "hello, world\n"
>>> write flash 0x1000 "hello, world\n"
avrdude> read flash 0x1000 16
>>> read flash 0x1000 16
1000  68 65 6c 6c 6f 2c 20 77  6f 72 6c 64 0a 00 ff ff  |hello, world ...|

avrdude> read flash 0x1010 16
>>> read flash 0x1010 16
1010  ff ff ff ff ff ff ff ff  ff ff ff ff ff ff ff ff  |................|

avrdude> write flash 0x1010 "hello, world\n"
>>> write flash 0x1010 "hello, world\n"
avrdude> read flash 0x1000 32
>>> read flash 0x1000 32
1000  68 65 6c 6c 6f 2c 20 77  6f 72 6c 64 0a 00 ff ff  |hello, world ...|
1010  68 65 6c 6c 6f 2c 20 77  6f 72 6c 64 0a 00 ff ff  |hello, world ...|

avrdude> quit
>>> quit


@mcuee
Copy link
Collaborator

mcuee commented Oct 3, 2022

The cache mechanism may need some explanation though. Not so sure why the cache message only shows after the quit command.

PS C:\work\avr\avrdude_test\avrdude_bin> .\avrdude_pr1106 -c usbasp -qqp t85 -t
avrdude> write flash 0x1000 "hello, world\n"0x1000 16
>>> write flash 0x1000 "hello, world\n"0x1000 16

avrdude_pr1106.exe (write): can't parse data "hello, world\n"0x1000 16

avrdude> write flash 0x1000 "hello, world\n" 0x1000 16
>>> write flash 0x1000 "hello, world\n" 0x1000 16
avrdude> read flash 0x1000 32
>>> read flash 0x1000 32
1000  68 65 6c 6c 6f 2c 20 77  6f 72 6c 64 0a 00 00 10  |hello, world ...|
1010  10 65 6c 6c 6f 2c 20 77  6f 72 6c 64 0a 00 ff ff  |.ello, world ...|

avrdude> quit
>>> quit
avrdude_pr1106.exe: expanding cache to all flash and EEPROM (takes time)...
avrdude_pr1106.exe: erasing chip and writing caches to all flash and EEPROM (takes time)...

PS C:\work\avr\avrdude_test\avrdude_bin> .\avrdude -c usbasp -qqp t85 -t
avrdude> read flash 0x1000 32
>>> read flash 0x1000 32
1000  68 65 6c 6c 6f 2c 20 77  6f 72 6c 64 0a 00 00 10  |hello, world ...|
1010  10 65 6c 6c 6f 2c 20 77  6f 72 6c 64 0a 00 ff ff  |.ello, world ...|

avrdude> quit
>>> quit

 - Now cached write only ever occurs when leaving the terminal
 - Added documentation about this new terminal feature
 - Added avr_chip_erase_cached() to set cache after CE
 - Added avr_reset_cache() to reset cache
 - Added an abort command for the terminal to reset the cache
@stefanrueger
Copy link
Collaborator Author

@mcuee and @MCUdude: Thanks for comments.

Following you comments I improved the cache API for terminal read/writes of flash/EEPROM

  • Now cached write only ever occurs when leaving the terminal
  • Added documentation about this new terminal feature
  • Added avr_chip_erase_cached() to set cache after CE
  • Added avr_reset_cache() to reset cache
  • Added an abort command for the terminal to reset the cache

Please check different programmers and different MCU families (PDI, UPDI, ISP, ...). My standard bash test script is

echo erase | avrdude -qqp m2560 -c usbtiny -t
echo 'read flash 0x3100 16' | avrdude -qqp m2560 -c usbtiny -t
echo 'write flash 0x3100 "hello, world\n"' | avrdude -qqp m2560 -c usbtiny -t
echo 'read flash 0x3100 16' | avrdude -qqp m2560 -c usbtiny -t
echo 'write flash 0x3100 "Hello, world\n"' | avrdude -qqp m2560 -c usbtiny -t
echo 'read flash 0x3100 16' | avrdude -qqp m2560 -c usbtiny -t
echo 'write flash 0x3100 "hello, world\n"' | avrdude -qqp m2560 -c usbtiny -t
echo 'read flash 0x3100 16' | avrdude -qqp m2560 -c usbtiny -t

The penultimate command takes a looooong time (6 minutes) b/c a 1 bit needs be written that was 0 before. Writing this bit requires reading all of flash (and EEPROM), then a chip erase followed by a complete rewrite of the device.

Should work for bootloaders, too, eg, -c arduino, but there (at least in optiboot), the penultimate command should not take long, as there is no problem writing 0s to flash (owing to SPM page erase in the bootloader).

I suspect terminal write might also work for jtag writes of EEPROM (which are said to only be able to write 0).

Please review and test.

@stefanrueger
Copy link
Collaborator Author

I tend to just hit ctrl+c to quit

ctrl+d is better (EOF in Un*x terminals)

@stefanrueger stefanrueger removed the bug Something isn't working label Oct 3, 2022
@mcuee
Copy link
Collaborator

mcuee commented Oct 4, 2022

It seems to work fine for the following simple test cases using usbasp. I will try JTAG1 with EEPROM and bootloader later as well.

C:\work\avr\avrdude_test\avrdude_bin> .\avrdude_pr1106 -c usbasp -qqp t88 -t
avrdude> write flash 0x1100 "hello, world\n"
>>> write flash 0x1100 "hello, world\n"
avrdude> quit
>>> quit
avrdude_pr1106.exe: writing cache to device... done

C:\work\avr\avrdude_test\avrdude_bin> .\avrdude_pr1106 -c usbasp -qqp t88 -t
avrdude> write flash 0x1000 "hello, world\n"
>>> write flash 0x1000 "hello, world\n"
avrdude> read flash 0x1000 16
>>> read flash 0x1000 16
1000  68 65 6c 6c 6f 2c 20 77  6f 72 6c 64 0a 00 ff ff  |hello, world ...|

avrdude> quit
>>> quit
avrdude_pr1106.exe: writing cache to device... done

C:\work\avr\avrdude_test\avrdude_bin> .\avrdude_pr1106 -c usbasp -qqp t88 -t
avrdude> read flash 0x1200 16
>>> read flash 0x1200 16
1200  ff ff ff ff ff ff ff ff  ff ff ff ff ff ff ff ff  |................|

avrdude> write flash 0x1200 "hello, world\n"
>>> write flash 0x1200 "hello, world\n"
avrdude> read flash 0x1300 16
>>> read flash 0x1300 16
1300  ff ff ff ff ff ff ff ff  ff ff ff ff ff ff ff ff  |................|

avrdude> write flash 0x1300 "hello, world\n"
>>> write flash 0x1300 "hello, world\n"
avrdude> quit
>>> quit
avrdude_pr1106.exe: writing cache to device... done

C:\work\avr\avrdude_test\avrdude_bin> .\avrdude_pr1106 -c usbasp -qqp t88 -t
avrdude> read flash 0x1300 16
>>> read flash 0x1300 16
1300  68 65 6c 6c 6f 2c 20 77  6f 72 6c 64 0a 00 ff ff  |hello, world ...|

avrdude> read flash 0x1200 16
>>> read flash 0x1200 16
1200  68 65 6c 6c 6f 2c 20 77  6f 72 6c 64 0a 00 ff ff  |hello, world ...|

avrdude> read flash 0x1100 16
>>> read flash 0x1100 16
1100  68 65 6c 6c 6f 2c 20 77  6f 72 6c 64 0a 00 ff ff  |hello, world ...|

avrdude> read flash 0x1000 16
>>> read flash 0x1000 16
1000  68 65 6c 6c 6f 2c 20 77  6f 72 6c 64 0a 00 ff ff  |hello, world ...|

avrdude> write flash 0x1000 "HELLO, WORLD\n"
>>> write flash 0x1000 "HELLO, WORLD\n"
avrdude> quit
>>> quit
avrdude_pr1106.exe: writing cache to device... done

C:\work\avr\avrdude_test\avrdude_bin> .\avrdude_git -c usbasp -qqp t88 -t
avrdude> read flash 0x1000 16
>>> read flash 0x1000 16
1000  48 45 4c 4c 4f 2c 20 57  4f 52 4c 44 0a 00 ff ff  |HELLO, WORLD ...|

avrdude> quit
>>> quit

@stefanrueger
Copy link
Collaborator Author

@mcuee Thanks for testing. This is brilliant. I've just tested the arduino bootloader with

echo 'read flash 0x3100 16' | avrdude -qqp m328p -c arduino -P /dev/ttyUSB0 -t
echo 'write flash 0x3100 "hello, world\n"' | avrdude -qqp m328p -c arduino -P /dev/ttyUSB0 -t
echo 'read flash 0x3100 16' | avrdude -qqp m328p -c arduino -P /dev/ttyUSB0 -t
echo 'write flash 0x3100 "Hello, world\n"' | avrdude -qqp m328p -c arduino -P /dev/ttyUSB0 -t
echo 'read flash 0x3100 16' | avrdude -qqp m328p -c arduino -P /dev/ttyUSB0 -t
echo 'write flash 0x3100 "hello, world\n"' | avrdude -qqp m328p -c arduino -P /dev/ttyUSB0 -t
echo 'read flash 0x3100 16' | avrdude -qqp m328p -c arduino -P /dev/ttyUSB0 -t

and the result

avrdude> avrdude> read flash 0x3100 16
3100  ff ff ff ff ff ff ff ff  ff ff ff ff ff ff ff ff  |................|

avrdude> avrdude> write flash 0x3100 "hello, world\n"
avrdude> avrdude: writing cache to device... done
avrdude> read flash 0x3100 16
3100  68 65 6c 6c 6f 2c 20 77  6f 72 6c 64 0a 00 ff ff  |hello, world ...|

avrdude> avrdude> write flash 0x3100 "Hello, world\n"
avrdude> avrdude: writing cache to device... done
avrdude> read flash 0x3100 16
3100  48 65 6c 6c 6f 2c 20 77  6f 72 6c 64 0a 00 ff ff  |Hello, world ...|

avrdude> avrdude> write flash 0x3100 "hello, world\n"
avrdude> avrdude: writing cache to device... done
avrdude> read flash 0x3100 16
3100  68 65 6c 6c 6f 2c 20 77  6f 72 6c 64 0a 00 ff ff  |hello, world ...|

So probably good to merge unless there are further comments.

@MCUdude
Copy link
Collaborator

MCUdude commented Oct 4, 2022

I'd still like to test a little more on various hardware (JTAG, PDI, UPDI etc.) before merging. But if writing the cache to flash may take some time, how about a progress bar that's visible in non-quell mode?

@mcuee
Copy link
Collaborator

mcuee commented Oct 4, 2022

I suspect terminal write might also work for jtag writes of EEPROM (which are said to only be able to write 0).

@stefanrueger Indeed it seems to work, tested with JTAG1 and ATmega32A. So I think this PR will fix #1072 and #1054.

Ref: #1072 (enhancement) and #1054 (bug)

PS C:\work\avr\avrdude_test\avrdude_bin> .\avrdude_pr1106v1 -c jtag1 -P COM3 -qqp m32 -t
avrdude> d ee 0x0 0x10
>>> d ee 0x0 0x10
0000  ff ff ff ff ff ff ff ff  ff ff ff ff ff ff ff ff  |................|

avrdude> write eeprom 0x0 "hello world!"
>>> write eeprom 0x0 "hello world!"
avrdude> quit
>>> quit
avrdude_pr1106v1.exe: writing cache to device... done

PS C:\work\avr\avrdude_test\avrdude_bin> .\avrdude_pr1106v1 -c jtag1 -P COM3 -qqp m32 -t
avrdude> d ee 0x0 0x10
>>> d ee 0x0 0x10
0000  68 65 6c 6c 6f 20 77 6f  72 6c 64 21 00 ff ff ff  |hello world!....|

avrdude> write eeprom 0x0 "HELLO WORLD!"
>>> write eeprom 0x0 "HELLO WORLD!"
avrdude> quit
>>> quit
avrdude_pr1106v1.exe: writing cache to device... done

PS C:\work\avr\avrdude_test\avrdude_bin> .\avrdude_pr1106v1 -c jtag1 -P COM3 -qqp m32 -t
avrdude> d ee 0x0 0x10
>>> d ee 0x0 0x10
0000  48 45 4c 4c 4f 20 57 4f  52 4c 44 21 00 ff ff ff  |HELLO WORLD!....|

avrdude> quit
>>> quit

@mcuee
Copy link
Collaborator

mcuee commented Oct 4, 2022

@stefanrueger

More complicated test case with JTAG1 and EEPROM. When I saw the "chip erase needed" information, I was worried that the Flash would get erazed. I was relieved that the Flash still works and not get erased at all.

PS C:\work\avr\avrdude_test\avrdude_bin> .\avrdude_pr1106v1 -c jtag1 -P COM3 -qqp m32 -t
avrdude> write eeprom 0x0 0xff 0xff 0xff 0xff
>>> write eeprom 0x0 0xff 0xff 0xff 0xff
avrdude> d ee 0x0 0x10
>>> d ee 0x0 0x10
0000  ff ff ff ff 4f 20 57 4f  52 4c 44 21 00 ff ff ff  |....O WORLD!....|

avrdude> quit
>>> quit
avrdude_pr1106v1.exe: writing cache to device... chip erase needed; this will take some time ... done

PS C:\work\avr\avrdude_test\avrdude_bin> .\avrdude_pr1106v1 -c jtag1 -P COM3 -qqp m32 -t
avrdude> d ee 0x0 0x10
>>> d ee 0x0 0x10
0000  ff ff ff ff 4f 20 57 4f  52 4c 44 21 00 ff ff ff  |....O WORLD!....|

avrdude> quit
>>> quit

@mcuee
Copy link
Collaborator

mcuee commented Oct 4, 2022

@stefanrueger
A minor thing (not related to this issue), maybe you can lower the warning message for the JTAG1. ATmega32A is perfectly fine for JTAG1. I used m32 in the above test to avoid the warning message.

PS C:\work\avr\avrdude_test\avrdude_bin> .\avrdude_pr1106v1 -c jtag1 -P COM3 -p m32a

avrdude_pr1106v1.exe: jtagmkI_initialize(): warning part ATmega32A has JTAG interface, but may be too new
avrdude_pr1106v1.exe: AVR device initialized and ready to accept instructions

Reading | ################################################## | 100% 0.02s

avrdude_pr1106v1.exe: Device signature = 0x1e9502 (probably m32a)

avrdude_pr1106v1.exe done.  Thank you

PS C:\work\avr\avrdude_test\avrdude_bin> .\avrdude_pr1106v1 -c jtag1 -P COM3 -qqp m32a -t
avrdude_pr1106v1.exe: jtagmkI_initialize(): warning part ATmega32A has JTAG interface, but may be too new
avrdude>

@MCUdude
Copy link
Collaborator

MCUdude commented Oct 4, 2022

A minor thing (not related to this issue), maybe you can lower the warning message for the JTAG1. ATmega32A is perfectly fine for JTAG1. I used m32 in the above test to avoid the warning message.

If the JTAGmkI officially supports a part (ATmega32 for instance), it also supports die-shrink variants like ATMega32A as well.
avrdude.conf.in should be updated to support ATmega16A, ATmega32A, ATmega64A, ATmega128A, ATmega165A and ATmega169A.

@mcuee
Copy link
Collaborator

mcuee commented Oct 4, 2022

JTAG1 is also okay with Flash. And it is good after the last operation the application still works.

PS C:\work\avr\avrdude_test\avrdude_bin> .\avrdude_pr1106v1 -c jtag1 -P COM3 -p m32a -U flash:r:m32ademo.hex:i

avrdude_pr1106v1.exe: jtagmkI_initialize(): warning part ATmega32A has JTAG interface, but may be too new
avrdude_pr1106v1.exe: AVR device initialized and ready to accept instructions

Reading | ################################################## | 100% 0.04s

avrdude_pr1106v1.exe: Device signature = 0x1e9502 (probably m32a)
avrdude_pr1106v1.exe: reading flash memory ...

Reading | ################################################## | 100% 6.38s

avrdude_pr1106v1.exe: writing output file m32ademo.hex

avrdude_pr1106v1.exe done.  Thank you.

PS C:\work\avr\avrdude_test\avrdude_bin> .\avrdude_pr1106v1 -c jtag1 -P COM3 -qqp m32a -t
avrdude_pr1106v1.exe: jtagmkI_initialize(): warning part ATmega32A has JTAG interface, but may be too new
avrdude> write flash 0x200 "Hello world!"
>>> write flash 0x200 "Hello world!"
avrdude> dump flash 0x200 0x10
>>> dump flash 0x200 0x10
0200  48 65 6c 6c 6f 20 77 6f  72 6c 64 21 00 ff ff ff  |Hello world!....|

avrdude> quit
>>> quit
avrdude_pr1106v1.exe: writing cache to device... done

PS C:\work\avr\avrdude_test\avrdude_bin> .\avrdude_pr1106v1 -c jtag1 -P COM3 -qqp m32a -t
avrdude_pr1106v1.exe: jtagmkI_initialize(): warning part ATmega32A has JTAG interface, but may be too new
avrdude> dump flash 0x200 0x10
>>> dump flash 0x200 0x10
0200  48 65 6c 6c 6f 20 77 6f  72 6c 64 21 00 ff ff ff  |Hello world!....|

avrdude> write flash 0x200 0xff 0xff 0xff 0xff
>>> write flash 0x200 0xff 0xff 0xff 0xff
avrdude> quit
>>> quit
avrdude_pr1106v1.exe: writing cache to device... chip erase needed; this will take some time ... 
avrdude_pr1106v1.exe: jtagmkI_initialize(): warning part ATmega32A has JTAG interface, but may be too new
done

PS C:\work\avr\avrdude_test\avrdude_bin> .\avrdude_pr1106v1 -c jtag1 -P COM3 -qqp m32a -t
avrdude_pr1106v1.exe: jtagmkI_initialize(): warning part ATmega32A has JTAG interface, but may be too new
avrdude> dump flash 0x200 0x10
>>> dump flash 0x200 0x10
0200  ff ff ff ff 6f 20 77 6f  72 6c 64 21 00 ff ff ff  |....o world!....|

avrdude> quit
>>> quit

PS C:\work\avr\avrdude_test\avrdude_bin> .\avrdude_pr1106v1 -c jtag1 -P COM3 -p m32a -U flash:v:m32ademo.hex:i

avrdude_pr1106v1.exe: jtagmkI_initialize(): warning part ATmega32A has JTAG interface, but may be too new
avrdude_pr1106v1.exe: AVR device initialized and ready to accept instructions

Reading | ################################################## | 100% 0.02s

avrdude_pr1106v1.exe: Device signature = 0x1e9502 (probably m32a)
avrdude_pr1106v1.exe: verifying flash memory against m32ademo.hex

Reading | ################################################## | 100% 0.08s

avrdude_pr1106v1.exe: 292 bytes of flash verified

avrdude_pr1106v1.exe done.  Thank you.

@MCUdude
Copy link
Collaborator

MCUdude commented Oct 4, 2022

As I mentioned earlier, a progress bar when writing the cache in non-quell mode would be nice.

I'm also getting a funny warning when using the avrispmkii; stk500v2_page_erase(): this function must never be called.
I'll try with different targets and programmers later tonight.

$ ./avrdude -cavrispmkii -patmega1281 -t

avrdude: AVR device initialized and ready to accept instructions

Reading | ################################################## | 100% 0.00s

avrdude: Device signature = 0x1e9704 (probably m1281)
avrdude> read flash
>>> read flash 

Reading | ################################################## | 100% 0.01s

0000  48 65 6c 6c 6f 20 57 6f  72 6c 64 21 00 ff ff ff  |Hello World!....|
0010  ff ff ff ff ff ff ff ff  ff ff ff ff ff ff ff ff  |................|
0020  ff ff ff ff ff ff ff ff  ff ff ff ff ff ff ff ff  |................|
0030  ff ff ff ff ff ff ff ff  ff ff ff ff ff ff ff ff  |................|
0040  ff ff ff ff ff ff ff ff  ff ff ff ff ff ff ff ff  |................|
0050  ff ff ff ff ff ff ff ff  ff ff ff ff ff ff ff ff  |................|
0060  ff ff ff ff ff ff ff ff  ff ff ff ff ff ff ff ff  |................|
0070  ff ff ff ff ff ff ff ff  ff ff ff ff ff ff ff ff  |................|
0080  ff ff ff ff ff ff ff ff  ff ff ff ff ff ff ff ff  |................|
0090  ff ff ff ff ff ff ff ff  ff ff ff ff ff ff ff ff  |................|
00a0  ff ff ff ff ff ff ff ff  ff ff ff ff ff ff ff ff  |................|
00b0  ff ff ff ff ff ff ff ff  ff ff ff ff ff ff ff ff  |................|
00c0  ff ff ff ff ff ff ff ff  ff ff ff ff ff ff ff ff  |................|
00d0  ff ff ff ff ff ff ff ff  ff ff ff ff ff ff ff ff  |................|
00e0  ff ff ff ff ff ff ff ff  ff ff ff ff ff ff ff ff  |................|
00f0  ff ff ff ff ff ff ff ff  ff ff ff ff ff ff ff ff  |................|

avrdude> write flash 0 "abc"
>>> write flash 0 "abc" 

Writing | ################################################## | 100% 0.00s

avrdude> quit
>>> quit 
avrdude: writing cache to device... avrdude: stk500v2_page_erase(): this function must never be called
chip erase needed; this will take some time ... done

avrdude done.  Thank you.

Also improves avr_erase_chip_cached() to preset and reset cache
as the case may be.
@stefanrueger
Copy link
Collaborator Author

I'd still like to test a little more on various hardware (JTAG, PDI, UPDI etc.) before merging.

Good point. I noted that I forgot to treat the offsets for apptable and boot for the XMEGAs. That's now done.

@MCUdude
Copy link
Collaborator

MCUdude commented Oct 4, 2022

Here's some output from various programmers and targets. I'm using the following commands:

echo erase | ./avrdude -qqp atmega3209 -c pkobn_updi -t
echo 'read flash 0x3100 16' | ./avrdude -qqp atmega3209 -c pkobn_updi -t
echo 'write flash 0x3100 "hello, world\n"' | ./avrdude -qqp atmega3209 -c pkobn_updi -t
echo 'read flash 0x3100 16' | ./avrdude -qqp atmega3209 -c pkobn_updi -t
echo 'write flash 0x3100 "Hello, world\n"' | ./avrdude -qqp atmega3209 -c pkobn_updi -t
echo 'read flash 0x3100 16' | ./avrdude -qqp atmega3209 -c pkobn_updi -t
echo 'write flash 0x3100 "hello, world\n"' | ./avrdude -qqp atmega3209 -c pkobn_updi -t
echo 'read flash 0x3100 16' | ./avrdude -qqp atmega3209 -c pkobn_updi -t
pkobn_updi + ATmega3209
$ echo erase | ./avrdude -qqp atmega3209 -c pkobn_updi -t
         Vtarget                      : 5.10 V
         PDI/UPDI clock Xmega/megaAVR : 200 kHz

>>> erase 
avrdude: erasing chip
$ echo 'read flash 0x3100 16' | ./avrdude -qqp atmega3209 -c pkobn_updi -t
         Vtarget                      : 5.10 V
         PDI/UPDI clock Xmega/megaAVR : 200 kHz

>>> read flash 0x3100 16 
3100  ff ff ff ff ff ff ff ff  ff ff ff ff ff ff ff ff  |................|

$ echo 'write flash 0x3100 "hello, world\n"' | ./avrdude -qqp atmega3209 -c pkobn_updi -t
         Vtarget                      : 5.10 V
         PDI/UPDI clock Xmega/megaAVR : 200 kHz

>>> write flash 0x3100 "hello, world\n" 
avrdude: writing cache to device... done
$ echo 'read flash 0x3100 16' | ./avrdude -qqp atmega3209 -c pkobn_updi -t
         Vtarget                      : 5.10 V
         PDI/UPDI clock Xmega/megaAVR : 200 kHz

>>> read flash 0x3100 16 
3100  68 65 6c 6c 6f 2c 20 77  6f 72 6c 64 0a 00 ff ff  |hello, world ...|

$ echo 'write flash 0x3100 "Hello, world\n"' | ./avrdude -qqp atmega3209 -c pkobn_updi -t
         Vtarget                      : 5.10 V
         PDI/UPDI clock Xmega/megaAVR : 200 kHz

>>> write flash 0x3100 "Hello, world\n" 
avrdude: writing cache to device... done
$ echo 'read flash 0x3100 16' | ./avrdude -qqp atmega3209 -c pkobn_updi -t
         Vtarget                      : 5.10 V
         PDI/UPDI clock Xmega/megaAVR : 200 kHz

>>> read flash 0x3100 16 
3100  48 65 6c 6c 6f 2c 20 77  6f 72 6c 64 0a 00 ff ff  |Hello, world ...|

$ echo 'write flash 0x3100 "hello, world\n"' | ./avrdude -qqp atmega3209 -c pkobn_updi -t
         Vtarget                      : 5.10 V
         PDI/UPDI clock Xmega/megaAVR : 200 kHz

>>> write flash 0x3100 "hello, world\n" 
avrdude: writing cache to device... avrdude: jtag3_page_erase: not an Xmega device
read/chip erase/write will take time ... done
$ echo 'read flash 0x3100 16' | ./avrdude -qqp atmega3209 -c pkobn_updi -t
         Vtarget                      : 5.10 V
         PDI/UPDI clock Xmega/megaAVR : 200 kHz

>>> read flash 0x3100 16 
3100  68 65 6c 6c 6f 2c 20 77  6f 72 6c 64 0a 00 ff ff  |hello, world ...|
pkobn_updi + AVR64DD32
echo erase | ./avrdude -qqp avr64dd32 -c pkobn_updi -t
         Vtarget                      : 3.31 V
         PDI/UPDI clock Xmega/megaAVR : 100 kHz

>>> erase 
avrdude: erasing chip
$ echo 'read flash 0x3100 16' | ./avrdude -qqp avr64dd32 -c pkobn_updi -t
         Vtarget                      : 3.31 V
         PDI/UPDI clock Xmega/megaAVR : 100 kHz

>>> read flash 0x3100 16 
3100  ff ff ff ff ff ff ff ff  ff ff ff ff ff ff ff ff  |................|

$ echo 'write flash 0x3100 "hello, world\n"' | ./avrdude -qqp avr64dd32 -c pkobn_updi -t
         Vtarget                      : 3.31 V
         PDI/UPDI clock Xmega/megaAVR : 100 kHz

>>> write flash 0x3100 "hello, world\n" 
avrdude: writing cache to device... done
$ echo 'read flash 0x3100 16' | ./avrdude -qqp avr64dd32 -c pkobn_updi -t
         Vtarget                      : 3.31 V
         PDI/UPDI clock Xmega/megaAVR : 100 kHz

>>> read flash 0x3100 16 
3100  68 65 6c 6c 6f 2c 20 77  6f 72 6c 64 0a 00 ff ff  |hello, world ...|

$ echo 'write flash 0x3100 "Hello, world\n"' | ./avrdude -qqp avr64dd32 -c pkobn_updi -t
         Vtarget                      : 3.31 V
         PDI/UPDI clock Xmega/megaAVR : 100 kHz

>>> write flash 0x3100 "Hello, world\n" 
avrdude: writing cache to device... done
$ echo 'read flash 0x3100 16' | ./avrdude -qqp avr64dd32 -c pkobn_updi -t
         Vtarget                      : 3.31 V
         PDI/UPDI clock Xmega/megaAVR : 100 kHz

>>> read flash 0x3100 16 
3100  48 65 6c 6c 6f 2c 20 77  6f 72 6c 64 0a 00 ff ff  |Hello, world ...|

$ echo 'write flash 0x3100 "hello, world\n"' | ./avrdude -qqp avr64dd32 -c pkobn_updi -t
         Vtarget                      : 3.31 V
         PDI/UPDI clock Xmega/megaAVR : 100 kHz

>>> write flash 0x3100 "hello, world\n" 
avrdude: writing cache to device... avrdude: jtag3_page_erase: not an Xmega device
read/chip erase/write will take time ... done
$ echo 'read flash 0x3100 16' | ./avrdude -qqp avr64dd32 -c pkobn_updi -t
         Vtarget                      : 3.31 V
         PDI/UPDI clock Xmega/megaAVR : 100 kHz

>>> read flash 0x3100 16 
3100  68 65 6c 6c 6f 2c 20 77  6f 72 6c 64 0a 00 ff ff  |hello, world ...|
xplainedmini_updi + ATmega4808
$ echo erase | ./avrdude -qqp atmega4808 -c xplainedmini_updi -t
         Vtarget                      : 5.00 V
>>> erase 
avrdude: erasing chip
$ echo 'read flash 0x3100 16' | ./avrdude -qqp atmega4808 -c xplainedmini_updi -t
         Vtarget                      : 5.00 V
>>> read flash 0x3100 16 
3100  ff ff ff ff ff ff ff ff  ff ff ff ff ff ff ff ff  |................|

$ echo 'write flash 0x3100 "hello, world\n"' | ./avrdude -qqp atmega4808 -c xplainedmini_updi -t
         Vtarget                      : 5.00 V
>>> write flash 0x3100 "hello, world\n" 
avrdude: writing cache to device... done
$ echo 'read flash 0x3100 16' | ./avrdude -qqp atmega4808 -c xplainedmini_updi -t
         Vtarget                      : 5.00 V
>>> read flash 0x3100 16 
3100  68 65 6c 6c 6f 2c 20 77  6f 72 6c 64 0a 00 ff ff  |hello, world ...|

$ echo 'write flash 0x3100 "Hello, world\n"' | ./avrdude -qqp atmega4808 -c xplainedmini_updi -t
         Vtarget                      : 5.00 V
>>> write flash 0x3100 "Hello, world\n" 
avrdude: writing cache to device... done
$ echo 'read flash 0x3100 16' | ./avrdude -qqp atmega4808 -c xplainedmini_updi -t
         Vtarget                      : 5.00 V
>>> read flash 0x3100 16 
3100  48 65 6c 6c 6f 2c 20 77  6f 72 6c 64 0a 00 ff ff  |Hello, world ...|

$ echo 'write flash 0x3100 "hello, world\n"' | ./avrdude -qqp atmega4808 -c xplainedmini_updi -t
         Vtarget                      : 5.00 V
>>> write flash 0x3100 "hello, world\n" 
avrdude: writing cache to device... avrdude: jtag3_page_erase: not an Xmega device
read/chip erase/write will take time ... done
$ echo 'read flash 0x3100 16' | ./avrdude -qqp atmega4808 -c xplainedmini_updi -t
         Vtarget                      : 5.00 V
>>> read flash 0x3100 16 
3100  68 65 6c 6c 6f 2c 20 77  6f 72 6c 64 0a 00 ff ff  |hello, world ...|
serialupdi + ATmega4808
$ echo erase | ./avrdude -qqp atmega4808 -c serialupdi -P /dev/cu.usbserial-1410 -t
avrdude: UPDI link initialization OK
avrdude: NVM type 0: 16-bit, page oriented write
avrdude: Entering NVM programming mode
>>> erase 
avrdude: erasing chip
Bus error: 10
$ echo 'read flash 0x3100 16' | ./avrdude -qqp atmega4808 -c serialupdi -P /dev/cu.usbserial-1410 -t
avrdude: UPDI link initialization OK
avrdude: Device in NVM programming state, leaving programming mode
avrdude: NVM type 0: 16-bit, page oriented write
avrdude: Entering NVM programming mode
>>> read flash 0x3100 16 
3100  48 65 6c 6c 6f 2c 20 77  6f 72 6c 64 0a 00 ff ff  |Hello, world ...|

avrdude: Leaving NVM programming mode
$ echo 'write flash 0x3100 "hello, world\n"' | ./avrdude -qqp atmega4808 -c serialupdi -P /dev/cu.usbserial-1410 -t
avrdude: UPDI link initialization OK
avrdude: NVM type 0: 16-bit, page oriented write
avrdude: Entering NVM programming mode
>>> write flash 0x3100 "hello, world\n" 
avrdude: writing cache to device... avrdude: error: page erase not implemented yet
read/chip erase/write will take time ... done
avrdude: Leaving NVM programming mode
$ echo 'read flash 0x3100 16' | ./avrdude -qqp atmega4808 -c serialupdi -P /dev/cu.usbserial-1410 -t
avrdude: UPDI link initialization OK
avrdude: NVM type 0: 16-bit, page oriented write
avrdude: Entering NVM programming mode
>>> read flash 0x3100 16 
3100  68 65 6c 6c 6f 2c 20 77  6f 72 6c 64 0a 00 ff ff  |hello, world ...|

avrdude: Leaving NVM programming mode
$ echo 'write flash 0x3100 "Hello, world\n"' | ./avrdude -qqp atmega4808 -c serialupdi -P /dev/cu.usbserial-1410 -t
avrdude: UPDI link initialization OK
avrdude: NVM type 0: 16-bit, page oriented write
avrdude: Entering NVM programming mode
>>> write flash 0x3100 "Hello, world\n" 
avrdude: writing cache to device... done
avrdude: Leaving NVM programming mode
$ echo 'read flash 0x3100 16' | ./avrdude -qqp atmega4808 -c serialupdi -P /dev/cu.usbserial-1410 -t
avrdude: UPDI link initialization OK
avrdude: NVM type 0: 16-bit, page oriented write
avrdude: Entering NVM programming mode
>>> read flash 0x3100 16 
3100  48 65 6c 6c 6f 2c 20 77  6f 72 6c 64 0a 00 ff ff  |Hello, world ...|

avrdude: Leaving NVM programming mode
$ echo 'write flash 0x3100 "hello, world\n"' | ./avrdude -qqp atmega4808 -c serialupdi -P /dev/cu.usbserial-1410 -t
avrdude: UPDI link initialization OK
avrdude: NVM type 0: 16-bit, page oriented write
avrdude: Entering NVM programming mode
>>> write flash 0x3100 "hello, world\n" 
avrdude: writing cache to device... avrdude: error: page erase not implemented yet
read/chip erase/write will take time ... done
avrdude: Leaving NVM programming mode
$ echo 'read flash 0x3100 16' | ./avrdude -qqp atmega4808 -c serialupdi -P /dev/cu.usbserial-1410 -t
avrdude: UPDI link initialization OK
avrdude: NVM type 0: 16-bit, page oriented write
avrdude: Entering NVM programming mode
>>> read flash 0x3100 16 
3100  68 65 6c 6c 6f 2c 20 77  6f 72 6c 64 0a 00 ff ff  |hello, world ...|

avrdude: Leaving NVM programming mode
$ clear

$ echo erase | ./avrdude -qqp atmega4808 -c serialupdi -P /dev/cu.usbserial-1410 -t
avrdude: UPDI link initialization OK
avrdude: NVM type 0: 16-bit, page oriented write
avrdude: Entering NVM programming mode
>>> erase 
avrdude: erasing chip
Bus error: 10
$ echo 'read flash 0x3100 16' | ./avrdude -qqp atmega4808 -c serialupdi -P /dev/cu.usbserial-1410 -t
avrdude: UPDI link initialization OK
avrdude: Device in NVM programming state, leaving programming mode
avrdude: NVM type 0: 16-bit, page oriented write
avrdude: Entering NVM programming mode
>>> read flash 0x3100 16 
3100  68 65 6c 6c 6f 2c 20 77  6f 72 6c 64 0a 00 ff ff  |hello, world ...|

avrdude: Leaving NVM programming mode
$ echo 'write flash 0x3100 "hello, world\n"' | ./avrdude -qqp atmega4808 -c serialupdi -P /dev/cu.usbserial-1410 -t
avrdude: UPDI link initialization OK
avrdude: NVM type 0: 16-bit, page oriented write
avrdude: Entering NVM programming mode
>>> write flash 0x3100 "hello, world\n" 
avrdude: Leaving NVM programming mode
$ echo 'read flash 0x3100 16' | ./avrdude -qqp atmega4808 -c serialupdi -P /dev/cu.usbserial-1410 -t
avrdude: UPDI link initialization OK
avrdude: NVM type 0: 16-bit, page oriented write
avrdude: Entering NVM programming mode
>>> read flash 0x3100 16 
3100  68 65 6c 6c 6f 2c 20 77  6f 72 6c 64 0a 00 ff ff  |hello, world ...|

avrdude: Leaving NVM programming mode
$ echo 'write flash 0x3100 "Hello, world\n"' | ./avrdude -qqp atmega4808 -c serialupdi -P /dev/cu.usbserial-1410 -t
avrdude: UPDI link initialization OK
avrdude: NVM type 0: 16-bit, page oriented write
avrdude: Entering NVM programming mode
>>> write flash 0x3100 "Hello, world\n" 
avrdude: writing cache to device... done
avrdude: Leaving NVM programming mode
$ echo 'read flash 0x3100 16' | ./avrdude -qqp atmega4808 -c serialupdi -P /dev/cu.usbserial-1410 -t
avrdude: UPDI link initialization OK
avrdude: NVM type 0: 16-bit, page oriented write
avrdude: Entering NVM programming mode
>>> read flash 0x3100 16 
3100  48 65 6c 6c 6f 2c 20 77  6f 72 6c 64 0a 00 ff ff  |Hello, world ...|

avrdude: Leaving NVM programming mode
$ echo 'write flash 0x3100 "hello, world\n"' | ./avrdude -qqp atmega4808 -c serialupdi -P /dev/cu.usbserial-1410 -t
avrdude: UPDI link initialization OK
avrdude: NVM type 0: 16-bit, page oriented write
avrdude: Entering NVM programming mode
>>> write flash 0x3100 "hello, world\n" 
avrdude: writing cache to device... avrdude: error: page erase not implemented yet
read/chip erase/write will take time ... done
avrdude: Leaving NVM programming mode
$ echo 'read flash 0x3100 16' | ./avrdude -qqp atmega4808 -c serialupdi -P /dev/cu.usbserial-1410 -t
avrdude: UPDI link initialization OK
avrdude: NVM type 0: 16-bit, page oriented write
avrdude: Entering NVM programming mode
>>> read flash 0x3100 16 
3100  68 65 6c 6c 6f 2c 20 77  6f 72 6c 64 0a 00 ff ff  |hello, world ...|

avrdude: Leaving NVM programming mode
jtag2updi + ATmega4808 (writing cache seemed quicker that other UPDI programmers)
$ echo erase | ./avrdude -qqp atmega4808 -c jtag2updi -P /dev/cu.usbserial-1410 -t
>>> erase 
avrdude: erasing chip
$ echo 'read flash 0x3100 16' | ./avrdude -qqp atmega4808 -c jtag2updi -P /dev/cu.usbserial-1410 -t
>>> read flash 0x3100 16 
3100  ff ff ff ff ff ff ff ff  ff ff ff ff ff ff ff ff  |................|

$ echo 'write flash 0x3100 "hello, world\n"' | ./avrdude -qqp atmega4808 -c jtag2updi -P /dev/cu.usbserial-1410 -t
>>> write flash 0x3100 "hello, world\n" 
avrdude: writing cache to device... done
$ echo 'read flash 0x3100 16' | ./avrdude -qqp atmega4808 -c jtag2updi -P /dev/cu.usbserial-1410 -t
>>> read flash 0x3100 16 
3100  68 65 6c 6c 6f 2c 20 77  6f 72 6c 64 0a 00 ff ff  |hello, world ...|

$ echo 'write flash 0x3100 "Hello, world\n"' | ./avrdude -qqp atmega4808 -c jtag2updi -P /dev/cu.usbserial-1410 -t
>>> write flash 0x3100 "Hello, world\n" 
avrdude: writing cache to device... done
$ echo 'read flash 0x3100 16' | ./avrdude -qqp atmega4808 -c jtag2updi -P /dev/cu.usbserial-1410 -t
>>> read flash 0x3100 16 
3100  48 65 6c 6c 6f 2c 20 77  6f 72 6c 64 0a 00 ff ff  |Hello, world ...|

$ echo 'write flash 0x3100 "hello, world\n"' | ./avrdude -qqp atmega4808 -c jtag2updi -P /dev/cu.usbserial-1410 -t
>>> write flash 0x3100 "hello, world\n" 
avrdude: writing cache to device... done
$ echo 'read flash 0x3100 16' | ./avrdude -qqp atmega4808 -c jtag2updi -P /dev/cu.usbserial-1410 -t
>>> read flash 0x3100 16 
3100  68 65 6c 6c 6f 2c 20 77  6f 72 6c 64 0a 00 ff ff  |hello, world ...|
avrispmkii + ATxmega128A3U (was very quick writing the cache)
$ echo erase | ./avrdude -qqp atxmega128a3u -c avrispmkii -t
>>> erase 
avrdude: erasing chip
$ echo 'read flash 0x3100 16' | ./avrdude -qqp atxmega128a3u -c avrispmkii -t
>>> read flash 0x3100 16 
3100  ff ff ff ff ff ff ff ff  ff ff ff ff ff ff ff ff  |................|

$ echo 'write flash 0x3100 "hello, world\n"' | ./avrdude -qqp atxmega128a3u -c avrispmkii -t
>>> write flash 0x3100 "hello, world\n" 
avrdude: writing cache to device... done
$ echo 'read flash 0x3100 16' | ./avrdude -qqp atxmega128a3u -c avrispmkii -t
>>> read flash 0x3100 16 
3100  68 65 6c 6c 6f 2c 20 77  6f 72 6c 64 0a 00 ff ff  |hello, world ...|

$ echo 'write flash 0x3100 "Hello, world\n"' | ./avrdude -qqp atxmega128a3u -c avrispmkii -t
>>> write flash 0x3100 "Hello, world\n" 
avrdude: writing cache to device... done
$ echo 'read flash 0x3100 16' | ./avrdude -qqp atxmega128a3u -c avrispmkii -t
>>> read flash 0x3100 16 
3100  48 65 6c 6c 6f 2c 20 77  6f 72 6c 64 0a 00 ff ff  |Hello, world ...|

$ echo 'write flash 0x3100 "hello, world\n"' | ./avrdude -qqp atxmega128a3u -c avrispmkii -t
>>> write flash 0x3100 "hello, world\n" 
avrdude: writing cache to device... done
$ echo 'read flash 0x3100 16' | ./avrdude -qqp atxmega128a3u -c avrispmkii -t
>>> read flash 0x3100 16 
3100  68 65 6c 6c 6f 2c 20 77  6f 72 6c 64 0a 00 ff ff  |hello, world ...|
dragon_jtag + ATxmega256A3BU (was very quick writing the cache)
$ echo erase | ./avrdude -qqp atxmega256a3bu -c dragon_jtag -t
>>> erase 
avrdude: erasing chip
$ echo 'read flash 0x3100 16' | ./avrdude -qqp atxmega256a3bu -c dragon_jtag -t
>>> read flash 0x3100 16 
3100  ff ff ff ff ff ff ff ff  ff ff ff ff ff ff ff ff  |................|

$ echo 'write flash 0x3100 "hello, world\n"' | ./avrdude -qqp atxmega256a3bu -c dragon_jtag -t
>>> write flash 0x3100 "hello, world\n" 
avrdude: writing cache to device... done
$ echo 'read flash 0x3100 16' | ./avrdude -qqp atxmega256a3bu -c dragon_jtag -t
>>> read flash 0x3100 16 
3100  68 65 6c 6c 6f 2c 20 77  6f 72 6c 64 0a 00 ff ff  |hello, world ...|

$ echo 'write flash 0x3100 "Hello, world\n"' | ./avrdude -qqp atxmega256a3bu -c dragon_jtag -t
>>> write flash 0x3100 "Hello, world\n" 
avrdude: writing cache to device... done
$ echo 'read flash 0x3100 16' | ./avrdude -qqp atxmega256a3bu -c dragon_jtag -t
>>> read flash 0x3100 16 
3100  48 65 6c 6c 6f 2c 20 77  6f 72 6c 64 0a 00 ff ff  |Hello, world ...|

$ echo 'write flash 0x3100 "hello, world\n"' | ./avrdude -qqp atxmega256a3bu -c dragon_jtag -t
>>> write flash 0x3100 "hello, world\n" 
avrdude: writing cache to device... done
$ echo 'read flash 0x3100 16' | ./avrdude -qqp atxmega256a3bu -c dragon_jtag -t
>>> read flash 0x3100 16 
3100  68 65 6c 6c 6f 2c 20 77  6f 72 6c 64 0a 00 ff ff  |hello, world ...|
dragon_isp + ATmega8535
echo erase | ./avrdude -qqp atmega8535 -c dragon_isp -t
>>> erase 
avrdude: erasing chip
$ echo 'read flash 0x1100 16' | ./avrdude -qqp atmega8535 -c dragon_isp -t
>>> read flash 0x1100 16 
1100  ff ff ff ff ff ff ff ff  ff ff ff ff ff ff ff ff  |................|

$ echo 'write flash 0x1100 "hello, world\n"' | ./avrdude -qqp atmega8535 -c dragon_isp -t
>>> write flash 0x1100 "hello, world\n" 
avrdude: writing cache to device... done
$ echo 'read flash 0x1100 16' | ./avrdude -qqp atmega8535 -c dragon_isp -t
>>> read flash 0x1100 16 
1100  68 65 6c 6c 6f 2c 20 77  6f 72 6c 64 0a 00 ff ff  |hello, world ...|

$ echo 'write flash 0x1100 "Hello, world\n"' | ./avrdude -qqp atmega8535 -c dragon_isp -t
>>> write flash 0x1100 "Hello, world\n" 
avrdude: writing cache to device... done
$ echo 'read flash 0x1100 16' | ./avrdude -qqp atmega8535 -c dragon_isp -t
>>> read flash 0x1100 16 
1100  48 65 6c 6c 6f 2c 20 77  6f 72 6c 64 0a 00 ff ff  |Hello, world ...|

$ echo 'write flash 0x1100 "hello, world\n"' | ./avrdude -qqp atmega8535 -c dragon_isp -t
>>> write flash 0x1100 "hello, world\n" 
avrdude: writing cache to device... avrdude: stk500v2_page_erase(): this function must never be called
read/chip erase/write will take time ... done
$ echo 'read flash 0x1100 16' | ./avrdude -qqp atmega8535 -c dragon_isp -t
>>> read flash 0x1100 16 
1100  68 65 6c 6c 6f 2c 20 77  6f 72 6c 64 0a 00 ff ff  |hello, world ...|
stk600 + ATmega2560 (writing cache slow as heck!)
$ echo erase | ./avrdude -qqp atmega2560 -c stk600 -t
>>> erase 
avrdude: erasing chip
$ echo 'read flash 0x3100 16' | ./avrdude -qqp atmega2560 -c stk600 -t
>>> read flash 0x3100 16 
3100  ff ff ff ff ff ff ff ff  ff ff ff ff ff ff ff ff  |................|

$ echo 'write flash 0x3100 "hello, world\n"' | ./avrdude -qqp atmega2560 -c stk600 -t
>>> write flash 0x3100 "hello, world\n" 
avrdude: writing cache to device... done
$ echo 'read flash 0x3100 16' | ./avrdude -qqp atmega2560 -c stk600 -t
>>> read flash 0x3100 16 
3100  68 65 6c 6c 6f 2c 20 77  6f 72 6c 64 0a 00 ff ff  |hello, world ...|

$ echo 'write flash 0x3100 "Hello, world\n"' | ./avrdude -qqp atmega2560 -c stk600 -t
>>> write flash 0x3100 "Hello, world\n" 
avrdude: writing cache to device... done
$ echo 'read flash 0x3100 16' | ./avrdude -qqp atmega2560 -c stk600 -t
>>> read flash 0x3100 16 
3100  48 65 6c 6c 6f 2c 20 77  6f 72 6c 64 0a 00 ff ff  |Hello, world ...|

$ echo 'write flash 0x3100 "hello, world\n"' | ./avrdude -qqp atmega2560 -c stk600 -t
>>> write flash 0x3100 "hello, world\n" 
avrdude: writing cache to device... avrdude: stk500v2_page_erase(): this function must never be called
read/chip erase/write will take time ... done
$ echo 'read flash 0x3100 16' | ./avrdude -qqp atmega2560 -c stk600 -t
>>> read flash 0x3100 16 
3100  68 65 6c 6c 6f 2c 20 77  6f 72 6c 64 0a 00 ff ff  |hello, world ...|
xboot/avr109/butterfly + ATmega2560 (just for fun really)
echo erase | ./avrdude -qqp atmega2560 -c butterfly -P /dev/cu.usbmodem14101 -b 115200 -t
Connecting to programmer: .
Found programmer: Id = "XBoot++"; type = S
    Software Version = 1.7; No Hardware Version given.
Programmer supports auto addr increment.
Programmer supports buffered memory access with buffersize=256 bytes.

Programmer supports the following devices:
    Device code: 0x7b

>>> erase 
avrdude: erasing chip
$ echo 'read flash 0x3100 16' | ./avrdude -qqp atmega2560 -c butterfly -P /dev/cu.usbmodem14101 -b 115200 -t
Connecting to programmer: .
Found programmer: Id = "XBoot++"; type = S
    Software Version = 1.7; No Hardware Version given.
Programmer supports auto addr increment.
Programmer supports buffered memory access with buffersize=256 bytes.

Programmer supports the following devices:
    Device code: 0x7b

>>> read flash 0x3100 16 
3100  ff ff ff ff ff ff ff ff  ff ff ff ff ff ff ff ff  |................|

$ echo 'write flash 0x3100 "hello, world\n"' | ./avrdude -qqp atmega2560 -c butterfly -P /dev/cu.usbmodem14101 -b 115200 -t
Connecting to programmer: .
Found programmer: Id = "XBoot++"; type = S
    Software Version = 1.7; No Hardware Version given.
Programmer supports auto addr increment.
Programmer supports buffered memory access with buffersize=256 bytes.

Programmer supports the following devices:
    Device code: 0x7b

>>> write flash 0x3100 "hello, world\n" 
avrdude: writing cache to device... flash verification error at addr 3100
$ echo 'read flash 0x3100 16' | ./avrdude -qqp atmega2560 -c butterfly -P /dev/cu.usbmodem14101 -b 115200 -t
Connecting to programmer: .
Found programmer: Id = "XBoot++"; type = S
    Software Version = 1.7; No Hardware Version given.
Programmer supports auto addr increment.
Programmer supports buffered memory access with buffersize=256 bytes.

Programmer supports the following devices:
    Device code: 0x7b

>>> read flash 0x3100 16 
3100  ff ff ff ff ff ff ff ff  ff ff ff ff ff ff ff ff  |................|

$ echo 'write flash 0x3100 "Hello, world\n"' | ./avrdude -qqp atmega2560 -c butterfly -P /dev/cu.usbmodem14101 -b 115200 -t
Connecting to programmer: .
Found programmer: Id = "XBoot++"; type = S
    Software Version = 1.7; No Hardware Version given.
Programmer supports auto addr increment.
Programmer supports buffered memory access with buffersize=256 bytes.

Programmer supports the following devices:
    Device code: 0x7b

>>> write flash 0x3100 "Hello, world\n" 
avrdude: writing cache to device... flash verification error at addr 3100
$ echo 'read flash 0x3100 16' | ./avrdude -qqp atmega2560 -c butterfly -P /dev/cu.usbmodem14101 -b 115200 -t
Connecting to programmer: .
Found programmer: Id = "XBoot++"; type = S
    Software Version = 1.7; No Hardware Version given.
Programmer supports auto addr increment.
Programmer supports buffered memory access with buffersize=256 bytes.

Programmer supports the following devices:
    Device code: 0x7b

>>> read flash 0x3100 16 
3100  ff ff ff ff ff ff ff ff  ff ff ff ff ff ff ff ff  |................|

$ echo 'write flash 0x3100 "hello, world\n"' | ./avrdude -qqp atmega2560 -c butterfly -P /dev/cu.usbmodem14101 -b 115200 -t
Connecting to programmer: .
Found programmer: Id = "XBoot++"; type = S
    Software Version = 1.7; No Hardware Version given.
Programmer supports auto addr increment.
Programmer supports buffered memory access with buffersize=256 bytes.

Programmer supports the following devices:
    Device code: 0x7b

>>> write flash 0x3100 "hello, world\n" 
avrdude: writing cache to device... flash verification error at addr 3100
$ echo 'read flash 0x3100 16' | ./avrdude -qqp atmega2560 -c butterfly -P /dev/cu.usbmodem14101 -b 115200 -t
Connecting to programmer: .
Found programmer: Id = "XBoot++"; type = S
    Software Version = 1.7; No Hardware Version given.
Programmer supports auto addr increment.
Programmer supports buffered memory access with buffersize=256 bytes.

Programmer supports the following devices:
    Device code: 0x7b

>>> read flash 0x3100 16 
3100  ff ff ff ff ff ff ff ff  ff ff ff ff ff ff ff ff  |................|
usbasp + ATmega1281
$ echo erase | ./avrdude -qqp atmega1281 -c usbasp -t
>>> erase 
avrdude: erasing chip
Bus error: 10
$ echo 'read flash 0x3100 16' | ./avrdude -qqp atmega1281 -c usbasp -t
>>> read flash 0x3100 16 
3100  ff ff ff ff ff ff ff ff  ff ff ff ff ff ff ff ff  |................|

$ echo 'write flash 0x3100 "hello, world\n"' | ./avrdude -qqp atmega1281 -c usbasp -t
>>> write flash 0x3100 "hello, world\n" 
avrdude: writing cache to device... done
$ echo 'read flash 0x3100 16' | ./avrdude -qqp atmega1281 -c usbasp -t
>>> read flash 0x3100 16 
3100  68 65 6c 6c 6f 2c 20 77  6f 72 6c 64 0a 00 ff ff  |hello, world ...|

$ echo 'write flash 0x3100 "Hello, world\n"' | ./avrdude -qqp atmega1281 -c usbasp -t
>>> write flash 0x3100 "Hello, world\n" 
avrdude: writing cache to device... done
$ echo 'read flash 0x3100 16' | ./avrdude -qqp atmega1281 -c usbasp -t
>>> read flash 0x3100 16 
3100  48 65 6c 6c 6f 2c 20 77  6f 72 6c 64 0a 00 ff ff  |Hello, world ...|

$ echo 'write flash 0x3100 "hello, world\n"' | ./avrdude -qqp atmega1281 -c usbasp -t
>>> write flash 0x3100 "hello, world\n" 
avrdude: writing cache to device... read/chip erase/write will take time ... done
$ echo 'read flash 0x3100 16' | ./avrdude -qqp atmega1281 -c usbasp -t
>>> read flash 0x3100 16 
3100  68 65 6c 6c 6f 2c 20 77  6f 72 6c 64 0a 00 ff ff  |hello, world ...|
usbtiny + ATmega128
$ echo erase | ./avrdude -qqp atmega128 -c usbtiny -t
>>> erase 
avrdude: erasing chip
$ echo 'read flash 0x3100 16' | ./avrdude -qqp atmega128 -c usbtiny -t
>>> read flash 0x3100 16 
3100  ff ff ff ff ff ff ff ff  ff ff ff ff ff ff ff ff  |................|

$ echo 'write flash 0x3100 "hello, world\n"' | ./avrdude -qqp atmega128 -c usbtiny -t
>>> write flash 0x3100 "hello, world\n" 
avrdude: writing cache to device... done
$ echo 'read flash 0x3100 16' | ./avrdude -qqp atmega128 -c usbtiny -t
>>> read flash 0x3100 16 
3100  68 65 6c 6c 6f 2c 20 77  6f 72 6c 64 0a 00 ff ff  |hello, world ...|

$ echo 'write flash 0x3100 "Hello, world\n"' | ./avrdude -qqp atmega128 -c usbtiny -t
>>> write flash 0x3100 "Hello, world\n" 
avrdude: writing cache to device... done
$ echo 'read flash 0x3100 16' | ./avrdude -qqp atmega128 -c usbtiny -t
>>> read flash 0x3100 16 
3100  48 65 6c 6c 6f 2c 20 77  6f 72 6c 64 0a 00 ff ff  |Hello, world ...|

$ echo 'write flash 0x3100 "hello, world\n"' | ./avrdude -qqp atmega128 -c usbtiny -t
>>> write flash 0x3100 "hello, world\n" 
avrdude: writing cache to device... read/chip erase/write will take time ... done
$ echo 'read flash 0x3100 16' | ./avrdude -qqp atmega128 -c usbtiny -t
>>> read flash 0x3100 16 
3100  68 65 6c 6c 6f 2c 20 77  6f 72 6c 64 0a 00 ff ff  |hello, world ...|

@stefanrueger
Copy link
Collaborator Author

funny warning when using the avrispmkii; stk500v2_page_erase(): this function must never be called.

Hilarious, indeed. This PR is one of the early adopters of pgm->page_erase(), and this has uncovered a few funny messages. These are outside this PR, and there is actually no harm done as far as I can tell. It's more like a reminder to clean up the mechanics of pgm->page_erase(). Explanation: The PR tries to utilise page erase if it's offered to avoid the costly chip erase. If the page erase balks the PR decides on a chip erase, so all we see are these messages.

progress bar when writing the cache in non-quell mode would be nice

Yes, long waits are much neater with progress bars:

$ echo 'write flash 0x3100 "hello, world\n"' | avrdude -p m328p -c usb-bub-ii -t
avrdude: AVR device initialized and ready to accept instructions

Reading | ################################################## | 100% 0.00s

avrdude: Device signature = 0x1e950f (probably m328p)
avrdude> write flash 0x3100 "hello, world\n"

Writing | ################################################## | 100% 0.07s

avrdude> avrdude: writing cache to device... 
Reading | ################################################## | 100% 17.84s
Erasing | ################################################## | 100% 0.04s
Writing | ################################################## | 100% 2.63s

@MCUdude and @mcuee: Many thanks for sterling and systematic testing. By and large the idea seems to work well, and it's good to see the terminal mode can now actually write to flash on the majority of devices. I am particularly pleased with jtag EEPROM writes now working in the terminal, too.

And yes, programming one bit on the ATmega2560 can be slooooow:

$ echo "write flash 0x3100 'h'" | avrdude -p m2560 -c usbtiny -t
vrdude: AVR device initialized and ready to accept instructions

Reading | ################################################## | 100% 0.00s

avrdude: Device signature = 0x1e9801 (probably m2560)
avrdude> write flash 0x3100 "hello, world\n"

Writing | ################################################## | 100% 0.25s

avrdude> avrdude: writing cache to device... 
Reading | ################################################## | 100% 339.52s
Erasing | ################################################## | 100% 0.06s
Writing | ################################################## | 100% 0.72s

I don't have ATxmega devices, so cannot test the different flash type memories such as application, apptable, and boot, but hope my previous commit works with them as well. They need to refer to the same internal cache at different offsets, of course.

@stefanrueger
Copy link
Collaborator Author

xboot/avr109/butterfly + ATmega2560

Any insights why this combo doesn't work in terminal mode? Does it work with -U?

@stefanrueger
Copy link
Collaborator Author

avrispmkii + ATxmega128A3U (was very quick writing the cache)

I expect all xmegas and the newer UPDI interfaces to be vvv quick owing to page erase. No need to download the whole chip, erase it and upload it again...

@MCUdude
Copy link
Collaborator

MCUdude commented Oct 4, 2022

Thanks for the progress bar @stefanrueger! STK600 output below. The STK600 was way faster once I added -B1.

We should probably look into the page_erase functionality sometime. Currently, jtag3.c does support page erase on Xmegas, but not AVRs with UPDI, even though I suspect the procedure is more or less the same:

avrdude/src/jtag3.c

Lines 1690 to 1694 in 3b8f41c

if (!(p->prog_modes & PM_PDI)) {
avrdude_message(MSG_INFO, "%s: jtag3_page_erase: not an Xmega device\n",
progname);
return -1;
}

I tried to add PM_UPDI, but it still wanted to write the entire flash contents on exit. Not sure why.

echo erase | ./avrdude -p atmega2560 -c stk600 -b 115200 -t -B1

avrdude: AVR device initialized and ready to accept instructions

Reading | ################################################## | 100% 0.00s

avrdude: Device signature = 0x1e9801 (probably m2560)
>>> erase 
avrdude: erasing chip

avrdude done.  Thank you.

$ echo 'read flash 0x3100 16' | ./avrdude -p atmega2560 -c stk600 -b 115200 -t

avrdude: AVR device initialized and ready to accept instructions

Reading | ################################################## | 100% 0.00s

avrdude: Device signature = 0x1e9801 (probably m2560)
>>> read flash 0x3100 16 

Reading | ################################################## | 100% 0.01s

3100  ff ff ff ff ff ff ff ff  ff ff ff ff ff ff ff ff  |................|


avrdude done.  Thank you.

$ echo 'write flash 0x3100 "hello, world\n"' | ./avrdude -p atmega2560 -c stk600 -b 115200 -t

avrdude: AVR device initialized and ready to accept instructions

Reading | ################################################## | 100% 0.00s

avrdude: Device signature = 0x1e9801 (probably m2560)
>>> write flash 0x3100 "hello, world\n" 

Writing | ################################################## | 100% 0.01s

avrdude: writing cache to device... done

avrdude done.  Thank you.

$ echo 'read flash 0x3100 16' | ./avrdude -p atmega2560 -c stk600 -b 115200 -t

avrdude: AVR device initialized and ready to accept instructions

Reading | ################################################## | 100% 0.00s

avrdude: Device signature = 0x1e9801 (probably m2560)
>>> read flash 0x3100 16 

Reading | ################################################## | 100% 0.01s

3100  68 65 6c 6c 6f 2c 20 77  6f 72 6c 64 0a 00 ff ff  |hello, world ...|


avrdude done.  Thank you.

$ echo 'write flash 0x3100 "Hello, world\n"' | ./avrdude -p atmega2560 -c stk600 -b 115200 -t

avrdude: AVR device initialized and ready to accept instructions

Reading | ################################################## | 100% 0.00s

avrdude: Device signature = 0x1e9801 (probably m2560)
>>> write flash 0x3100 "Hello, world\n" 

Writing | ################################################## | 100% 0.01s

avrdude: writing cache to device... done

avrdude done.  Thank you.

$ echo 'read flash 0x3100 16' | ./avrdude -p atmega2560 -c stk600 -b 115200 -t

avrdude: AVR device initialized and ready to accept instructions

Reading | ################################################## | 100% 0.00s

avrdude: Device signature = 0x1e9801 (probably m2560)
>>> read flash 0x3100 16 

Reading | ################################################## | 100% 0.01s

3100  48 65 6c 6c 6f 2c 20 77  6f 72 6c 64 0a 00 ff ff  |Hello, world ...|


avrdude done.  Thank you.

$ echo 'write flash 0x3100 "hello, world\n"' | ./avrdude -p atmega2560 -c stk600 -b 115200 -t

avrdude: AVR device initialized and ready to accept instructions

Reading | ################################################## | 100% 0.00s

avrdude: Device signature = 0x1e9801 (probably m2560)
>>> write flash 0x3100 "hello, world\n" 

Writing | ################################################## | 100% 0.01s

avrdude: writing cache to device... avrdude: stk500v2_page_erase(): this function must never be called

Reading | ################################################## | 100% 12.80s
Erasing | ################################################## | 100% 0.08s
Writing | ################################################## | 100% 0.02s

avrdude done.  Thank you.

$ echo 'read flash 0x3100 16' | ./avrdude -p atmega2560 -c stk600 -b 115200 -t

avrdude: AVR device initialized and ready to accept instructions

Reading | ################################################## | 100% 0.00s

avrdude: Device signature = 0x1e9801 (probably m2560)
>>> read flash 0x3100 16 

Reading | ################################################## | 100% 0.01s

3100  68 65 6c 6c 6f 2c 20 77  6f 72 6c 64 0a 00 ff ff  |hello, world ...|


avrdude done.  Thank you.

@MCUdude
Copy link
Collaborator

MCUdude commented Oct 4, 2022

I don't have ATxmega devices, so cannot test the different flash type memories such as application, apptable, and boot, but hope my previous commit works with them as well. They need to refer to the same internal cache at different offsets, of course.

Seems to work just fine!

avrispmkii + ATxmega128A3U boot
$ echo erase | ./avrdude -qqp atxmega128a3u -c avrispmkii -b 115200 -t -B1
>>> erase 
avrdude: erasing chip
$ echo 'read boot 0x100 16' | ./avrdude -qqp atxmega128a3u -c avrispmkii -b 115200 -t
>>> read boot 0x100 16 
0100  ff ff ff ff ff ff ff ff  ff ff ff ff ff ff ff ff  |................|

$ echo 'write boot 0x100 "hello, world\n"' | ./avrdude -qqp atxmega128a3u -c avrispmkii -b 115200 -t
>>> write boot 0x100 "hello, world\n" 
avrdude: writing cache to device... done
$ echo 'read boot 0x100 16' | ./avrdude -qqp atxmega128a3u -c avrispmkii -b 115200 -t
>>> read boot 0x100 16 
0100  68 65 6c 6c 6f 2c 20 77  6f 72 6c 64 0a 00 ff ff  |hello, world ...|

$ echo 'write boot 0x100 "Hello, world\n"' | ./avrdude -qqp atxmega128a3u -c avrispmkii -b 115200 -t
>>> write boot 0x100 "Hello, world\n" 
avrdude: writing cache to device... done
$ echo 'read boot 0x100 16' | ./avrdude -qqp atxmega128a3u -c avrispmkii -b 115200 -t
>>> read boot 0x100 16 
0100  48 65 6c 6c 6f 2c 20 77  6f 72 6c 64 0a 00 ff ff  |Hello, world ...|

$ echo 'write boot 0x100 "hello, world\n"' | ./avrdude -qqp atxmega128a3u -c avrispmkii -b 115200 -t
>>> write boot 0x100 "hello, world\n" 
avrdude: writing cache to device... done
$ echo 'read boot 0x100 16' | ./avrdude -qqp atxmega128a3u -c avrispmkii -b 115200 -t
>>> read boot 0x100 16 
0100  68 65 6c 6c 6f 2c 20 77  6f 72 6c 64 0a 00 ff ff  |hello, world ...|
avrispmkii + ATxmega128A3U application
echo erase | ./avrdude -qqp atxmega128a3u -c avrispmkii -b 115200 -t -B1
>>> erase 
avrdude: erasing chip
$ echo 'read application 0x100 16' | ./avrdude -qqp atxmega128a3u -c avrispmkii -b 115200 -t
>>> read application 0x100 16 
0100  ff ff ff ff ff ff ff ff  ff ff ff ff ff ff ff ff  |................|

$ echo 'write application 0x100 "hello, world\n"' | ./avrdude -qqp atxmega128a3u -c avrispmkii -b 115200 -t
>>> write application 0x100 "hello, world\n" 
avrdude: writing cache to device... done
$ echo 'read application 0x100 16' | ./avrdude -qqp atxmega128a3u -c avrispmkii -b 115200 -t
>>> read application 0x100 16 
0100  68 65 6c 6c 6f 2c 20 77  6f 72 6c 64 0a 00 ff ff  |hello, world ...|

$ echo 'write application 0x100 "Hello, world\n"' | ./avrdude -qqp atxmega128a3u -c avrispmkii -b 115200 -t
>>> write application 0x100 "Hello, world\n" 
avrdude: writing cache to device... done
$ echo 'read application 0x100 16' | ./avrdude -qqp atxmega128a3u -c avrispmkii -b 115200 -t
>>> read application 0x100 16 
0100  48 65 6c 6c 6f 2c 20 77  6f 72 6c 64 0a 00 ff ff  |Hello, world ...|

$ echo 'write application 0x100 "hello, world\n"' | ./avrdude -qqp atxmega128a3u -c avrispmkii -b 115200 -t
>>> write application 0x100 "hello, world\n" 
avrdude: writing cache to device... done
$ echo 'read application 0x100 16' | ./avrdude -qqp atxmega128a3u -c avrispmkii -b 115200 -t
>>> read application 0x100 16 
0100  68 65 6c 6c 6f 2c 20 77  6f 72 6c 64 0a 00 ff ff  |hello, world ...|
avrispmkii + ATxmega128A3U apptable
echo erase | ./avrdude -qqp atxmega128a3u -c avrispmkii -b 115200 -t -B1
>>> erase 
avrdude: erasing chip
$ echo 'read apptable 0x1000 16' | ./avrdude -qqp atxmega128a3u -c avrispmkii -b 115200 -t
>>> read apptable 0x1000 16 
1000  ff ff ff ff ff ff ff ff  ff ff ff ff ff ff ff ff  |................|

$ echo 'write apptable 0x1000 "hello, world\n"' | ./avrdude -qqp atxmega128a3u -c avrispmkii -b 115200 -t
>>> write apptable 0x1000 "hello, world\n" 
avrdude: writing cache to device... done
$ echo 'read apptable 0x1000 16' | ./avrdude -qqp atxmega128a3u -c avrispmkii -b 115200 -t
>>> read apptable 0x1000 16 
1000  68 65 6c 6c 6f 2c 20 77  6f 72 6c 64 0a 00 ff ff  |hello, world ...|

$ echo 'write apptable 0x1000 "Hello, world\n"' | ./avrdude -qqp atxmega128a3u -c avrispmkii -b 115200 -t
>>> write apptable 0x1000 "Hello, world\n" 
avrdude: writing cache to device... done
$ echo 'read apptable 0x1000 16' | ./avrdude -qqp atxmega128a3u -c avrispmkii -b 115200 -t
>>> read apptable 0x1000 16 
1000  48 65 6c 6c 6f 2c 20 77  6f 72 6c 64 0a 00 ff ff  |Hello, world ...|

$ echo 'write apptable 0x1000 "hello, world\n"' | ./avrdude -qqp atxmega128a3u -c avrispmkii -b 115200 -t
>>> write apptable 0x1000 "hello, world\n" 
avrdude: writing cache to device... done
$ echo 'read apptable 0x1000 16' | ./avrdude -qqp atxmega128a3u -c avrispmkii -b 115200 -t
>>> read apptable 0x1000 16 
1000  68 65 6c 6c 6f 2c 20 77  6f 72 6c 64 0a 00 ff ff  |hello, world ...|

@stefanrueger
Copy link
Collaborator Author

The STK600 was way faster once I added -B1

Glad to hear. But how can avrdude read 256k via 115200 baud in 12.8 s? It takes a minimum of 23 s at that baud rate...

$ echo 'write flash 0x3100 "hello, world\n"' | ./avrdude -p atmega2560 -c stk600 -b 115200 -t
...
Reading | ################################################## | 100% 12.80s
Erasing | ################################################## | 100% 0.08s
Writing | ################################################## | 100% 0.02s

Or is the baudrate something nominal and the real comms speed much higher? Or does the STK600 protocol have some compression over the comms line?

And why is the USBtiny so slow, indeed? An effective throughput below 9600 baud...

[application, apptable, boot] seems to work just fine!

And when you write "Hello, apptable\n" to apptable 0 and read the corresponding address from flash, still there? And vice versa?

@MCUdude
Copy link
Collaborator

MCUdude commented Oct 5, 2022

Glad to hear. But how can avrdude read 256k via 115200 baud in 12.8 s? It takes a minimum of 23 s at that baud rate...

The first command sets -B1, which is something like a 1us/1MHz SPI clock speed. This is stored in the programmer until the next power cycle. The -b 115200 was something I forgot to remove before pasting the commands, but I suspect it ignores it, as the baud rate isn't really relevant on a USB-based programmer like the STK600 is.

And why is the USBtiny so slow, indeed? An effective throughput below 9600 baud...

You can try to add -B1 to each command to see if it helps. I didn't, and it took forever to write to an ATmega2560. I did this before you added the progress bar, so I don't know exactly how long it took.

@mcuee
Copy link
Collaborator

mcuee commented Oct 5, 2022

The STK600 was way faster once I added -B1.

@MCUdude
Yes it is the same for my AVRISP mkii clone.

Ref: my test result under Linux, not as fast as your STK600 of 12.8s but still quite fast (14.52s).

mcuee@UbuntuSwift3:~/build/avr$ avrdude -c avrispmkii -p m2560 -B 1 
-U flash:r:readback_m2560_avrispmkii_B1.hex:i 
avrdude: AVR device initialized and ready to accept instructions
Reading | ################################################## | 100% 0.00s
avrdude: Device signature = 0x1e9801 (probably m2560)
avrdude: reading flash memory:
Reading | ################################################## | 100% 14.52s
avrdude: writing output file "readback_m2560_avrispmkii_B1.hex"
avrdude done.  Thank you.

@MCUdude
Copy link
Collaborator

MCUdude commented Oct 5, 2022

Ref: my test result under Linux, not as fast as your STK600 of 12.8s but still quite fast (14.52s).

This may be because the avrispmkii uses a USB chip (pdiusbd12), while the STK600 uses an AVR, AT90USB1287, with native USB support.

@mcuee
Copy link
Collaborator

mcuee commented Oct 5, 2022

And why is the USBtiny so slow, indeed? An effective throughput below 9600 baud...

@stefanrueger

USBtiny is slow, adding -B1 does help, but still slow. usbasp is much faster than USBtiny.

Please refer to my test result here.

mcuee@UbuntuSwift3:~/build/avr/avrdude_sr/bin$ ./avrdude_pr1029 -c usbtiny -p m2560 -B1 
-U flash:r:m2560_readback_pr1029.hex:i

avrdude_pr1029: AVR device initialized and ready to accept instructions

Reading | ################################################## | 100% 0.00s

avrdude_pr1029: Device signature = 0x1e9801 (probably m2560)
avrdude_pr1029: reading flash memory:

Reading | ################################################## | 100% 186.50s

avrdude_pr1029: writing output file "m2560_readback_pr1029.hex"

avrdude_pr1029 done.  Thank you.

BTW, I have consolidated some benchmark results here.

 - Added the syntax report_progress(1, -1, NULL) to abort a report neatly on
   detection of errors. For example aborting in the middle looks like

   Writing | #########################------------------------- | 50% 0.73s

 - In terminal, made a careful distinction between reporting Caching (for
   eeprom/flash) and Writing (other mem types)

 - Also did slight code refactoring
@stefanrueger
Copy link
Collaborator Author

  • Slight code refactoring
  • In terminal, made a careful distinction between reporting Caching (for eeprom/flash) and Writing (other mem types)
  • Added the syntax report_progress(1, -1, NULL) to abort a report neatly on detection of errors.
$ echo "write flash 0x3100 'h'" | avrdude -p m328p -c usbtiny -t

avrdude: AVR device initialized and ready to accept instructions

Reading | ################################################## | 100% 0.00s

avrdude: Device signature = 0x1e950f (probably m328p)
avrdude> write flash 0x3100 'h'

Caching | ################################################## | 100% 0.07s

avrdude> avrdude: synching cache to device...
Reading | ################################################## | 100% 18.86s
Erasing | ################################################## | 100% 0.05s
Writing | #########################------------------------- | 50% 0.73s

avrdude: flash verification error at addr 0x0200

avrdude done.  Thank you.

Now, I am happy with the current state of this PR.

I could suppress the funny warnings for not implemented page erase functions, but I think that serves as useful reminder to us(*) to have a close look at proper implementation of page erase for UPDI etc.

(*) us means in this context anyone but me ;) I don't have the hardware to test the page erase functionality.

Will do a squash merge soon unless I hear otherwise.

@MCUdude
Copy link
Collaborator

MCUdude commented Oct 5, 2022

I could suppress the funny warnings for not implemented page erase functions, but I think that serves as useful reminder to us(*) to have a close look at proper implementation of page erase for UPDI etc.

It appears to me that it's impossible to perform a page erase over ISP, is this correct? At least, it seems like no ISP programmer implementation supports page erase over ISP. As for UPDI, page erase should be implemented for JTAG3/EDBG and serialupdi. I'll look into the JTAG3 part and see if I can figure it out for UPDI targets.

Maybe @dbuchwald can look into the SerialUPDI page erase functionality, now that Avrdude can utilize this in a useful way?

@stefanrueger
Copy link
Collaborator Author

It appears to me that it's impossible to perform a page erase over ISP, is this correct?

Correct. Though bootloaders on parts with ISP interface can (and do) erase a page using SPM.

I still plan to furnish my (overdue) urclock programmer with (optional) page erase functionality if the boodloader signals that it provides that separately. Normally, however, bootloaders would just erase a page before they write it, that is, for them memory does not look like NOR-memory that cannot set a bit once cleared.

This PR just checks the existence of pgm->page_erase, and if that exists then it's called and if furthermore that works out it will be used: https://github.com/stefanrueger/avrdude/blob/8be06f4cb342a5558f15c017ae258453d334af2b/src/avrcache.c#L345-L355

@stefanrueger
Copy link
Collaborator Author

The other aspect of page_erase is that it's a programmer function that I take to be applicable to all eeprom and flash like memories, just like paged_load and paged_write. So, any implementation ideally caters for all these, though the caller should be prepared to see page_erase return -1.

@MCUdude
Copy link
Collaborator

MCUdude commented Oct 5, 2022

Correct. Though bootloaders on parts with ISP interface can (and do) erase a page using SPM.

Since pgm->page_erase is always tried first, regardless of target and programming interface, we should probably remove silly warnings like "this function must never be called", since there's no way to perform a page erase anyways.

BTW I think I figured how to get flash page erase working on UPDI targets using a JTAG3 compatible programmer. I'll submit a PR or open an issue regarding this tomorrow.

Without jtag3 UPDI page erase fix
$ echo erase | ./avrdude -p avr128db48 -c pkobn_updi -t 

         Vtarget                      : 3.31 V
         PDI/UPDI clock Xmega/megaAVR : 100 kHz

avrdude: AVR device initialized and ready to accept instructions

Reading | ################################################## | 100% 0.01s

avrdude: Device signature = 0x1e970c (probably avr128db48)
>>> erase 
avrdude: erasing chip

avrdude done.  Thank you.

$ echo 'read flash 0x1000 16' | ./avrdude -p avr128db48 -c pkobn_updi -t

         Vtarget                      : 3.31 V
         PDI/UPDI clock Xmega/megaAVR : 100 kHz

avrdude: AVR device initialized and ready to accept instructions

Reading | ################################################## | 100% 0.01s

avrdude: Device signature = 0x1e970c (probably avr128db48)
>>> read flash 0x1000 16 

Reading | ################################################## | 100% 0.09s

1000  ff ff ff ff ff ff ff ff  ff ff ff ff ff ff ff ff  |................|


avrdude done.  Thank you.

$ echo 'write flash 0x1000 "hello, world\n"' | ./avrdude -p avr128db48 -c pkobn_updi -t

         Vtarget                      : 3.31 V
         PDI/UPDI clock Xmega/megaAVR : 100 kHz

avrdude: AVR device initialized and ready to accept instructions

Reading | ################################################## | 100% 0.01s

avrdude: Device signature = 0x1e970c (probably avr128db48)
>>> write flash 0x1000 "hello, world\n" 

Writing | ################################################## | 100% 0.09s

avrdude: writing cache to device... done

avrdude done.  Thank you.

$ echo 'read flash 0x1000 16' | ./avrdude -p avr128db48 -c pkobn_updi -t

         Vtarget                      : 3.31 V
         PDI/UPDI clock Xmega/megaAVR : 100 kHz

avrdude: AVR device initialized and ready to accept instructions

Reading | ################################################## | 100% 0.01s

avrdude: Device signature = 0x1e970c (probably avr128db48)
>>> read flash 0x1000 16 

Reading | ################################################## | 100% 0.09s

1000  68 65 6c 6c 6f 2c 20 77  6f 72 6c 64 0a 00 ff ff  |hello, world ...|


avrdude done.  Thank you.

$ echo 'write flash 0x1000 "Hello, world\n"' | ./avrdude -p avr128db48 -c pkobn_updi -t

         Vtarget                      : 3.31 V
         PDI/UPDI clock Xmega/megaAVR : 100 kHz

avrdude: AVR device initialized and ready to accept instructions

Reading | ################################################## | 100% 0.01s

avrdude: Device signature = 0x1e970c (probably avr128db48)
>>> write flash 0x1000 "Hello, world\n" 

Writing | ################################################## | 100% 0.09s

avrdude: writing cache to device... done

avrdude done.  Thank you.

$ echo 'read flash 0x1000 16' | ./avrdude -p avr128db48 -c pkobn_updi -t

         Vtarget                      : 3.31 V
         PDI/UPDI clock Xmega/megaAVR : 100 kHz

avrdude: AVR device initialized and ready to accept instructions

Reading | ################################################## | 100% 0.01s

avrdude: Device signature = 0x1e970c (probably avr128db48)
>>> read flash 0x1000 16 

Reading | ################################################## | 100% 0.09s

1000  48 65 6c 6c 6f 2c 20 77  6f 72 6c 64 0a 00 ff ff  |Hello, world ...|


avrdude done.  Thank you.

$ echo 'write flash 0x1000 "hello, world\n"' | ./avrdude -p avr128db48 -c pkobn_updi -t

         Vtarget                      : 3.31 V
         PDI/UPDI clock Xmega/megaAVR : 100 kHz

avrdude: AVR device initialized and ready to accept instructions

Reading | ################################################## | 100% 0.01s

avrdude: Device signature = 0x1e970c (probably avr128db48)
>>> write flash 0x1000 "hello, world\n" 

Writing | ################################################## | 100% 0.09s

avrdude: writing cache to device... avrdude: jtag3_page_erase: not an Xmega device

Reading | ################################################## | 100% 21.94s
Erasing | ################################################## | 100% 0.02s
Writing | ################################################## | 100% 0.24s

avrdude done.  Thank you.

$ echo 'read flash 0x1000 16' | ./avrdude -p avr128db48 -c pkobn_updi -t

         Vtarget                      : 3.31 V
         PDI/UPDI clock Xmega/megaAVR : 100 kHz

avrdude: AVR device initialized and ready to accept instructions

Reading | ################################################## | 100% 0.01s

avrdude: Device signature = 0x1e970c (probably avr128db48)
>>> read flash 0x1000 16 

Reading | ################################################## | 100% 0.09s

1000  68 65 6c 6c 6f 2c 20 77  6f 72 6c 64 0a 00 ff ff  |hello, world ...|


avrdude done.  Thank you.
With jtag3 UPDI page erase fix
echo erase | ./avrdude -p avr128db48 -c pkobn_updi -t 

         Vtarget                      : 3.31 V
         PDI/UPDI clock Xmega/megaAVR : 100 kHz

avrdude: AVR device initialized and ready to accept instructions

Reading | ################################################## | 100% 0.01s

avrdude: Device signature = 0x1e970c (probably avr128db48)
>>> erase 
avrdude: erasing chip

avrdude done.  Thank you.

$ echo 'read flash 0x1000 16' | ./avrdude -p avr128db48 -c pkobn_updi -t

         Vtarget                      : 3.31 V
         PDI/UPDI clock Xmega/megaAVR : 100 kHz

avrdude: AVR device initialized and ready to accept instructions

Reading | ################################################## | 100% 0.01s

avrdude: Device signature = 0x1e970c (probably avr128db48)
>>> read flash 0x1000 16 

Reading | ################################################## | 100% 0.09s

1000  ff ff ff ff ff ff ff ff  ff ff ff ff ff ff ff ff  |................|


avrdude done.  Thank you.

$ echo 'write flash 0x1000 "hello, world\n"' | ./avrdude -p avr128db48 -c pkobn_updi -t

         Vtarget                      : 3.31 V
         PDI/UPDI clock Xmega/megaAVR : 100 kHz

avrdude: AVR device initialized and ready to accept instructions

Reading | ################################################## | 100% 0.01s

avrdude: Device signature = 0x1e970c (probably avr128db48)
>>> write flash 0x1000 "hello, world\n" 

Writing | ################################################## | 100% 0.09s

avrdude: writing cache to device... done

avrdude done.  Thank you.

$ echo 'read flash 0x1000 16' | ./avrdude -p avr128db48 -c pkobn_updi -t

         Vtarget                      : 3.31 V
         PDI/UPDI clock Xmega/megaAVR : 100 kHz

avrdude: AVR device initialized and ready to accept instructions

Reading | ################################################## | 100% 0.01s

avrdude: Device signature = 0x1e970c (probably avr128db48)
>>> read flash 0x1000 16 

Reading | ################################################## | 100% 0.09s

1000  68 65 6c 6c 6f 2c 20 77  6f 72 6c 64 0a 00 ff ff  |hello, world ...|


avrdude done.  Thank you.

$ echo 'write flash 0x1000 "Hello, world\n"' | ./avrdude -p avr128db48 -c pkobn_updi -t

         Vtarget                      : 3.31 V
         PDI/UPDI clock Xmega/megaAVR : 100 kHz

avrdude: AVR device initialized and ready to accept instructions

Reading | ################################################## | 100% 0.01s

avrdude: Device signature = 0x1e970c (probably avr128db48)
>>> write flash 0x1000 "Hello, world\n" 

Writing | ################################################## | 100% 0.09s

avrdude: writing cache to device... done

avrdude done.  Thank you.

$ echo 'read flash 0x1000 16' | ./avrdude -p avr128db48 -c pkobn_updi -t

         Vtarget                      : 3.31 V
         PDI/UPDI clock Xmega/megaAVR : 100 kHz

avrdude: AVR device initialized and ready to accept instructions

Reading | ################################################## | 100% 0.01s

avrdude: Device signature = 0x1e970c (probably avr128db48)
>>> read flash 0x1000 16 

Reading | ################################################## | 100% 0.09s

1000  48 65 6c 6c 6f 2c 20 77  6f 72 6c 64 0a 00 ff ff  |Hello, world ...|


avrdude done.  Thank you.

$ echo 'write flash 0x1000 "hello, world\n"' | ./avrdude -p avr128db48 -c pkobn_updi -t

         Vtarget                      : 3.31 V
         PDI/UPDI clock Xmega/megaAVR : 100 kHz

avrdude: AVR device initialized and ready to accept instructions

Reading | ################################################## | 100% 0.01s

avrdude: Device signature = 0x1e970c (probably avr128db48)
>>> write flash 0x1000 "hello, world\n" 

Writing | ################################################## | 100% 0.09s

avrdude: writing cache to device... done

avrdude done.  Thank you.

$ echo 'read flash 0x1000 16' | ./avrdude -p avr128db48 -c pkobn_updi -t

         Vtarget                      : 3.31 V
         PDI/UPDI clock Xmega/megaAVR : 100 kHz

avrdude: AVR device initialized and ready to accept instructions

Reading | ################################################## | 100% 0.01s

avrdude: Device signature = 0x1e970c (probably avr128db48)
>>> read flash 0x1000 16 

Reading | ################################################## | 100% 0.09s

1000  68 65 6c 6c 6f 2c 20 77  6f 72 6c 64 0a 00 ff ff  |hello, world ...|


avrdude done.  Thank you.

@stefanrueger
Copy link
Collaborator Author

remove silly warnings like "this function must never be called"

Yes, the programmer should not say this. It should rather not offer pgm->page_erase, ie, set it to NULL. It's one of those functions that are not mandatory in the programmer and which the caller is obliged to check for existence first. This is outside this PR, though.

figured how to get flash page erase working on UPDI targets using a JTAG3 compatible programmer

Vvv cool. Cannot wait to see the PR!

@stefanrueger stefanrueger merged commit d74b17b into avrdudes:main Oct 5, 2022
@stefanrueger stefanrueger deleted the avr_cache branch October 5, 2022 21:16
MCUdude added a commit to MCUdude/avrdude that referenced this pull request Oct 5, 2022
Very handy to have now that avrdudes#1106 is merged
@MCUdude
Copy link
Collaborator

MCUdude commented Oct 5, 2022

Vvv cool. Cannot wait to see the PR!

I've pushed the fix here. It's just a few code lines, but it takes time to track something like this down.
https://github.com/MCUdude/avrdude/tree/jtag3-page-erase-updi

Now all we need is page erase functionality for SerialUPDI!

@stefanrueger
Copy link
Collaborator Author

I've pushed the fix here.

Brill - vvv cool to see page erase coming along!

@mcuee
Copy link
Collaborator

mcuee commented Oct 6, 2022

Vvv cool. Cannot wait to see the PR!

I've pushed the fix here. It's just a few code lines, but it takes time to track something like this down. https://github.com/MCUdude/avrdude/tree/jtag3-page-erase-updi

Now all we need is page erase functionality for SerialUPDI!

@MCUdude

I think it is good to create a PR with your fix without wating for serialupidi, as your fix already works for JTAG3 based updi programmers.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants