Standalone use of atmega644p / 164p

Hi guys,

I've found that the digital I/O on the 328 have been insufficient for a few projects, so I've been trying to get a 644p and a 164p working standalone on breadboard. I've done a lot of standalone 328ing in the past by bootloading them with arduino-as-ISP and hooking an empty duemilanove's Rx / Tx to the chips on perfboard.

Anyway, I've tried using the Calunium 644p, Remotuino 164, Duino 644p and sanguino 644p files but keep running into the same hitch. I'm able to bootload them using the duemilanove as ISP. But then when I take the 328 out of the arduino, and connect the Rx / Tx's to the 644p and try to upload blink as I always have with 328s, I just always get the classic "avrdude: stk500_recv(): programmer is not responding", though I've tried both sets of UARTs.

Is there something extra about this process that I'm missing? If anyone has any ideas, I'd love to hear them

Thanks a lot

How are you clocking the 644P?

With a 16mhz crystal and 2 18pf ceramic capacitors.

Cheers

Is there a reason you want to use a bootloader?

This is a good question.

The main reason is that all of my standalone projects are fitted with 4-pin plugs that with a wee shield+cable that I made can be programmed. Sure, it would be possible to make another and switch it out depending on which box I'm currently programming (or buy a standalone programmer for these boxes) but I've seen a number of tutorials out there that make this 'bootloading-and-programming-a-standalone-644-with-arduino-IDE' seem trivial, so it seems like I should be able to get it to work...

Thanks for your replies

Does anything here help (the 1284 is essentially the same processor with more memory)...

so it seems like I should be able to get it to work...

It will work, it has to. :slight_smile:

Does the baud rate correspond to what the bootloader uses?

How do you reset the target, did you also connect the reset pin's of the duemilanova board to the target? (Actually a picture would be useful.)

Does the bootloader do anything? If you reset the target does it blink a led?
I have a sanguino rbk (a 644p) that still has the original bootloader, it briefly blinks arduino pin 0 after reset.

I have never updated the bootloader but let's say it is time to do so now. I'll burn the latest bootloader from the sanguino project (for arduino 1.0.1) so we can compare behavior.

(Right now I use arduino 1.0.1 with the mighty 1284 stuff that coding badly refers to. But there is no boot loader for the 644p over there.)

Thanks for the link Coding Badly. I did follow that page, and also left a comment there a few days ago (awaiting moderation) about whether a 164/324/644 version of the Mighty software may be forthcoming.

I tried starting again from the beginning with the Sanguino bootloader, and it works as expected. Also, with just the bootloader, arduino pin 0 is blinking indefinitely. So I went back to try the same thing again with the "Calunium 644P (Stripboard)" bootloader and get the same result as before. ( "avrdude: stk500_recv(): programmer is not responding" on trying to upload a sketch).

Now, naturally I'm not so concerned about that since it's working with the Sanguino loader, but it could be useful to others if it was found out why Calunium isn't working for me. So to answer your questions :

  • I'm resetting by connecting pin D10 from arduino-as-ISP during bootloading, and by connecting reset pin to reset pin during sketch upload

  • I haven't seen any pins blink from the Calunium bootloader

As for the baud rate corresponding to what the bootloader uses, in the Calunium boards.txt I see the line "cal644p_strip_16.upload.speed=38400". But that would dictate both the bootloader's upload speed, and the
sketch upload speed, wouldn't it?

Finally, now that I've got it going on 644p, I'd love to also get it going on my 164p... it seems most of these projects focus on the 1284p and the 644p, but the 164p is about half the price of the 1284p where I live, and fine for those mainly interested in a DIP with more I/O and 2 UARTs, but not so concerned about more flash/sram/eeprom. Do you think it's possible to make a few number changes to the Sanguino 644p software to get it to support 164p? Or is it a lot more involved than that..

Thanks again

It is worth trying. Two things would be needed: core files and a bootloader.

Based on the ideas described here: Alternate CORE files for Arduino I would expect that the core files for the sanguino or the 1284 would work as is because the chips are pin compatible.

I checked out the optiboot sources and made a rough attempt to build a booter for the atmega168p. This patch file describes my modifications (patch -p1 < patch_file when positioned in the optiboot root dir applies them):

diff -r cc5e4843feec optiboot/bootloaders/optiboot/Makefile
--- a/optiboot/bootloaders/optiboot/Makefile    Tue Apr 03 00:51:23 2012 -0700
+++ b/optiboot/bootloaders/optiboot/Makefile    Wed Oct 03 00:10:06 2012 +0200
@@ -265,6 +265,25 @@
 atmega1284_isp: EFUSE = FD
 atmega1284_isp: isp

+atmega164: TARGET = atmega164p
+atmega164: MCU_TARGET = atmega164p
+atmega164: CFLAGS += '-DLED_START_FLASHES=3' '-DBAUD_RATE=115200' 
+atmega164: AVR_FREQ = 16000000L
+atmega164: LDSECTIONS  = -Wl,--section-start=.text=0x3e00 -Wl,--section-start=.version=0x3ffe
+atmega164: $(PROGRAM)_atmega164p.hex
+atmega164: $(PROGRAM)_atmega164p.lst
+
+atmega164_isp: atmega164
+atmega164_isp: TARGET = atmega164p
+atmega164_isp: MCU_TARGET = atmega164p
+# 512 byte boot
+atmega164_isp: HFUSE = DC
+# Low power xtal (16MHz) 16KCK/14CK+65ms
+atmega164_isp: LFUSE = FF
+# 2.7V brownout
+atmega164_isp: EFUSE = FD
+atmega164_isp: isp
+
 # Sanguino has a minimum boot size of 1024 bytes, so enable extra functions
 #
 sanguino: TARGET = atmega644p
diff -r cc5e4843feec optiboot/bootloaders/optiboot/makeall
--- a/optiboot/bootloaders/optiboot/makeall     Tue Apr 03 00:51:23 2012 -0700
+++ b/optiboot/bootloaders/optiboot/makeall     Wed Oct 03 00:10:06 2012 +0200
@@ -18,3 +18,4 @@
 make mega
 make atmega88
 make luminet
+make atmega164
diff -r cc5e4843feec optiboot/bootloaders/optiboot/optiboot.c
--- a/optiboot/bootloaders/optiboot/optiboot.c  Tue Apr 03 00:51:23 2012 -0700
+++ b/optiboot/bootloaders/optiboot/optiboot.c  Wed Oct 03 00:10:06 2012 +0200
@@ -303,6 +303,9 @@
 #elif defined (__AVR_ATmega644P__)
 #define RAMSTART (0x100)
 #define NRWWSTART (0xE000)
+#elif defined (__AVR_ATmega164P__)
+#define RAMSTART (0x100)
+#define NRWWSTART (0x0)
 // correct for a bug in avr-libc
 #undef SIGNATURE_2
 #define SIGNATURE_2 0x0A
diff -r cc5e4843feec optiboot/bootloaders/optiboot/pin_defs.h
--- a/optiboot/bootloaders/optiboot/pin_defs.h  Tue Apr 03 00:51:23 2012 -0700
+++ b/optiboot/bootloaders/optiboot/pin_defs.h  Wed Oct 03 00:10:06 2012 +0200
@@ -44,7 +44,7 @@
 #endif

 /* Sanguino support */
-#if defined(__AVR_ATmega644P__) || defined(__AVR_ATmega1284P__)
+#if defined(__AVR_ATmega164P__) || defined(__AVR_ATmega644P__) || defined(__AVR_ATmega1284P__)
 /* Onboard LED is connected to pin PB0 on Sanguino */
 #define LED_DDR     DDRB
 #define LED_PORT    PORTB

This creates a new make target atmega164. The booter will be placed at the end of the 16K flash, leds are the same as on the 644…
This compiles a optiboot_atmega164p.hex. No idea what other changes are still needed. E.g. the atmega164p has a page size of 64 words while the atmega644p has a page size of 128 words. I don’t know whether the optiboot code and/or the avrdude.conf file automatically deal with this. Unfortunately I don’t have an atmega164p to try, so I am a bit blocked here.

Maybe somebody with some optiboot code knowledge can jump in here?

Wow, thank you so much for this work, I appreciate it. I understand it might take a few back-and-forths since you don’t have a 164p on hand, but I’ll try my best… I haven’t done this stuff before, so if we could go a little bit step-by-step that’d be great.

Here’s what I’ve done so far.

  • I copied the hardware/sanguino folder as hardware/sanguino164p, and changed the board name in the new boards.txt to match.

  • I noticed there was no optiboot in the sanguino bootloaders, so I copied the folder from hardware/arduino/bootloaders/optiboot to my new hardware/sanguino164p/bootloaders/optiboot

  • I copy/pasted your patch code, and created a file with it, patch.txt, and placed it in hardware/sanguino164p/bootloaders/optiboot

  • I ran patch -p1 < patch.txt and it couldn’t find the files to patch because the addresses were /optiboot/bootloaders/optiboot/Makefile etc. so I made a patch2.txt adjusting the addresses all to ie. — a/Makefile etc.

  • I then get ‘Hunk #1 FAILED’ errors, eg.

patching file Makefile
Hunk #1 FAILED at 265.
1 out of 1 hunk FAILED

If you could let me know where I’ve gone wrong, that’d be great.

------- EDIT -------

I realized that though the Sanguino distribution didn’t come with optiboot, you must have been using the one directly from Google-code. So I cloned that, tried the patch there, and got :

 patch -p1 < patch.txtpatching file optiboot/bootloaders/optiboot/Makefile
patching file optiboot/bootloaders/optiboot/makeall
patching file optiboot/bootloaders/optiboot/optiboot.c
patching file optiboot/bootloaders/optiboot/pin_defs.h
Hunk #1 FAILED at 44.

Reading up on the patch file syntax, still not sure why the last hunk failed, so I replaced the ifdef manually and tried to compile with make atmega164. I got this output :

optiboot$ make atmega164
avr-gcc -g -Wall -Os -fno-inline-small-functions -fno-split-wide-types -mshort-calls -mmcu=atmega164p -DF_CPU=16000000L  '-DLED_START_FLASHES=3' '-DBAUD_RATE=115200'    -c -o optiboot.o optiboot.c
optiboot.c: In function ‘main’:
optiboot.c:420:3: error: ‘LED_DDR’ undeclared (first use in this function)
optiboot.c:420:3: note: each undeclared identifier is reported only once for each function it appears in
optiboot.c:420:14: error: ‘LED’ undeclared (first use in this function)
optiboot.c: In function ‘flash_led’:
optiboot.c:746:5: error: ‘LED_PIN’ undeclared (first use in this function)
optiboot.c:746:16: error: ‘LED’ undeclared (first use in this function)
make: *** [optiboot.o] Error 1

I directly took the head of development of optiboot itself. See: http://code.google.com/p/optiboot/source/checkout

The arduino project only pulls changes from there if they are relevant to mcu’s supported by arduino, so for the atmega164 and friends, we’re better off at optiboot.
It goes like this:

hg clone https://code.google.com/p/optiboot/
cd optiboot
patch -p1 < patch_file
cd optiboot/bootloaders/optiboot
./makeall

Where did you see that the 164 is half the price of an 1284?
E.g. at be.farnell.com, the atmega1284p-pu and the atmega164pa-p are about 5.5 euro.
Of coarse it can be fun to just try to make it work, regardless of the price.

Thanks Peter,

I also cloned from optiboot. So I tried again from scratch using just the terminal code you mentioned, but still the same; hunk 4 fails.

kx@kx-laptop:~/Programming/Arduino/arduino-1.0.1/hardware/sanguino164p/bootloaders$ hg clone https://code.google.com/p/optiboot/
destination directory: optiboot
requesting all changes
adding changesets
adding manifests
adding file changes
added 34 changesets with 299 changes to 119 files
updating to branch default
36 files updated, 0 files merged, 0 files removed, 0 files unresolved
kx@kx-laptop:~/Programming/Arduino/arduino-1.0.1/hardware/sanguino164p/bootloaders$ cd optiboot
kx@kx-laptop:~/Programming/Arduino/arduino-1.0.1/hardware/sanguino164p/bootloaders/optiboot$ patch -p1 < patch.txt
patching file optiboot/bootloaders/optiboot/Makefile
patching file optiboot/bootloaders/optiboot/makeall
patching file optiboot/bootloaders/optiboot/optiboot.c
patching file optiboot/bootloaders/optiboot/pin_defs.h
Hunk #1 FAILED at 44.
1 out of 1 hunk FAILED -- saving rejects to file optiboot/bootloaders/optiboot/pin_defs.h.rej

If I apply the last hunk manually and proceed, ( that is, in pin_defs.h
replace #if defined(AVR_ATmega644P) || defined(AVR_ATmega1284P) with #if defined(AVR_ATmega164P) || defined(AVR_ATmega644P) || defined(AVR_ATmega1284P) )

and ./makeall, I get

kx@kx-laptop:~/Programming/Arduino/arduino-1.0.1/hardware/sanguino164p/bootloaders/optiboot/optiboot/bootloaders/optiboot$ ./makeall
rm -rf *.o *.elf *.lst *.map *.sym *.lss *.eep *.srec *.bin *.hex
avr-gcc -g -Wall -Os -fno-inline-small-functions -fno-split-wide-types -mshort-calls -mmcu=atmega8 -DF_CPU=16000000L   '-DLED_START_FLASHES=3' '-DBAUD_RATE=115200'   -c -o optiboot.o optiboot.c
optiboot.c:319:0: warning: "RAMSTART" redefined
/usr/lib/gcc/avr/4.5.3/../../../avr/include/avr/iom8.h:568:0: note: this is the location of the previous definition
avr-gcc -g -Wall -Os -fno-inline-small-functions -fno-split-wide-types -mshort-calls -mmcu=atmega8 -DF_CPU=16000000L   '-DLED_START_FLASHES=3' '-DBAUD_RATE=115200' -Wl,--section-start=.text=0x1e00 -Wl,--section-start=.version=0x1ffe -Wl,--relax -Wl,--gc-sections -nostartfiles -nostdlib -o optiboot_atmega8.elf optiboot.o 
avr-size optiboot_atmega8.elf
   text	   data	    bss	    dec	    hex	filename
    488	      0	      0	    488	    1e8	optiboot_atmega8.elf
/// ............Cut a section out because of character limit in this forum ...............//////
    506	      0	      0	    506	    1fa	optiboot_pro_16MHz.elf
avr-objcopy -j .text -j .data -j .version --set-section-flags .version=alloc,load -O ihex optiboot_pro_16MHz.elf optiboot_pro_16MHz.hex
avr-objdump -h -S optiboot_pro_16MHz.elf > optiboot_pro_16MHz.lst
rm optiboot.o optiboot_pro_16MHz.elf
avr-gcc -g -Wall -Os -fno-inline-small-functions -fno-split-wide-types -mshort-calls -mmcu=atmega168 -DF_CPU=20000000L  '-DLED_START_FLASHES=3' '-DBAUD_RATE=115200'   -c -o optiboot.o optiboot.c
avr-gcc -g -Wall -Os -fno-inline-small-functions -fno-split-wide-types -mshort-calls -mmcu=atmega168 -DF_CPU=20000000L  '-DLED_START_FLASHES=3' '-DBAUD_RATE=115200' -Wl,--section-start=.text=0x3e00 -Wl,--section-start=.version=0x3ffe -Wl,--relax -Wl,--gc-sections -nostartfiles -nostdlib -o optiboot_pro_20mhz.elf optiboot.o 
avr-size optiboot_pro_20mhz.elf
   text	   data	    bss	    dec	    hex	filename
    506	      0	      0	    506	    1fa	optiboot_pro_20mhz.elf
avr-objcopy -j .text -j .data -j .version --set-section-flags .version=alloc,load -O ihex optiboot_pro_20mhz.elf optiboot_pro_20mhz.hex
avr-objdump -h -S optiboot_pro_20mhz.elf > optiboot_pro_20mhz.lst
rm optiboot.o optiboot_pro_20mhz.elf
avr-gcc -g -Wall -Os -fno-inline-small-functions -fno-split-wide-types -mshort-calls -mmcu=atmega328p -DF_CPU=8000000L  '-DLED_START_FLASHES=3' '-DBAUD_RATE=115200'   -c -o optiboot.o optiboot.c
avr-gcc -g -Wall -Os -fno-inline-small-functions -fno-split-wide-types -mshort-calls -mmcu=atmega328p -DF_CPU=8000000L  '-DLED_START_FLASHES=3' '-DBAUD_RATE=115200' -Wl,--section-start=.text=0x7e00 -Wl,--section-start=.version=0x7ffe -Wl,--relax -Wl,--gc-sections -nostartfiles -nostdlib -o optiboot_atmega328_pro_8MHz.elf optiboot.o 
avr-size optiboot_atmega328_pro_8MHz.elf
   text	   data	    bss	    dec	    hex	filename
    506	      0	      0	    506	    1fa	optiboot_atmega328_pro_8MHz.elf
avr-objcopy -j .text -j .data -j .version --set-section-flags .version=alloc,load -O ihex optiboot_atmega328_pro_8MHz.elf optiboot_atmega328_pro_8MHz.hex
avr-objdump -h -S optiboot_atmega328_pro_8MHz.elf > optiboot_atmega328_pro_8MHz.lst
rm optiboot.o optiboot_atmega328_pro_8MHz.elf
avr-gcc -g -Wall -Os -fno-inline-small-functions -fno-split-wide-types -mshort-calls -mmcu=atmega644p -DF_CPU=16000000L  '-DLED_START_FLASHES=3' '-DBAUD_RATE=115200' '-DBIGBOOT'   -c -o optiboot.o optiboot.c
avr-gcc -g -Wall -Os -fno-inline-small-functions -fno-split-wide-types -mshort-calls -mmcu=atmega644p -DF_CPU=16000000L  '-DLED_START_FLASHES=3' '-DBAUD_RATE=115200' '-DBIGBOOT' -Wl,--section-start=.text=0xfc00 -Wl,--section-start=.version=0xfffe -Wl,--relax -Wl,--gc-sections -nostartfiles -nostdlib -o optiboot_atmega644p.elf optiboot.o 
avr-size optiboot_atmega644p.elf
   text	   data	    bss	    dec	    hex	filename
    506	      0	      0	    506	    1fa	optiboot_atmega644p.elf
avr-objcopy -j .text -j .data -j .version --set-section-flags .version=alloc,load -O ihex optiboot_atmega644p.elf optiboot_atmega644p.hex
avr-objdump -h -S optiboot_atmega644p.elf > optiboot_atmega644p.lst
rm optiboot.o optiboot_atmega644p.elf
make: *** No rule to make target `mega'.  Stop.
avr-gcc -g -Wall -Os -fno-inline-small-functions -fno-split-wide-types -mshort-calls -mmcu=atmega88 -DF_CPU=16000000L   '-DLED_START_FLASHES=3' '-DBAUD_RATE=115200'   -c -o optiboot.o optiboot.c
avr-gcc -g -Wall -Os -fno-inline-small-functions -fno-split-wide-types -mshort-calls -mmcu=atmega88 -DF_CPU=16000000L   '-DLED_START_FLASHES=3' '-DBAUD_RATE=115200' -Wl,--section-start=.text=0x1e00 -Wl,--section-start=.version=0x1ffe -Wl,--relax -Wl,--gc-sections -nostartfiles -nostdlib -o optiboot_atmega88.elf optiboot.o 
avr-size optiboot_atmega88.elf
   text	   data	    bss	    dec	    hex	filename
    506	      0	      0	    506	    1fa	optiboot_atmega88.elf
avr-objcopy -j .text -j .data -j .version --set-section-flags .version=alloc,load -O ihex optiboot_atmega88.elf optiboot_atmega88.hex
avr-objdump -h -S optiboot_atmega88.elf > optiboot_atmega88.lst
rm optiboot.o optiboot_atmega88.elf
avr-gcc -g -Wall -Os -fno-inline-small-functions -fno-split-wide-types -mshort-calls -mmcu=attiny84 -DF_CPU=1000000L  '-DLED_START_FLASHES=3' '-DSOFT_UART' '-DBAUD_RATE=9600' '-DVIRTUAL_BOOT_PARTITION'   -c -o optiboot.o optiboot.c
optiboot.c:313:0: warning: "RAMSTART" redefined
/usr/lib/gcc/avr/4.5.3/../../../avr/include/avr/iotn84.h:42:0: note: this is the location of the previous definition
avr-gcc -g -Wall -Os -fno-inline-small-functions -fno-split-wide-types -mshort-calls -mmcu=attiny84 -DF_CPU=1000000L  '-DLED_START_FLASHES=3' '-DSOFT_UART' '-DBAUD_RATE=9600' '-DVIRTUAL_BOOT_PARTITION' -Wl,--section-start=.text=0x1d00 -Wl,--section-start=.version=0x1efe -Wl,--relax -Wl,--gc-sections -nostartfiles -nostdlib -o optiboot_luminet.elf optiboot.o 
avr-size optiboot_luminet.elf
   text	   data	    bss	    dec	    hex	filename
    602	      0	      0	    602	    25a	optiboot_luminet.elf
avr-objcopy -j .text -j .data -j .version --set-section-flags .version=alloc,load -O ihex optiboot_luminet.elf optiboot_luminet.hex
avr-objdump -h -S optiboot_luminet.elf > optiboot_luminet.lst
rm optiboot.o optiboot_luminet.elf

Is this expected? Should I have also gotten an atmega164 hex, or is the 644 hex now suitable to be renamed and tried with the 164 chip?

Also, about the price, I’m just talking about my local electronics shop here in Tokyo where the 1284s are 600yen, and the 164s are 300yen (6 Euro / 3 Euro), and the 1284s and 644s are constantly out of stock, whereas they always have plenty of 164s :slight_smile:

Thanks again

No, you should have an optiboot_atmega164p.hex and an optiboot_atmega164p.lst.
Do you have a line

make atmega164

in makeall?
(if not just do make atmega164 manually)

Ok, I realized that though the patch process was able to succeed for the first files and only fail for the last file, it decides not to apply any of the changes. So I went through and made all the changes manually. Then I could compile the optiboot_atmega164p.hex file successfully.

So I put it in the bootloaders folder, and changed the boards.txt to this :

############################################################

atmega164p.name=Sanguino W/ ATmega164P

atmega164p.upload.protocol=stk500
atmega164p.upload.maximum_size=15872
atmega164p.upload.speed=57600

atmega164p.bootloader.low_fuses=0xFF
atmega164p.bootloader.high_fuses=0x9A
atmega164p.bootloader.extended_fuses=0xFF
atmega164p.bootloader.path=atmega
atmega164p.bootloader.file=optiboot_atmega164p.hex
atmega164p.bootloader.unlock_bits=0x3F
atmega164p.bootloader.lock_bits=0x0F

atmega164p.build.mcu=atmega164p
atmega164p.build.f_cpu=16000000L
atmega164p.build.core=arduino
atmega164p.build.variant=standard
##############################################################

Does that seem about right? Perhaps since the previous entry was for the old-style bootloader rather than optiboot there are some more changes required there.

Then using arduino-as-ISP I was able to successfully upload the bootloader to the atmega164p! Unfortunately it still doesn't work yet - I get the 'avrdude: stk500_recv(): programmer is not responding' message when trying to upload a blink sketch via the serial port (both UARTs).

Any ideas of where to proceed from here?

Thanks a lot

The optiboot just compiled uses baud rate 115200 (see code).
No matter what, after reset a led on ic pin 1(see code) should blink briefly. Does it do that?

We had better check each fuse bit carefuly first in order not to brick the chip. I can help with that later...

In meantime I flashed the optiboot just compiled for 644 into my sanguino rbk, it works well, I use this boards.txt to download sketches:

sanguino.name=Sanguino
sanguino.upload.protocol=arduino
sanguino.upload.maximum_size=63488
sanguino.upload.speed=115200
sanguino.bootloader.low_fuses=0xFF
sanguino.bootloader.high_fuses=0xDC
sanguino.bootloader.extended_fuses=0xFD
sanguino.bootloader.path=atmega644p
sanguino.bootloader.file=ATmegaBOOT_644P.hex
sanguino.bootloader.unlock_bits=0x3F
sanguino.bootloader.lock_bits=0x0F
sanguino.build.mcu=atmega644p
sanguino.build.f_cpu=16000000L
sanguino.build.core=standard
sanguino.build.variant=standard

Good news! The blink sketch is running on the 164p using optiboot. I eventually found a successful configuration with the following :

############################################################
atmega164p.name=Sanguino W/ ATmega164p
atmega164p.upload.protocol=arduino
atmega164p.upload.maximum_size=15872
atmega164p.upload.speed=115200
atmega164p.bootloader.low_fuses=0xFF
atmega164p.bootloader.high_fuses=0xDC
atmega164p.bootloader.extended_fuses=0xFD
atmega164p.bootloader.path=atmega
atmega164p.bootloader.file=optiboot_atmega164p.hex
atmega164p.bootloader.unlock_bits=0x3F
atmega164p.bootloader.lock_bits=0x0F
atmega164p.build.mcu=atmega164p
atmega164p.build.f_cpu=16000000L
atmega164p.build.core=arduino
atmega164p.build.variant=standard
##############################################################

Kind of a hybrid of our two respective entries. I have to admit I still don't really know what quite a few of them actually mean, but it works regardless. The build.core line as 'standard' would not compile at all for me, so needed to use 'arduino'. Yes the ic pin 1 does give a quick double-blink on reset. I also don't really know anything about the fuse settings, so you may think changing them would be better.

Thanks again for all your help. Hopefully there are others out there like me that'll find this thread useful in the future.

Champagne!

Hopefully there are others out there like me that’ll find this thread useful in the future.

If there are, we might ask the optiboot developer to adopt our extra build target for the 164p.
If not, it was fun figuring this out!